mirror of
https://github.com/raphnet/gc_n64_usb-v3
synced 2024-12-21 23:08:53 -05:00
Do away with the gcn64 work buffer (saves more memory!)
This commit is contained in:
parent
1a44a190cb
commit
b7b07a37ee
25
gamecube.c
25
gamecube.c
@ -41,7 +41,7 @@ static void gamecubeInit(void)
|
|||||||
gamecubeUpdate();
|
gamecubeUpdate();
|
||||||
}
|
}
|
||||||
|
|
||||||
void gc_decodeAnswer()
|
void gc_decodeAnswer(unsigned char data[8])
|
||||||
{
|
{
|
||||||
unsigned char x,y,cx,cy;
|
unsigned char x,y,cx,cy;
|
||||||
|
|
||||||
@ -87,14 +87,14 @@ void gc_decodeAnswer()
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
last_built_report.pad_type = PAD_TYPE_GAMECUBE;
|
last_built_report.pad_type = PAD_TYPE_GAMECUBE;
|
||||||
last_built_report.gc.buttons = gcn64_protocol_getByte(0) | gcn64_protocol_getByte(8) << 8;
|
last_built_report.gc.buttons = data[0] | data[1] << 8;
|
||||||
x = gcn64_protocol_getByte(16);
|
x = data[2];
|
||||||
y = gcn64_protocol_getByte(24);
|
y = data[3];
|
||||||
cx = gcn64_protocol_getByte(32);
|
cx = data[4];
|
||||||
cy = gcn64_protocol_getByte(40);
|
cy = data[5];
|
||||||
last_built_report.gc.lt = gcn64_protocol_getByte(48);
|
last_built_report.gc.lt = data[6];
|
||||||
last_built_report.gc.rt = gcn64_protocol_getByte(56);
|
last_built_report.gc.rt = data[7];
|
||||||
gcn64_protocol_getBytes(0, 8, last_built_report.gc.raw_data);
|
memcpy(last_built_report.gc.raw_data, data, 8);
|
||||||
|
|
||||||
if (origins_set) {
|
if (origins_set) {
|
||||||
last_built_report.gc.x = ((int)x-(int)orig_x);
|
last_built_report.gc.x = ((int)x-(int)orig_x);
|
||||||
@ -117,8 +117,7 @@ void gc_decodeAnswer()
|
|||||||
|
|
||||||
static char gamecubeUpdate()
|
static char gamecubeUpdate()
|
||||||
{
|
{
|
||||||
//unsigned char tmp=0;
|
unsigned char tmpdata[GC_GETSTATUS_REPLY_LENGTH];
|
||||||
unsigned char tmpdata[8];
|
|
||||||
unsigned char count;
|
unsigned char count;
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
@ -147,12 +146,12 @@ static char gamecubeUpdate()
|
|||||||
tmpdata[1] = GC_GETSTATUS2;
|
tmpdata[1] = GC_GETSTATUS2;
|
||||||
tmpdata[2] = GC_GETSTATUS3(gc_rumbling);
|
tmpdata[2] = GC_GETSTATUS3(gc_rumbling);
|
||||||
|
|
||||||
count = gcn64_transaction(tmpdata, 3);
|
count = gcn64_transaction(tmpdata, 3, tmpdata, GC_GETSTATUS_REPLY_LENGTH);
|
||||||
if (count != GC_GETSTATUS_REPLY_LENGTH) {
|
if (count != GC_GETSTATUS_REPLY_LENGTH) {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
gc_decodeAnswer();
|
gc_decodeAnswer(tmpdata);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -25,9 +25,6 @@
|
|||||||
|
|
||||||
#undef FORCE_KEYBOARD
|
#undef FORCE_KEYBOARD
|
||||||
|
|
||||||
#define GCN64_BUF_SIZE 40
|
|
||||||
static unsigned char gcn64_workbuf[GCN64_BUF_SIZE];
|
|
||||||
|
|
||||||
/******** IO port definitions and options **************/
|
/******** IO port definitions and options **************/
|
||||||
#ifndef STK525
|
#ifndef STK525
|
||||||
#define GCN64_DATA_PORT PORTD
|
#define GCN64_DATA_PORT PORTD
|
||||||
@ -45,20 +42,6 @@ static unsigned char gcn64_workbuf[GCN64_BUF_SIZE];
|
|||||||
|
|
||||||
#define DISABLE_INTS_DURING_COMM
|
#define DISABLE_INTS_DURING_COMM
|
||||||
|
|
||||||
|
|
||||||
/* Read a byte from the buffer (where 1 byte is 1 bit).
|
|
||||||
* MSb first.
|
|
||||||
*/
|
|
||||||
unsigned char gcn64_protocol_getByte(int offset)
|
|
||||||
{
|
|
||||||
return gcn64_workbuf[offset/8];
|
|
||||||
}
|
|
||||||
|
|
||||||
void gcn64_protocol_getBytes(int offset, int n_bytes, unsigned char *dstbuf)
|
|
||||||
{
|
|
||||||
memcpy(dstbuf, gcn64_workbuf + offset/8, n_bytes);
|
|
||||||
}
|
|
||||||
|
|
||||||
void gcn64protocol_hwinit(void)
|
void gcn64protocol_hwinit(void)
|
||||||
{
|
{
|
||||||
// data as input
|
// data as input
|
||||||
@ -79,22 +62,22 @@ void gcn64protocol_hwinit(void)
|
|||||||
*
|
*
|
||||||
* The result is in gcn64_workbuf.
|
* The result is in gcn64_workbuf.
|
||||||
*/
|
*/
|
||||||
int gcn64_transaction(unsigned char *data_out, int data_out_len)
|
unsigned char gcn64_transaction(const unsigned char *tx, int tx_len, unsigned char *rx, unsigned char rx_max)
|
||||||
{
|
{
|
||||||
int count;
|
int count;
|
||||||
unsigned char sreg = SREG;
|
unsigned char sreg = SREG;
|
||||||
// int i;
|
//int i;
|
||||||
|
|
||||||
#ifdef DISABLE_INTS_DURING_COMM
|
#ifdef DISABLE_INTS_DURING_COMM
|
||||||
cli();
|
cli();
|
||||||
#endif
|
#endif
|
||||||
gcn64_sendBytes(data_out, data_out_len);
|
gcn64_sendBytes(tx, tx_len);
|
||||||
count = gcn64_receiveBytes(gcn64_workbuf, 0);
|
count = gcn64_receiveBytes(rx, rx_max);
|
||||||
SREG = sreg;
|
SREG = sreg;
|
||||||
#if 0
|
#if 0
|
||||||
printf("Count: %d { ", count);
|
printf("Count: %d { ", count);
|
||||||
for (i=0; i<count; i++) {
|
for (i=0; i<count; i++) {
|
||||||
printf("%02x ", gcn64_workbuf[i]);
|
printf("%02x ", rx[i]);
|
||||||
}
|
}
|
||||||
printf("}\r\n");
|
printf("}\r\n");
|
||||||
#endif
|
#endif
|
||||||
@ -123,8 +106,9 @@ int gcn64_detectController(void)
|
|||||||
unsigned char tmp = GC_GETID;
|
unsigned char tmp = GC_GETID;
|
||||||
unsigned char count;
|
unsigned char count;
|
||||||
unsigned short id;
|
unsigned short id;
|
||||||
|
unsigned char data[4];
|
||||||
|
|
||||||
count = gcn64_transaction(&tmp, 1);
|
count = gcn64_transaction(&tmp, 1, data, sizeof(data));
|
||||||
if (count == 0) {
|
if (count == 0) {
|
||||||
return CONTROLLER_IS_ABSENT;
|
return CONTROLLER_IS_ABSENT;
|
||||||
}
|
}
|
||||||
@ -132,7 +116,7 @@ int gcn64_detectController(void)
|
|||||||
return CONTROLLER_IS_UNKNOWN;
|
return CONTROLLER_IS_UNKNOWN;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* -- Standard gamecube controller answer:
|
* -- Standard gamecube controller answer:
|
||||||
* 0000 1001 0000 0000 0010 0011 : 0x090023 or
|
* 0000 1001 0000 0000 0010 0011 : 0x090023 or
|
||||||
* 0000 1001 0000 0000 0010 0000 : 0x090020
|
* 0000 1001 0000 0000 0010 0000 : 0x090020
|
||||||
@ -145,13 +129,13 @@ int gcn64_detectController(void)
|
|||||||
*
|
*
|
||||||
* 1110 1001 1010 0000 0001 0111 : 0xE9A017
|
* 1110 1001 1010 0000 0001 0111 : 0xE9A017
|
||||||
* (controller on)
|
* (controller on)
|
||||||
*
|
*
|
||||||
* 1010 1000 0000
|
* 1010 1000 0000
|
||||||
*
|
*
|
||||||
* -- Intec wireless gamecube controller
|
* -- Intec wireless gamecube controller
|
||||||
* 0000 1001 0000 0000 0010 0000 : 0x090020
|
* 0000 1001 0000 0000 0010 0000 : 0x090020
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* -- Standard N64 controller
|
* -- Standard N64 controller
|
||||||
* 0000 0101 0000 0000 0000 0000 : 0x050000 (no pack)
|
* 0000 0101 0000 0000 0000 0000 : 0x050000 (no pack)
|
||||||
* 0000 0101 0000 0000 0000 0001 : 0x050001 With expansion pack
|
* 0000 0101 0000 0000 0000 0001 : 0x050001 With expansion pack
|
||||||
@ -164,8 +148,8 @@ int gcn64_detectController(void)
|
|||||||
* gamecube compatible controller is present. If on the other hand
|
* gamecube compatible controller is present. If on the other hand
|
||||||
* we have a 5, then we are communicating with a N64 controller.
|
* we have a 5, then we are communicating with a N64 controller.
|
||||||
*
|
*
|
||||||
* This conclusion appears to be corroborated by my old printout of
|
* This conclusion appears to be corroborated by my old printout of
|
||||||
* the document named "Yet another gamecube documentation (but one
|
* the document named "Yet another gamecube documentation (but one
|
||||||
* that's worth printing). The document explains that and ID can
|
* that's worth printing). The document explains that and ID can
|
||||||
* be read by sending what they call the 'SI command 0x00 to
|
* be read by sending what they call the 'SI command 0x00 to
|
||||||
* which the controller replies with 3 bytes. (Clearly, that's
|
* which the controller replies with 3 bytes. (Clearly, that's
|
||||||
@ -186,8 +170,7 @@ int gcn64_detectController(void)
|
|||||||
*
|
*
|
||||||
* */
|
* */
|
||||||
|
|
||||||
id = gcn64_protocol_getByte(0)<<8;
|
id = (data[0]<<8) | data[1];
|
||||||
id |= gcn64_protocol_getByte(8);
|
|
||||||
|
|
||||||
#ifdef FORCE_KEYBOARD
|
#ifdef FORCE_KEYBOARD
|
||||||
return CONTROLLER_IS_GC_KEYBOARD;
|
return CONTROLLER_IS_GC_KEYBOARD;
|
||||||
@ -209,7 +192,7 @@ int gcn64_detectController(void)
|
|||||||
// wavebird, controller off.
|
// wavebird, controller off.
|
||||||
return CONTROLLER_IS_GC;
|
return CONTROLLER_IS_GC;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return CONTROLLER_IS_UNKNOWN;
|
return CONTROLLER_IS_UNKNOWN;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -161,9 +161,6 @@
|
|||||||
|
|
||||||
void gcn64protocol_hwinit(void);
|
void gcn64protocol_hwinit(void);
|
||||||
int gcn64_detectController(void);
|
int gcn64_detectController(void);
|
||||||
int gcn64_transaction(unsigned char *data_out, int data_out_len);
|
unsigned char gcn64_transaction(const unsigned char *tx, int tx_len, unsigned char *rx, unsigned char rx_max);
|
||||||
|
|
||||||
unsigned char gcn64_protocol_getByte(int offset);
|
|
||||||
void gcn64_protocol_getBytes(int offset, int n_bytes, unsigned char *dstbuf);
|
|
||||||
|
|
||||||
#endif // _gcn64_protocol_h__
|
#endif // _gcn64_protocol_h__
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
#ifndef _gcn64txrx_h__
|
#ifndef _gcn64txrx_h__
|
||||||
#define _gcn64txrx_h__
|
#define _gcn64txrx_h__
|
||||||
|
|
||||||
void gcn64_sendBytes(unsigned char *data, unsigned char n_bytes);
|
void gcn64_sendBytes(const unsigned char *data, unsigned char n_bytes);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Receive up to \max_bytes bytes
|
* \brief Receive up to \max_bytes bytes
|
||||||
|
@ -78,8 +78,7 @@ static void hiddata_processCommandBuffer(void)
|
|||||||
// TODO : Range checking
|
// TODO : Range checking
|
||||||
// cmdbuf[] : RQ, CHN, LEN, data[]
|
// cmdbuf[] : RQ, CHN, LEN, data[]
|
||||||
channel = cmdbuf[1];
|
channel = cmdbuf[1];
|
||||||
cmdbuf_len = gcn64_transaction(cmdbuf+3, cmdbuf[2]);
|
cmdbuf_len = gcn64_transaction(cmdbuf+3, cmdbuf[2], cmdbuf + 3, CMDBUF_SIZE-3);
|
||||||
gcn64_protocol_getBytes(0, cmdbuf_len, cmdbuf + 3);
|
|
||||||
cmdbuf[2] = cmdbuf_len;
|
cmdbuf[2] = cmdbuf_len;
|
||||||
cmdbuf_len += 3; // Answer: RQ, CHN, LEN, data[]
|
cmdbuf_len += 3; // Answer: RQ, CHN, LEN, data[]
|
||||||
break;
|
break;
|
||||||
|
2
main.c
2
main.c
@ -222,10 +222,12 @@ Gamepad *detectPad(void)
|
|||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
case CONTROLLER_IS_N64:
|
case CONTROLLER_IS_N64:
|
||||||
|
printf("Detected N64 controller\n");
|
||||||
return n64GetGamepad();
|
return n64GetGamepad();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CONTROLLER_IS_GC:
|
case CONTROLLER_IS_GC:
|
||||||
|
printf("Detected GC controller\n");
|
||||||
return gamecubeGetGamepad();
|
return gamecubeGetGamepad();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
28
n64.c
28
n64.c
@ -53,13 +53,14 @@ unsigned char tmpdata[40];
|
|||||||
static char initRumble(void)
|
static char initRumble(void)
|
||||||
{
|
{
|
||||||
int count;
|
int count;
|
||||||
|
unsigned char data[4];
|
||||||
|
|
||||||
tmpdata[0] = N64_EXPANSION_WRITE;
|
tmpdata[0] = N64_EXPANSION_WRITE;
|
||||||
tmpdata[1] = 0x80;
|
tmpdata[1] = 0x80;
|
||||||
tmpdata[2] = 0x01;
|
tmpdata[2] = 0x01;
|
||||||
memset(tmpdata+3, 0x80, 32);
|
memset(tmpdata+3, 0x80, 32);
|
||||||
|
|
||||||
count = gcn64_transaction(tmpdata, 35);
|
count = gcn64_transaction(tmpdata, 35, data, sizeof(data));
|
||||||
if (count == 1)
|
if (count == 1)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
@ -69,12 +70,13 @@ static char initRumble(void)
|
|||||||
static char controlRumble(char enable)
|
static char controlRumble(char enable)
|
||||||
{
|
{
|
||||||
int count;
|
int count;
|
||||||
|
unsigned char data[4];
|
||||||
|
|
||||||
tmpdata[0] = N64_EXPANSION_WRITE;
|
tmpdata[0] = N64_EXPANSION_WRITE;
|
||||||
tmpdata[1] = 0xc0;
|
tmpdata[1] = 0xc0;
|
||||||
tmpdata[2] = 0x1b;
|
tmpdata[2] = 0x1b;
|
||||||
memset(tmpdata+3, enable ? 0x01 : 0x00, 32);
|
memset(tmpdata+3, enable ? 0x01 : 0x00, 32);
|
||||||
count = gcn64_transaction(tmpdata, 35);
|
count = gcn64_transaction(tmpdata, 35, data, sizeof(data));
|
||||||
if (count == 1)
|
if (count == 1)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
@ -86,7 +88,8 @@ static char n64Update(void)
|
|||||||
unsigned char count;
|
unsigned char count;
|
||||||
unsigned char x,y;
|
unsigned char x,y;
|
||||||
unsigned char btns1, btns2;
|
unsigned char btns1, btns2;
|
||||||
unsigned char caps[3];
|
unsigned char caps[N64_CAPS_REPLY_LENGTH];
|
||||||
|
unsigned char status[N64_GET_STATUS_REPLY_LENGTH];
|
||||||
|
|
||||||
/* Pad answer to N64_GET_CAPABILITIES
|
/* Pad answer to N64_GET_CAPABILITIES
|
||||||
*
|
*
|
||||||
@ -98,7 +101,7 @@ static char n64Update(void)
|
|||||||
* Bit 1 tells is if there was something connected that has been removed.
|
* Bit 1 tells is if there was something connected that has been removed.
|
||||||
*/
|
*/
|
||||||
tmpdata[0] = N64_GET_CAPABILITIES;
|
tmpdata[0] = N64_GET_CAPABILITIES;
|
||||||
count = gcn64_transaction(tmpdata, 1);
|
count = gcn64_transaction(tmpdata, 1, caps, sizeof(caps));
|
||||||
if (count != N64_CAPS_REPLY_LENGTH) {
|
if (count != N64_CAPS_REPLY_LENGTH) {
|
||||||
// a failed read could mean the pack or controller was gone. Init
|
// a failed read could mean the pack or controller was gone. Init
|
||||||
// will be necessary next time we detect a pack is present.
|
// will be necessary next time we detect a pack is present.
|
||||||
@ -106,10 +109,6 @@ static char n64Update(void)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
caps[0] = gcn64_protocol_getByte(0);
|
|
||||||
caps[1] = gcn64_protocol_getByte(8);
|
|
||||||
caps[2] = gcn64_protocol_getByte(16);
|
|
||||||
|
|
||||||
/* Detect when a pack becomes present and schedule initialisation when it happens. */
|
/* Detect when a pack becomes present and schedule initialisation when it happens. */
|
||||||
if ((caps[2] & 0x01) && (n64_rumble_state == RSTATE_UNAVAILABLE)) {
|
if ((caps[2] & 0x01) && (n64_rumble_state == RSTATE_UNAVAILABLE)) {
|
||||||
n64_rumble_state = RSTATE_INIT;
|
n64_rumble_state = RSTATE_INIT;
|
||||||
@ -173,7 +172,7 @@ static char n64Update(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
tmpdata[0] = N64_GET_STATUS;
|
tmpdata[0] = N64_GET_STATUS;
|
||||||
count = gcn64_transaction(tmpdata, 1);
|
count = gcn64_transaction(tmpdata, 1, status, sizeof(status));
|
||||||
if (count != N64_GET_STATUS_REPLY_LENGTH) {
|
if (count != N64_GET_STATUS_REPLY_LENGTH) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@ -200,10 +199,10 @@ static char n64Update(void)
|
|||||||
24-31: analog Y axis
|
24-31: analog Y axis
|
||||||
*/
|
*/
|
||||||
|
|
||||||
btns1 = gcn64_protocol_getByte(0);
|
btns1 = status[0];
|
||||||
btns2 = gcn64_protocol_getByte(8);
|
btns2 = status[1];
|
||||||
x = gcn64_protocol_getByte(16); // X axis
|
x = status[2];
|
||||||
y = gcn64_protocol_getByte(24); // Y axis
|
y = status[3];
|
||||||
|
|
||||||
#ifdef BUTTON_A_RUMBLE_TEST
|
#ifdef BUTTON_A_RUMBLE_TEST
|
||||||
if (btns1 & 0x80) {
|
if (btns1 & 0x80) {
|
||||||
@ -256,6 +255,7 @@ static char n64Probe(void)
|
|||||||
int count;
|
int count;
|
||||||
char i;
|
char i;
|
||||||
unsigned char tmp;
|
unsigned char tmp;
|
||||||
|
unsigned char data[4];
|
||||||
|
|
||||||
/* Pad answer to N64_GET_CAPABILITIES
|
/* Pad answer to N64_GET_CAPABILITIES
|
||||||
*
|
*
|
||||||
@ -274,7 +274,7 @@ static char n64Probe(void)
|
|||||||
_delay_ms(30);
|
_delay_ms(30);
|
||||||
|
|
||||||
tmp = N64_GET_CAPABILITIES;
|
tmp = N64_GET_CAPABILITIES;
|
||||||
count = gcn64_transaction(&tmp, 1);
|
count = gcn64_transaction(&tmp, 1, data, sizeof(data));
|
||||||
|
|
||||||
if (count == N64_CAPS_REPLY_LENGTH) {
|
if (count == N64_CAPS_REPLY_LENGTH) {
|
||||||
return 1;
|
return 1;
|
||||||
|
Loading…
Reference in New Issue
Block a user