diff --git a/Makefile b/Makefile index 9d7b708..ee487cc 100644 --- a/Makefile +++ b/Makefile @@ -9,7 +9,7 @@ CFLAGS=-Wall -mmcu=$(CPU) -DF_CPU=16000000L -Os -DUART1_STDOUT LDFLAGS=-mmcu=$(CPU) -Wl,-Map=$(PROGNAME).map HEXFILE=$(PROGNAME).hex -OBJS=main.o n64.o gcn64_protocol.o usart1.o usb.o bootloader.o +OBJS=main.o usbpad.o n64.o gcn64_protocol.o usart1.o usb.o bootloader.o all: $(HEXFILE) diff --git a/Makefile.stk525 b/Makefile.stk525 index e4ae50a..f1ed842 100644 --- a/Makefile.stk525 +++ b/Makefile.stk525 @@ -9,7 +9,7 @@ CFLAGS=-Wall -mmcu=$(CPU) -DF_CPU=16000000L -Os -DUART1_STDOUT -DSTK525 LDFLAGS=-mmcu=$(CPU) -Wl,-Map=$(PROGNAME).map HEXFILE=$(PROGNAME).hex -OBJS=main.o n64.o gcn64_protocol.o usart1.o usb.o bootloader.o +OBJS=main.o usbpad.o n64.o gcn64_protocol.o usart1.o usb.o bootloader.o all: $(HEXFILE) diff --git a/gamepad.h b/gamepad.h deleted file mode 100644 index 40242ec..0000000 --- a/gamepad.h +++ /dev/null @@ -1,25 +0,0 @@ -#ifndef _gamepad_h__ -#define _gamepad_h__ - -typedef struct { - int num_reports; - - int reportDescriptorSize; - void *reportDescriptor; // must be in flash - - int deviceDescriptorSize; // if 0, use default - void *deviceDescriptor; // must be in flash - - void (*init)(void); - char (*update)(void); - char (*changed)(int id); - int (*buildReport)(unsigned char *buf, int id); - void (*setVibration)(int value); - - /* Check for the controller */ - char (*probe)(void); /* return true if found */ -} Gamepad; - -#endif // _gamepad_h__ - - diff --git a/main.c b/main.c index b21c0b1..f48d8e4 100644 --- a/main.c +++ b/main.c @@ -10,10 +10,11 @@ #include "util.h" #include "usart1.h" #include "usb.h" -#include "gamepad.h" +#include "gamepads.h" #include "gcn64_protocol.h" #include "n64.h" #include "bootloader.h" +#include "usbpad.h" uint16_t hid_get_report_main(struct usb_request *rq, const uint8_t **dat); uint8_t hid_set_report_main(const struct usb_request *rq, const uint8_t *dat, uint16_t len); @@ -245,6 +246,7 @@ static unsigned char _FFB_effect_index; #define LOOP_MAX 0xFFFF static unsigned int _loop_count; +#if 0 static void effect_loop() { if (_loop_count) { @@ -253,11 +255,12 @@ static void effect_loop() } } } +#endif static void decideVibration(void) { - if (!_loop_count) - vibration_on = 0; +// if (!_loop_count) +// vibration_on = 0; if (!vibration_on) { gamepad_vibrate = 0; @@ -305,8 +308,8 @@ uint16_t hid_get_report_main(struct usb_request *rq, const uint8_t **dat) case HID_REPORT_TYPE_FEATURE: if (report_id == PID_BLOCK_LOAD_REPORT) { hid_report_data[0] = report_id; - hid_report_data[1] = 0x1; - hid_report_data[2] = 0x1; + hid_report_data[1] = 0x1; // Effect block index + hid_report_data[2] = 0x1; // (1: success, 2: oom, 3: load error) hid_report_data[3] = 10; hid_report_data[4] = 10; printf_P(PSTR("block load\r\n")); @@ -353,10 +356,10 @@ uint8_t hid_set_report_main(const struct usb_request *rq, const uint8_t *data, u switch(data[0]) { case REPORT_SET_STATUS: - printf_P(PSTR("eff. set stat\r\n")); + printf_P(PSTR("eff. set stat 0x%02x 0x%02x\r\n"),data[1],data[2]); break; case REPORT_EFFECT_BLOCK_IDX: - printf_P(PSTR("eff. blk. idx\r\n")); + printf_P(PSTR("eff. blk. idx %d\r\n"), data[1]); break; case REPORT_DISABLE_ACTUATORS: printf_P(PSTR("disable actuators\r\n")); @@ -370,7 +373,7 @@ uint8_t hid_set_report_main(const struct usb_request *rq, const uint8_t *data, u break; case REPORT_SET_PERIODIC: magnitude = data[2]; - decideVibration(); + // decideVibration(); printf_P(PSTR("periodic mag: %d"), data[2]); break; case REPORT_SET_CONSTANT_FORCE: @@ -383,13 +386,14 @@ uint8_t hid_set_report_main(const struct usb_request *rq, const uint8_t *data, u case REPORT_EFFECT_OPERATION: if (len != 4) return -1; - printf_P(PSTR("EFFECT OP\n")); /* Byte 0 : report ID * Byte 1 : bit 7=rom flag, bits 6-0=effect block index * Byte 2 : Effect operation * Byte 3 : Loop count */ _loop_count = data[3]<<3; + printf_P(PSTR("EFFECT OP: rom=%s, idx=0x%02x"), data[1] & 0x80 ? "Yes":"No", data[1] & 0x7F); + switch(data[1] & 0x7F) // Effect block index { case 1: // constant force @@ -398,16 +402,19 @@ uint8_t hid_set_report_main(const struct usb_request *rq, const uint8_t *data, u switch (data[2]) // effect operation { case EFFECT_OP_START: + printf_P(PSTR("Start\r\n")); vibration_on = 1; decideVibration(); break; case EFFECT_OP_START_SOLO: + printf_P(PSTR("Start solo\r\n")); vibration_on = 1; decideVibration(); break; case EFFECT_OP_STOP: + printf_P(PSTR("Stop\r\n")); vibration_on = 0; decideVibration(); break; @@ -475,6 +482,7 @@ uint8_t hid_set_report_data(const struct usb_request *rq, const uint8_t *dat, ui int main(void) { Gamepad *pad = NULL; + gamepad_data pad_data; hwinit(); usart1_init(); @@ -491,7 +499,7 @@ int main(void) usb_doTasks(); _delay_ms(5); - effect_loop(); + //effect_loop(); decideVibration(); if (last_v != gamepad_vibrate) { @@ -502,10 +510,12 @@ int main(void) } pad->update(); - if (pad->changed(1)) { + if (pad->changed()) { int report_size; - report_size = pad->buildReport(gamepad_report0, 1); + pad->getReport(&pad_data); + usbpad_buildReport(&pad_data, gamepad_report0); + report_size = usbpad_getReportSize(); usb_interruptSend(gamepad_report0, report_size); } } diff --git a/n64.c b/n64.c index 95ebbca..c74d5b2 100644 --- a/n64.c +++ b/n64.c @@ -18,31 +18,30 @@ #include #include #include -#include "gamepad.h" +#include "gamepads.h" #include "n64.h" #include "gcn64_protocol.h" -#define GCN64_REPORT_SIZE 15 - #undef BUTTON_A_RUMBLE_TEST /*********** prototypes *************/ static void n64Init(void); static char n64Update(void); -static char n64Changed(int id); -static int n64BuildReport(unsigned char *reportBuffer, int id); -static void n64SetVibration(int value); +static char n64Changed(void); +static void n64GetReport(gamepad_data *dst); +static void n64SetVibration(char enable); static char must_rumble = 0; #ifdef BUTTON_A_RUMBLE_TEST static char force_rumble = 0; #endif -/* What was most recently read from the controller */ -static unsigned char last_built_report[GCN64_REPORT_SIZE]; -/* What was most recently sent to the host */ -static unsigned char last_sent_report[GCN64_REPORT_SIZE]; +/* What was most recently read from the controller */ +static gamepad_data last_built_report; + +/* What was most recently reported through getReport */ +static gamepad_data last_sent_report; static void n64Init(void) { @@ -92,11 +91,9 @@ static char controlRumble(char enable) static char n64Update(void) { - int i; unsigned char count; unsigned char x,y; unsigned char btns1, btns2; - unsigned char rb1, rb2; unsigned char caps[3]; /* Pad answer to N64_GET_CAPABILITIES @@ -224,84 +221,40 @@ static char n64Update(void) } #endif - // Remap buttons as they always were by this - // adapter. Might change in v3 when a N64 - // specific report descriptor will be used. - // - rb1 = rb2 = 0; - for (i=0; i<4; i++) // A B Z START - rb1 |= (btns1 & (0x80 >> i)) ? (0x01<> i) ? (0x10<> i) ? (0x01<> i) ? (0x04<80) xval = 80; else if (xval<-80) xval = -80; - if (yval>80) yval = 80; else if (yval<-80) yval = -80; - - // Scale -80 ... +80 to -16000 ... +16000 - - xval *= 200; - yval *= 200; - yval = -yval; - - xval += 16000; - yval += 16000; - - last_built_report[1] = ((uint8_t*)&xval)[0]; - last_built_report[2] = ((uint8_t*)&xval)[1]; - - last_built_report[3] = ((uint8_t*)&yval)[0]; - last_built_report[4] = ((uint8_t*)&yval)[1]; - } -#ifdef CLASSIC_MODE // Adapter V1/V2 which required calibration - if (1) { - // Convert to unsigned - x = (x ^ 0x80) - 1; - y = ((y ^ 0x80) ) ^ 0xFF; - - // The following helps a cheap TTX controller - // which uses the full 8 bit range instead - // of +/- 80. The specific test here prevents - // receiving a value of 128 (instead of -127). - // - // This will have no effect on "normal" controllers. - if (x == 0xFF) - x = 0; - - last_built_report[1] = 0; - last_built_report[2] = x; - - last_built_report[3] = 0; - last_built_report[4] = y; - } -#endif - last_built_report[5] = 0x80; - last_built_report[6] = 0x3e; - - last_built_report[7] = 0x80; - last_built_report[8] = 0x3e; - - last_built_report[9] = 0x80; - last_built_report[10] = 0x3e; - - last_built_report[11] = 0x80; - last_built_report[12] = 0x3e; - - // buttons - last_built_report[13] = rb1; - last_built_report[14] = rb2; + /* Some cheap non-official controllers + * use the full 8 bit range instead of the + * normal +-80 observed on official controllers. In + * particular, some units (but not all!) produced + * by TTX. The symptom is usually "The joystick + * left direction does not work". + * + * So I limit values to the -127 to +127 range, + * otherwise it causes problem later + * when the sign is inverted. Using 16 bit + * signed numbers instead of 8 bit would solve + * this, but this is only for cheap, not + * even worth using controllers so I don't + * care. + * + * The joystick will now "work" as bad as it would + * on a N64, or maybe a little better. This should + * help people realise they got what the paid for + * instead of suspecting the adapter. */ + if (last_built_report.n64.x == -128) + last_built_report.n64.x = -127; + if (last_built_report.n64.y == -128) + last_built_report.n64.y = -127; return 0; } @@ -338,32 +291,30 @@ static char n64Probe(void) return 0; } -static char n64Changed(int id) +static char n64Changed(void) { - return memcmp(last_built_report, last_sent_report, GCN64_REPORT_SIZE); + return memcmp(&last_built_report, &last_sent_report, sizeof(gamepad_data)); } -static int n64BuildReport(unsigned char *reportBuffer, int id) +static void n64GetReport(gamepad_data *dst) { - if (reportBuffer) - memcpy(reportBuffer, last_built_report, GCN64_REPORT_SIZE); + if (dst) + memcpy(dst, &last_built_report, sizeof(gamepad_data)); - memcpy( last_sent_report, last_built_report, GCN64_REPORT_SIZE); - return GCN64_REPORT_SIZE; + memcpy(&last_sent_report, &last_built_report, sizeof(gamepad_data)); } -static void n64SetVibration(int value) +static void n64SetVibration(char enable) { - must_rumble = value; + must_rumble = enable; } static Gamepad N64Gamepad = { .init = n64Init, .update = n64Update, .changed = n64Changed, - .buildReport = n64BuildReport, + .getReport = n64GetReport, .probe = n64Probe, - .num_reports = 1, .setVibration = n64SetVibration, }; diff --git a/n64.h b/n64.h index 5bd5afd..0b16442 100644 --- a/n64.h +++ b/n64.h @@ -1,4 +1,4 @@ -#include "gamepad.h" +#include "gamepads.h" Gamepad *n64GetGamepad(void);