thwill Guru Joined: 16/09/2019 Location: United KingdomPosts: 4196
Posted: 12:07pm 03 Feb 2025
Moving conversation from the "wrong" thread. matherp said The bit I'm stuck with is how the device descriptor maps onto the bits in your sdl coding. In the case of my gamepad the 8 buttons are in byte 5 bits 4,5,6,7 and byte 6 bits 0,1,4,5 The d-pad is pseudo analog in bytes 0 and 1. If you look at the AI print on the other thread - you can interpret the analog dpad and it points to byte 5 and 6 for the buttons but I can't see how to understand which bits are which. Perhaps that is in the sdl info? Have you got a readout for PID E401, VID 081F? you can let me see? The latest PicoMite.zip above just reports an "invalid address, resetting" error when I call the DEVICE(GAMEPAD <id>) function. Rather than the "No-name" (PID E401, VID 081F) which the PicoMite doesn't like at all (if it is attached then even the keyboard is non-functional) can I suggest on my machine we concentrate on the "Buffalo Classic USB Gamepad" (pid=&H2060, vid=&H583) as this is a named brand and cost some real money. In the meantime I've analysed the code for the two generic and PS3 gamepads you already support vs. their SDL mappings and at least for the generics it looks like there may be some sort of correlation between the button numbers b# and where in the report data structure the values are read from, but it's not trivial and I don't have a large enough sample size (or at the moment brainpower) to identify precisely what the mapping is, I think there is more in the original descriptor I need to be able to understand: // vid == 0x0810 (2064) && pid == 0xE501 (58625) 030000001008000001e5000010010000, NEXT SNES Controller, a:b2, b:b1, back:b8, dpdown:+a1, dpleft:-a0, dpright:+a0, dpup:-a1, leftshoulder:b4, rightshoulder:b5, righttrigger:b6, start:b9, x:b3, y:b0, platform:Linux, void process_specific_gamepad(uint8_t const* report, uint16_t len, uint8_t n) { nunstruct[n].type=SNES; uint16_t b=0; if(report[5] & 0x10)b|=1<<10; // byte 6, bit 4 - Button X - b3 if(report[5] & 0x20)b|=1<<11; // byte 6, bit 6 - Button A - b2 if(report[5] & 0x40)b|=1<<13; // byte 6, bit 7 - Button B - b1 if(report[5] & 0x80)b|=1<<12; // byte 6, bit 8 - Button Y - b0 if(report[6] & 1)b|=1<<4; // byte 7, bit 0 - Button L - b4 if(report[6] & 2)b|=1; // byte 7, bit 1 - Button R - b5 // byte 7, bit 2 - Unused - possibly b6 ? // byte 7, bit 3 - Unused - possibly b7 ? if(report[6] & 0x10)b|=1<<3; // byte 7, bit 4 - Button Select - b8 if(report[6] & 0x20)b|=1<<1; // byte 7, bit 5 - Button Start - b9 if(report[3] < 0x40)b|=1<<8; if(report[3] > 0xC0)b|=1<<6; if(report[4] < 0x40)b|=1<<7; if(report[4] > 0xC0)b|=1<<5; ... } // vid == 0x081F (2079) && pid == 0xE401 (58369) 030000001f08000001e4000010010000, Super Famicom Controller, a:b2, b:b1, back:b8, dpdown:+a1, dpleft:-a0, dpright:+a0, dpup:-a1, leftshoulder:b4, rightshoulder:b5, start:b9, x:b3, y:b0, platform:Linux, void process_generic_gamepad(uint8_t const* report, uint16_t len, uint8_t n) { nunstruct[n].type=SNES; uint16_t b=0; if(report[5] & 0x10)b|=1<<10; // byte 6, bit 4 - Button X - b3 if(report[5] & 0x20)b|=1<<11; // byte 6, bit 6 - Button A - b2 if(report[5] & 0x40)b|=1<<13; // byte 6, bit 7 - Button B - b1 if(report[5] & 0x80)b|=1<<12; // byte 6, bit 8 - Button Y - b0 if(report[6] & 1)b|=1<<4; // byte 7, bit 0 - Button L - b4 if(report[6] & 2)b|=1; // byte 7, bit 1 - Button R - b5 // byte 7, bit 2 - Unused - possibly b6 ? // byte 7, bit 3 - Unused - possibly b7 ? if(report[6] & 0x10)b|=1<<3; // byte 7, bit 4 - Button Select - b8 if(report[6] & 0x20)b|=1<<1; // byte 7, bit 5 - Button Start - b9 if(report[0] < 0x7f)b|=1<<8; if(report[0] > 0x7f)b|=1<<6; if(report[1] < 0x7f)b|=1<<7; if(report[1] > 0x7f)b|=1<<5; ... } // vid == 0x054c && pid == 0x0268 030000004c0500006802000000000000, PS3 Controller, a:b2, b:b1, back:b9, dpdown:h0.4, dpleft:h0.8, dpright:h0.2, dpup:h0.1, guide:b12, leftshoulder:b6, leftstick:b10, lefttrigger:a3~, leftx:a0, lefty:a1, rightshoulder:b7, rightstick:b11, righttrigger:a4~, rightx:a2, righty:a5, start:b8, x:b3, y:b0, platform:Windows, void process_sony_ds3(uint8_t const* report, uint16_t len, uint8_t n) { nunstruct[n].type=PS3; uint16_t b=0; if(report[3]&0x80)b|=1<<12; // byte 4, bit 7 - Button Y - b0 if(report[3]&0x40)b|=1<<13; // byte 4, bit 6 - Button B - b1 if(report[3]&0x20)b|=1<<11; // byte 4, bit 5 - Button A - b2 if(report[3]&0x10)b|=1<<10; // byte 4, bit 4 - Button X - b3 if(report[3]&0x8)b|=1; // byte 4, bit 3 - Button R - b7 if(report[3]&0x4)b|=1<<4; // byte 4, bit 2 - Button L - b6 if(report[3]&0x2)b|=1<<9; // byte 4, bit 1 - Button R2 - are these the analog triggers (a4~) or the stick buttons (b10) ? if(report[3]&0x1)b|=1<<14; // byte 4, bit 0 - Button L2 - are these the analog triggers (a3~) or the stick buttons (b11) ? if(report[2]&0x80)b|=1<<8; // byte 3, bit 7 - Button Left - h0.8 if(report[2]&0x40)b|=1<<5; // byte 3, bit 6 - Button Down - h0.4 if(report[2]&0x20)b|=1<<6; // byte 3, bit 5 - Button Right - h0.2 if(report[2]&0x10)b|=1<<7; // byte 3, bit 4 - Button Up - h0.1 if(report[2]&0x8)b|=1<<1; // byte 3, bit 3 - Start - b8 if(report[2]&0x1)b|=1<<3; // byte 3, bit 0 - Select (Back) - b9 if(report[4]&0x1)b|=1<<2; // byte 5, bit 0 - Home (Guide) - b12 nunstruct[n].ax=report[6]; nunstruct[n].ay=report[7]; nunstruct[n].Z=report[8]; nunstruct[n].C=report[9]; nunstruct[n].L=report[18]; nunstruct[n].R=report[19]; ... }
Best wishes, TomEdited 2025-02-03 22:09 by thwill