mirror of
https://github.com/raphnet/4nes4snes
synced 2024-12-21 22:48:51 -05:00
fixes
This commit is contained in:
parent
b772e29b7a
commit
ec9d9997ab
@ -1,2 +1,9 @@
|
||||
--- v1.1 (18 Apr 2007)
|
||||
- Changed report descriptor. There are now four separate report IDs, one
|
||||
per controller. This was necessary because even though all axis and buttons
|
||||
were perfectly functional in 'control panel -> game controllers', it was not
|
||||
the case in many games, including zsnes and snes9x!
|
||||
- Changed device id to 0x0A9D
|
||||
|
||||
--- v1.0 (24 Mar 2007)
|
||||
Initial release.
|
||||
|
@ -57,9 +57,9 @@ Table of contents:
|
||||
http://www.mecanique.co.uk/products/usb/pid.html
|
||||
|
||||
|
||||
6) Where do I get more information and updates?
|
||||
6) Where can I get more information and updates?
|
||||
--------------------------------------------
|
||||
Visit 4nes4snes page:
|
||||
Visit the 4nes4snes webpage:
|
||||
http://www.raphnet.net/electronique/4nes4snes/index_en.php
|
||||
you may also contact me by email:
|
||||
Raphael Assenat <raph@raphnet.net>
|
||||
|
11
gamepad.h
11
gamepad.h
@ -3,7 +3,7 @@
|
||||
|
||||
typedef struct {
|
||||
// size of reports built by buildReport
|
||||
int report_size;
|
||||
char num_reports;
|
||||
|
||||
int reportDescriptorSize;
|
||||
void *reportDescriptor; // must be in flash
|
||||
@ -13,8 +13,13 @@ typedef struct {
|
||||
|
||||
void (*init)(void);
|
||||
void (*update)(void);
|
||||
char (*changed)(void);
|
||||
void (*buildReport)(unsigned char *buf);
|
||||
|
||||
char (*changed)(char id);
|
||||
/**
|
||||
* \param id Controller id (starting at 1 to match report IDs)
|
||||
* \return The number of bytes written to buf.
|
||||
* */
|
||||
char (*buildReport)(unsigned char *buf, char id);
|
||||
} Gamepad;
|
||||
|
||||
#endif // _gamepad_h__
|
||||
|
180
main.c
180
main.c
@ -25,6 +25,9 @@
|
||||
#include "leds.h"
|
||||
#include "devdesc.h"
|
||||
|
||||
/* The maximum number of independent reports that are supported. */
|
||||
#define MAX_REPORTS 8
|
||||
|
||||
int usbCfgSerialNumberStringDescriptor[] PROGMEM = {
|
||||
USB_STRING_DESCRIPTOR_HEADER(USB_CFG_SERIAL_NUMBER_LENGTH),
|
||||
'1', '0', '0', '0'
|
||||
@ -78,76 +81,61 @@ static uchar reportBuffer[12]; /* buffer for HID reports */
|
||||
/* ----------------------------- USB interface ----------------------------- */
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
static uchar idleRate; /* in 4 ms units */
|
||||
static uchar idleRates[MAX_REPORTS]; /* in 4 ms units */
|
||||
|
||||
static uchar reportPos=0;
|
||||
|
||||
uchar usbFunctionSetup(uchar data[8])
|
||||
{
|
||||
usbRequest_t *rq = (void *)data;
|
||||
int i;
|
||||
|
||||
usbMsgPtr = reportBuffer;
|
||||
if((rq->bmRequestType & USBRQ_TYPE_MASK) == USBRQ_TYPE_CLASS){ /* class request type */
|
||||
if(rq->bRequest == USBRQ_HID_GET_REPORT){ /* wValue: ReportType (highbyte), ReportID (lowbyte) */
|
||||
/* we only have one report type, so don't look at wValue */
|
||||
reportPos=0;
|
||||
//curGamepad->buildReport(reportBuffer);
|
||||
//return curGamepad->report_size;
|
||||
return 0xff;
|
||||
}else if(rq->bRequest == USBRQ_HID_GET_IDLE){
|
||||
usbMsgPtr = &idleRate;
|
||||
return 1;
|
||||
}else if(rq->bRequest == USBRQ_HID_SET_IDLE){
|
||||
idleRate = rq->wValue.bytes[1];
|
||||
|
||||
/* class request type */
|
||||
if((rq->bmRequestType & USBRQ_TYPE_MASK) == USBRQ_TYPE_CLASS){
|
||||
switch (rq->bRequest)
|
||||
{
|
||||
case USBRQ_HID_GET_REPORT:
|
||||
/* wValue: ReportType (highbyte), ReportID (lowbyte) */
|
||||
reportPos=0;
|
||||
return curGamepad->buildReport(reportBuffer, rq->wValue.bytes[0]);
|
||||
|
||||
case USBRQ_HID_GET_IDLE:
|
||||
if (rq->wValue.bytes[0] > 0 && rq->wValue.bytes[0] <= MAX_REPORTS) {
|
||||
usbMsgPtr = idleRates + (rq->wValue.bytes[0] - 1);
|
||||
return 1;
|
||||
}
|
||||
break;
|
||||
|
||||
case USBRQ_HID_SET_IDLE:
|
||||
if (rq->wValue.bytes[0]==0) {
|
||||
for (i=0; i<MAX_REPORTS; i++)
|
||||
idleRates[i] = rq->wValue.bytes[1];
|
||||
}
|
||||
else {
|
||||
if (rq->wValue.bytes[0] > 0 && rq->wValue.bytes[0] <= MAX_REPORTS) {
|
||||
idleRates[rq->wValue.bytes[0]-1] = rq->wValue.bytes[1];
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}else{
|
||||
/* no vendor specific requests implemented */
|
||||
} else {
|
||||
/* no vendor specific requests implemented */
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
uchar usbFunctionRead(uchar *data, uchar len)
|
||||
{
|
||||
char i,c;
|
||||
for (c=0; reportPos < sizeof(reportBuffer) && c<len; c++, reportPos++)
|
||||
{
|
||||
*data = reportBuffer[reportPos];
|
||||
i++;
|
||||
}
|
||||
return c;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
int main(void)
|
||||
{
|
||||
char must_report = 0, first_run = 1;
|
||||
uchar idleCounter = 0;
|
||||
// int run_mode;
|
||||
char must_report = 0; /* bitfield */
|
||||
uchar idleCounters[MAX_REPORTS];
|
||||
int i;
|
||||
|
||||
// led pin as output
|
||||
// DDRD |= 0x20;
|
||||
memset(idleCounters, 0, MAX_REPORTS);
|
||||
|
||||
#if 0
|
||||
/* Dip switch common: DB0, outputs: DB1 and DB2 */
|
||||
DDRB |= 0x01;
|
||||
DDRB &= ~0x06;
|
||||
|
||||
PORTB |= 0x06; /* enable pull up on DB1 and DB2 */
|
||||
PORTB &= ~0x01; /* Set DB0 to low */
|
||||
|
||||
_delay_ms(10); /* let pins settle */
|
||||
run_mode = (PINB & 0x06)>>1;
|
||||
|
||||
switch(run_mode)
|
||||
{
|
||||
default:
|
||||
case 3:
|
||||
curGamepad = snesGetGamepad();
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
|
||||
curGamepad = snesGetGamepad();
|
||||
|
||||
// configure report descriptor according to
|
||||
@ -173,6 +161,9 @@ int main(void)
|
||||
curGamepad->init();
|
||||
odDebugInit();
|
||||
usbInit();
|
||||
|
||||
curGamepad->update();
|
||||
|
||||
sei();
|
||||
DBG1(0x00, 0, 0);
|
||||
|
||||
@ -183,71 +174,66 @@ int main(void)
|
||||
// this must be called at each 50 ms or less
|
||||
usbPoll();
|
||||
|
||||
if (first_run) {
|
||||
curGamepad->update();
|
||||
first_run = 0;
|
||||
}
|
||||
|
||||
if(TIFR & (1<<TOV0)){ /* 22 ms timer */
|
||||
TIFR = 1<<TOV0;
|
||||
if(idleRate != 0){
|
||||
if(idleCounter > 4){
|
||||
idleCounter -= 5; /* 22 ms in units of 4 ms */
|
||||
}else{
|
||||
idleCounter = idleRate;
|
||||
must_report = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Read the controllers at 60hz */
|
||||
if (TIFR & (1<<OCF2))
|
||||
{
|
||||
TIFR = 1<<OCF2;
|
||||
if (!must_report)
|
||||
{
|
||||
curGamepad->update();
|
||||
if (curGamepad->changed()) {
|
||||
must_report = 1;
|
||||
|
||||
curGamepad->update();
|
||||
|
||||
/* Check what will have to be reported */
|
||||
for (i=0; i<curGamepad->num_reports; i++) {
|
||||
if (curGamepad->changed(i+1)) {
|
||||
must_report |= (1<<i);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/* Try to report at the granularity requested by
|
||||
* the host. */
|
||||
if (TIFR & (1<<TOV0)) { /* 22 ms timer */
|
||||
TIFR = 1<<TOV0;
|
||||
|
||||
for (i=0; i<curGamepad->num_reports; i++)
|
||||
{
|
||||
// 0 means
|
||||
if(idleRates[i] != 0){
|
||||
if (idleCounters[i] > 4) {
|
||||
idleCounters[i] -= 5; /* 22 ms in units of 4 ms */
|
||||
} else {
|
||||
// reset the counter and schedule a report for this
|
||||
idleCounters[i] = idleRates[i];
|
||||
must_report |= (1<<i);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
if(must_report)
|
||||
{
|
||||
if (usbInterruptIsReady())
|
||||
{
|
||||
int reported=0;
|
||||
unsigned char empty=0;
|
||||
for (i = 0; i < curGamepad->num_reports; i++)
|
||||
{
|
||||
if ((must_report & (1<<i)) == 0)
|
||||
continue;
|
||||
|
||||
curGamepad->buildReport(reportBuffer);
|
||||
reportPos = 0;
|
||||
if (usbInterruptIsReady())
|
||||
{
|
||||
char len;
|
||||
|
||||
while (reported < curGamepad->report_size)
|
||||
{
|
||||
int cur_report_siz;
|
||||
|
||||
|
||||
if (curGamepad->report_size - reported >= 8)
|
||||
cur_report_siz = 8;
|
||||
else
|
||||
cur_report_siz = curGamepad->report_size - reported;
|
||||
|
||||
usbSetInterrupt(&reportBuffer[reported], cur_report_siz);
|
||||
len = curGamepad->buildReport(reportBuffer, i+1);
|
||||
usbSetInterrupt(reportBuffer, len);
|
||||
|
||||
while (!usbInterruptIsReady())
|
||||
{
|
||||
usbPoll();
|
||||
wdt_reset();
|
||||
}
|
||||
|
||||
reported += cur_report_siz;
|
||||
}
|
||||
|
||||
usbSetInterrupt(&empty, 0);
|
||||
must_report = 0;
|
||||
}
|
||||
|
||||
must_report = 0;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
|
209
snes.c
209
snes.c
@ -16,7 +16,6 @@
|
||||
#include "leds.h"
|
||||
#include "snes.h"
|
||||
|
||||
#define REPORT_SIZE 12
|
||||
#define GAMEPAD_BYTES 8 /* 2 byte per snes controller * 4 controllers */
|
||||
|
||||
/******** IO port definitions **************/
|
||||
@ -50,8 +49,8 @@
|
||||
/*********** prototypes *************/
|
||||
static void snesInit(void);
|
||||
static void snesUpdate(void);
|
||||
static char snesChanged(void);
|
||||
static void snesBuildReport(unsigned char *reportBuffer);
|
||||
static char snesChanged(char report_id);
|
||||
static char snesBuildReport(unsigned char *reportBuffer, char report_id);
|
||||
|
||||
|
||||
// the most recent bytes we fetched from the controller
|
||||
@ -205,13 +204,13 @@ static void snesUpdate(void)
|
||||
|
||||
}
|
||||
|
||||
static char snesChanged(void)
|
||||
static char snesChanged(char report_id)
|
||||
{
|
||||
static int first = 1;
|
||||
if (first) { first = 0; return 1; }
|
||||
|
||||
return memcmp(last_read_controller_bytes,
|
||||
last_reported_controller_bytes, GAMEPAD_BYTES);
|
||||
report_id--; // first report is 1
|
||||
|
||||
return memcmp( &last_read_controller_bytes[report_id<<1],
|
||||
&last_reported_controller_bytes[report_id<<1],
|
||||
2);
|
||||
}
|
||||
|
||||
static char getX(unsigned char nesByte1)
|
||||
@ -245,8 +244,13 @@ static unsigned char snesReorderButtons(unsigned char bytes[2])
|
||||
return v;
|
||||
}
|
||||
|
||||
static void snesBuildReport(unsigned char *reportBuffer)
|
||||
static char snesBuildReport(unsigned char *reportBuffer, char id)
|
||||
{
|
||||
char idx;
|
||||
|
||||
if (id < 0 || id > 4)
|
||||
return 0;
|
||||
|
||||
/* last_read_controller_bytes[] structure:
|
||||
*
|
||||
* [0] : controller 1, 8 first bits (dpad + start + sel + y|a + b)
|
||||
@ -262,86 +266,139 @@ static void snesBuildReport(unsigned char *reportBuffer)
|
||||
* [7] : controller 4, 4 extra snes buttons
|
||||
*/
|
||||
|
||||
idx = id - 1;
|
||||
if (reportBuffer != NULL)
|
||||
{
|
||||
reportBuffer[0]=getX(last_read_controller_bytes[0]);
|
||||
reportBuffer[1]=getY(last_read_controller_bytes[0]);
|
||||
reportBuffer[2]=getX(last_read_controller_bytes[2]);
|
||||
reportBuffer[3]=getY(last_read_controller_bytes[2]);
|
||||
reportBuffer[4]=getX(last_read_controller_bytes[4]);
|
||||
reportBuffer[5]=getY(last_read_controller_bytes[4]);
|
||||
reportBuffer[6]=getX(last_read_controller_bytes[6]);
|
||||
reportBuffer[7]=getY(last_read_controller_bytes[6]);
|
||||
reportBuffer[0]=id;
|
||||
reportBuffer[1]=getX(last_read_controller_bytes[idx*2]);
|
||||
reportBuffer[2]=getY(last_read_controller_bytes[idx*2]);
|
||||
|
||||
if (nesMode & 0x01)
|
||||
reportBuffer[8] = last_read_controller_bytes[0] & 0xf0;
|
||||
if (nesMode & (0x01<<idx))
|
||||
reportBuffer[3] = last_read_controller_bytes[idx*2] & 0xf0;
|
||||
else
|
||||
reportBuffer[8] = snesReorderButtons(&last_read_controller_bytes[0]);
|
||||
|
||||
if (nesMode & 0x02)
|
||||
reportBuffer[9] = last_read_controller_bytes[2] & 0xf0;
|
||||
else
|
||||
reportBuffer[9] = snesReorderButtons(&last_read_controller_bytes[2]);
|
||||
|
||||
if (nesMode & 0x04)
|
||||
reportBuffer[10] = last_read_controller_bytes[4] & 0xf0;
|
||||
else
|
||||
reportBuffer[10] = snesReorderButtons(&last_read_controller_bytes[4]);
|
||||
|
||||
if (nesMode & 0x08)
|
||||
reportBuffer[11] = last_read_controller_bytes[6] & 0xf0;
|
||||
else
|
||||
reportBuffer[11] = snesReorderButtons(&last_read_controller_bytes[6]);
|
||||
|
||||
|
||||
reportBuffer[3] = snesReorderButtons(&last_read_controller_bytes[idx*2]);
|
||||
}
|
||||
memcpy(last_reported_controller_bytes,
|
||||
last_read_controller_bytes,
|
||||
GAMEPAD_BYTES);
|
||||
|
||||
memcpy(&last_reported_controller_bytes[idx*2],
|
||||
&last_read_controller_bytes[idx*2],
|
||||
2);
|
||||
|
||||
return 4;
|
||||
}
|
||||
|
||||
const char snes_usbHidReportDescriptor[] PROGMEM = {
|
||||
0x05, 0x01, // USAGE_PAGE (Generic Desktop)
|
||||
0x09, 0x04, // USAGE (Joystick)
|
||||
0xa1, 0x01, // COLLECTION (Application)
|
||||
0x09, 0x01, // USAGE (Pointer)
|
||||
0xa1, 0x00, // COLLECTION (Physical)
|
||||
|
||||
0x09, 0x30, // USAGE (X)
|
||||
0x09, 0x31, // USAGE (Y)
|
||||
0x09, 0x32, // USAGE (Z)
|
||||
0x09, 0x33, // USAGE (Rx)
|
||||
0x09, 0x34, // USAGE (Ry)
|
||||
0x09, 0x35, // USAGE (Rz)
|
||||
0x09, 0x36, // USAGE (Slider)
|
||||
0x09, 0x37, // USAGE (Dial)
|
||||
|
||||
0x15, 0x00, // LOGICAL_MINIMUM (0)
|
||||
0x26, 0xff, 0x00, // LOGICAL_MAXIMUM (255)
|
||||
0x75, 0x08, // REPORT_SIZE (8)
|
||||
0x95, 0x08, // REPORT_COUNT (8)
|
||||
0x81, 0x02, // INPUT (Data,Var,Abs)
|
||||
0xc0, // END_COLLECTION
|
||||
/* Controller and report_id 1 */
|
||||
0x05, 0x01, // USAGE_PAGE (Generic Desktop)
|
||||
0x09, 0x04, // USAGE (Joystick)
|
||||
0xa1, 0x01, // COLLECTION (Application)
|
||||
0x09, 0x01, // USAGE (Pointer)
|
||||
0xa1, 0x00, // COLLECTION (Physical)
|
||||
0x85, 0x01, // REPORT_ID (1)
|
||||
0x09, 0x30, // USAGE (X)
|
||||
0x09, 0x31, // USAGE (Y)
|
||||
0x15, 0x00, // LOGICAL_MINIMUM (0)
|
||||
0x26, 0xff, 0x00, // LOGICAL_MAXIMUM (255)
|
||||
0x75, 0x08, // REPORT_SIZE (8)
|
||||
0x95, 0x02, // REPORT_COUNT (2)
|
||||
0x81, 0x02, // INPUT (Data,Var,Abs)
|
||||
|
||||
0x05, 0x09, // USAGE_PAGE (Button)
|
||||
0x19, 1, // USAGE_MINIMUM (Button 1)
|
||||
0x29, 8, // USAGE_MAXIMUM (Button 8)
|
||||
0x15, 0x00, // LOGICAL_MINIMUM (0)
|
||||
0x25, 0x01, // LOGICAL_MAXIMUM (1)
|
||||
0x75, 1, // REPORT_SIZE (1)
|
||||
0x95, 8, // REPORT_COUNT (8)
|
||||
0x81, 0x02, // INPUT (Data,Var,Abs)
|
||||
0xc0, // END_COLLECTION
|
||||
0xc0, // END_COLLECTION
|
||||
|
||||
/* Controller and report_id 2 */
|
||||
0x05, 0x01, // USAGE_PAGE (Generic Desktop)
|
||||
0x09, 0x04, // USAGE (Joystick)
|
||||
0xa1, 0x01, // COLLECTION (Application)
|
||||
0x09, 0x01, // USAGE (Pointer)
|
||||
0xa1, 0x00, // COLLECTION (Physical)
|
||||
0x85, 0x02, // REPORT_ID (2)
|
||||
0x09, 0x30, // USAGE (X)
|
||||
0x09, 0x31, // USAGE (Y)
|
||||
0x15, 0x00, // LOGICAL_MINIMUM (0)
|
||||
0x26, 0xff, 0x00, // LOGICAL_MAXIMUM (255)
|
||||
0x75, 0x08, // REPORT_SIZE (8)
|
||||
0x95, 0x02, // REPORT_COUNT (2)
|
||||
0x81, 0x02, // INPUT (Data,Var,Abs)
|
||||
0x05, 0x09, // USAGE_PAGE (Button)
|
||||
0x19, 1, // USAGE_MINIMUM (Button 1)
|
||||
0x29, 8, // USAGE_MAXIMUM (Button 8)
|
||||
0x15, 0x00, // LOGICAL_MINIMUM (0)
|
||||
0x25, 0x01, // LOGICAL_MAXIMUM (1)
|
||||
0x75, 1, // REPORT_SIZE (1)
|
||||
0x95, 8, // REPORT_COUNT (8)
|
||||
0x81, 0x02, // INPUT (Data,Var,Abs)
|
||||
0xc0, // END_COLLECTION
|
||||
0xc0, // END_COLLECTION
|
||||
|
||||
/* Controller and report_id 3 */
|
||||
0x05, 0x01, // USAGE_PAGE (Generic Desktop)
|
||||
0x09, 0x04, // USAGE (Joystick)
|
||||
0xa1, 0x01, // COLLECTION (Application)
|
||||
0x09, 0x01, // USAGE (Pointer)
|
||||
0xa1, 0x00, // COLLECTION (Physical)
|
||||
0x85, 0x03, // REPORT_ID (3)
|
||||
0x09, 0x30, // USAGE (X)
|
||||
0x09, 0x31, // USAGE (Y)
|
||||
0x15, 0x00, // LOGICAL_MINIMUM (0)
|
||||
0x26, 0xff, 0x00, // LOGICAL_MAXIMUM (255)
|
||||
0x75, 0x08, // REPORT_SIZE (8)
|
||||
0x95, 0x02, // REPORT_COUNT (2)
|
||||
0x81, 0x02, // INPUT (Data,Var,Abs)
|
||||
0x05, 0x09, // USAGE_PAGE (Button)
|
||||
0x19, 1, // USAGE_MINIMUM (Button 1)
|
||||
0x29, 8, // USAGE_MAXIMUM (Button 8)
|
||||
0x15, 0x00, // LOGICAL_MINIMUM (0)
|
||||
0x25, 0x01, // LOGICAL_MAXIMUM (1)
|
||||
0x75, 1, // REPORT_SIZE (1)
|
||||
0x95, 8, // REPORT_COUNT (8)
|
||||
0x81, 0x02, // INPUT (Data,Var,Abs)
|
||||
0xc0, // END_COLLECTION
|
||||
0xc0, // END_COLLECTION
|
||||
|
||||
/* Controller and report_id 4 */
|
||||
0x05, 0x01, // USAGE_PAGE (Generic Desktop)
|
||||
0x09, 0x04, // USAGE (Joystick)
|
||||
0xa1, 0x01, // COLLECTION (Application)
|
||||
0x09, 0x01, // USAGE (Pointer)
|
||||
0xa1, 0x00, // COLLECTION (Physical)
|
||||
0x85, 0x04, // REPORT_ID (4)
|
||||
0x09, 0x30, // USAGE (X)
|
||||
0x09, 0x31, // USAGE (Y)
|
||||
0x15, 0x00, // LOGICAL_MINIMUM (0)
|
||||
0x26, 0xff, 0x00, // LOGICAL_MAXIMUM (255)
|
||||
0x75, 0x08, // REPORT_SIZE (8)
|
||||
0x95, 0x02, // REPORT_COUNT (2)
|
||||
0x81, 0x02, // INPUT (Data,Var,Abs)
|
||||
0x05, 0x09, // USAGE_PAGE (Button)
|
||||
0x19, 1, // USAGE_MINIMUM (Button 1)
|
||||
0x29, 8, // USAGE_MAXIMUM (Button 8)
|
||||
0x15, 0x00, // LOGICAL_MINIMUM (0)
|
||||
0x25, 0x01, // LOGICAL_MAXIMUM (1)
|
||||
0x75, 1, // REPORT_SIZE (1)
|
||||
0x95, 8, // REPORT_COUNT (8)
|
||||
0x81, 0x02, // INPUT (Data,Var,Abs)
|
||||
0xc0, // END_COLLECTION
|
||||
0xc0, // END_COLLECTION
|
||||
|
||||
0x05, 0x09, // USAGE_PAGE (Button)
|
||||
0x19, 1, // USAGE_MINIMUM (Button 1)
|
||||
0x29, 32, // USAGE_MAXIMUM (Button 32)
|
||||
0x15, 0x00, // LOGICAL_MINIMUM (0)
|
||||
0x25, 0x01, // LOGICAL_MAXIMUM (1)
|
||||
0x75, 1, // REPORT_SIZE (1)
|
||||
0x95, 32, // REPORT_COUNT (32)
|
||||
0x81, 0x02, // INPUT (Data,Var,Abs)
|
||||
|
||||
0xc0 // END_COLLECTION
|
||||
};
|
||||
|
||||
Gamepad SnesGamepad = {
|
||||
report_size: REPORT_SIZE,
|
||||
reportDescriptorSize: sizeof(snes_usbHidReportDescriptor),
|
||||
init: snesInit,
|
||||
update: snesUpdate,
|
||||
changed: snesChanged,
|
||||
buildReport: snesBuildReport
|
||||
.num_reports = 4,
|
||||
.reportDescriptorSize = sizeof(snes_usbHidReportDescriptor),
|
||||
.init = snesInit,
|
||||
.update = snesUpdate,
|
||||
.changed = snesChanged,
|
||||
.buildReport = snesBuildReport
|
||||
};
|
||||
|
||||
Gamepad *snesGetGamepad(void)
|
||||
|
16
usbconfig.h
16
usbconfig.h
@ -5,7 +5,7 @@
|
||||
* Tabsize: 4
|
||||
* Copyright: (c) 2005 by OBJECTIVE DEVELOPMENT Software GmbH
|
||||
* License: Proprietary, free under certain conditions. See Documentation.
|
||||
* This Revision: $Id: usbconfig.h,v 1.4 2007-03-28 02:29:23 raph Exp $
|
||||
* This Revision: $Id: usbconfig.h,v 1.5 2007-04-18 23:58:01 raph Exp $
|
||||
*/
|
||||
|
||||
#ifndef __usbconfig_h_included__
|
||||
@ -55,7 +55,7 @@ must be adapted to your hardware.
|
||||
/* Define this to 1 if the device has its own power supply. Set it to 0 if the
|
||||
* device is powered from the USB bus.
|
||||
*/
|
||||
#define USB_CFG_MAX_BUS_POWER 100
|
||||
#define USB_CFG_MAX_BUS_POWER 120
|
||||
/* Set this variable to the maximum USB bus power consumption of your device.
|
||||
* The value is in milliamperes. [It will be divided by two since USB
|
||||
* communicates power requirements in units of 2 mA.]
|
||||
@ -74,7 +74,7 @@ must be adapted to your hardware.
|
||||
* transfers. Set it to 0 if you don't need it and want to save a couple of
|
||||
* bytes.
|
||||
*/
|
||||
#define USB_CFG_IMPLEMENT_FN_READ 1
|
||||
#define USB_CFG_IMPLEMENT_FN_READ 0
|
||||
/* Set this to 1 if you need to send control replies which are generated
|
||||
* "on the fly" when usbFunctionRead() is called. If you only want to send
|
||||
* data from a static buffer, set it to 0 and return the data from
|
||||
@ -95,14 +95,14 @@ must be adapted to your hardware.
|
||||
* own Vendor ID, define it here. Otherwise you use obdev's free shared
|
||||
* VID/PID pair. Be sure to read USBID-License.txt for rules!
|
||||
*/
|
||||
#define USB_CFG_DEVICE_ID 0x9c, 0x0a
|
||||
#define USB_CFG_DEVICE_ID 0x9d, 0x0a
|
||||
/* This is the ID of the product, low byte first. It is interpreted in the
|
||||
* scope of the vendor ID. If you have registered your own VID with usb.org
|
||||
* or if you have licensed a PID from somebody else, define it here. Otherwise
|
||||
* you use obdev's free shared VID/PID pair. Be sure to read the rules in
|
||||
* USBID-License.txt!
|
||||
*/
|
||||
#define USB_CFG_DEVICE_VERSION 0x00, 0x01
|
||||
#define USB_CFG_DEVICE_VERSION 0x01, 0x01
|
||||
/* Version number of the device: Minor number first, then major number.
|
||||
*/
|
||||
#define USB_CFG_VENDOR_NAME 'r', 'a', 'p', 'h', 'n', 'e', 't', '.', 'n', 'e', 't'
|
||||
@ -115,10 +115,8 @@ must be adapted to your hardware.
|
||||
* obdev's free shared VID/PID pair. See the file USBID-License.txt for
|
||||
* details.
|
||||
*/
|
||||
#define USB_CFG_DEVICE_NAME 'R','a','p','n','e','t','.','n','e','t', \
|
||||
'\'', 's', ' ', '8',' ','A','x','e','s', \
|
||||
',',' ', '3','2',' ','B','u','t','t','o','n','s'
|
||||
#define USB_CFG_DEVICE_NAME_LEN 31
|
||||
#define USB_CFG_DEVICE_NAME '4','n','e','s','4','s','n','e','s'
|
||||
#define USB_CFG_DEVICE_NAME_LEN 9
|
||||
/* Same as above for the device name. If you don't want a device name, undefine
|
||||
* the macros. See the file USBID-License.txt before you assign a name.
|
||||
*/
|
||||
|
Loading…
Reference in New Issue
Block a user