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