Home
JAQForum Ver 24.01
Log In or Join  
Active Topics
Local Time 01:00 08 Feb 2025 Privacy Policy
Jump to

Notice. New forum software under development. It's going to miss a few functions and look a bit ugly for a while, but I'm working on it full time now as the old forum was too unstable. Couple days, all good. If you notice any issues, please contact me.

Forum Index : Microcontroller and PC projects : PicoMiteVGAUSB: What gamepads are supported ?

     Page 1 of 2    
Author Message
thwill

Guru

Joined: 16/09/2019
Location: United Kingdom
Posts: 4136
Posted: 11:56am 02 Feb 2025
Copy link to clipboard 
Print this post

Hi folks,

Using real 'mite hardware for the first time in months whilst trying to implement USB gamepad support for PETSCII Robots.

Which USB gamepads are supported? I've tried all the following with no response:

    - Official XBOX 360 gamepad
    - 3rd party XBOX 360 gamepad
    - "Buffalo Classic USB Gamepad" - looks like a SNES gamepad
    - "The Pi Hut" labelled SNES look-alike USB gamepad
    - No-name SNES look-alike USB gamepad

Running "PicoMiteVGA MMBasic USB RP2040 Edition v6.00.02b4" on a PCB by @bigmik that I'm not sure he ever published on TBS.

USB keyboard works, and USB mouse at least registers (I don't have a test program for it).

Best wishes,

Tom
MMBasic for Linux, Game*Mite, CMM2 Welcome Tape, Creaky old text adventures
 
thwill

Guru

Joined: 16/09/2019
Location: United Kingdom
Posts: 4136
Posted: 12:21pm 02 Feb 2025
Copy link to clipboard 
Print this post

Peter, assuming you haven't accidentally borked USB gamepad support entirely is there any possibility you could build a test version that dumps dev_addr, pid and vid to the display so I can see if there is any life at all. If there is, but it doesn't match what you've already encoded I'll get the tools working and look into it myself. If there is no life then it's probably a H/W problem with my soldering or this PCB.

Best wishes,

Tom
MMBasic for Linux, Game*Mite, CMM2 Welcome Tape, Creaky old text adventures
 
matherp
Guru

Joined: 11/12/2012
Location: United Kingdom
Posts: 9512
Posted: 12:57pm 02 Feb 2025
Copy link to clipboard 
Print this post

I've tested V6.00.02b6 as downloaded from Geoff and it definitely works with generic gamepads, PS4 and PS3. Xbox controllers are not specifically supported although I have included code that someone gave me which apparently works with their xbox clone (but not mine which just continuously connects and then disconnects)

This version will report Unknown device and the PID/VID for any device not specifically categorised. Let me know what happens with the gamepads and if they give sensible answers I can include them. The Xbox controllers I would ignore.


PicoMite.zip
 
Volhout
Guru

Joined: 05/03/2018
Location: Netherlands
Posts: 4529
Posted: 01:18pm 02 Feb 2025
Copy link to clipboard 
Print this post

Tom,

The USB mouse works in the build in editor. You can easily test that. It positions. I do not know if you can use it to cut/copy/paste.

Volhout
Edited 2025-02-02 23:19 by Volhout
PicomiteVGA PETSCII ROBOTS
 
thwill

Guru

Joined: 16/09/2019
Location: United Kingdom
Posts: 4136
Posted: 01:49pm 02 Feb 2025
Copy link to clipboard 
Print this post

Thanks Peter,

With just the keyboard and mouse attached it reports:

Unknown Device Connected on channel 3 (pid=&HA01B, vid=&H4D9)


If without power-cycling I attach "The Pi Hut" gamepad to the 3rd port it reports:

Unknown Device Connected on channel 3 (pid=&H11, vid=&H79)


If without power-cycling I attach the "Buffalo Classic USB Gamepad" to the 4th port it reports:

Unknown Device Connected on channel 3 (pid=&H2060, vid=&H583)


The "No-name" one is very strange, it reports nothing and if I power-cycle with it attached then even the keyboard and mouse are not reported. Linux/SDL2 can see this controller but it's not one that SDL2 has in its default map.

The X-Box controllers report nothing.

@Volhout thanks for the comment about the mouse and EDITor, that works.

Best wishes,

Tom
Edited 2025-02-02 23:50 by thwill
MMBasic for Linux, Game*Mite, CMM2 Welcome Tape, Creaky old text adventures
 
thwill

Guru

Joined: 16/09/2019
Location: United Kingdom
Posts: 4136
Posted: 02:04pm 02 Feb 2025
Copy link to clipboard 
Print this post

Linux agrees with those PID/VID combinations (lsusb) and says the "No-name" one is a "Manta gamepad" with pid=&HE401, vid=&h081F

Best wishes,

Tom
Edited 2025-02-03 00:04 by thwill
MMBasic for Linux, Game*Mite, CMM2 Welcome Tape, Creaky old text adventures
 
matherp
Guru

Joined: 11/12/2012
Location: United Kingdom
Posts: 9512
Posted: 02:22pm 02 Feb 2025
Copy link to clipboard 
Print this post

I've added those as generic gamepads. Please test and report. Note there are two variants of generic. I've put them all as the first type. If the left hand 4-way pad doesn't work as expected we can try the other. If that doesn't work I'll post a version with diags


PicoMite.zip
 
thwill

Guru

Joined: 16/09/2019
Location: United Kingdom
Posts: 4136
Posted: 03:13pm 02 Feb 2025
Copy link to clipboard 
Print this post

Thanks Peter,

* The Pi Hut gamepad now reports 256 with no buttons down.
* The Buffalo gamepad now reports 96 with no buttons down.
* With just my keyboard plugged in the PM firmware now identifies a USB gamepad on channel 3, I think that is device (pid=&HA01B, vid=&H4D9) which is not a gamepad.

<Sighs> Looks like I was talking bollocks when I suggested there was such a thing as a "generic USB" gamepad. I now know that for this reason SDL contains a reasonably large map of controller GUID => button/stick  mappings and provides mechanisms to add/override your own.

Best wishes,

Tom
Edited 2025-02-03 01:26 by thwill
MMBasic for Linux, Game*Mite, CMM2 Welcome Tape, Creaky old text adventures
 
matherp
Guru

Joined: 11/12/2012
Location: United Kingdom
Posts: 9512
Posted: 03:30pm 02 Feb 2025
Copy link to clipboard 
Print this post

Try this

PicoMite.zip

Below is the decode for the two types of generic supported. Based on these write versions for your controllers given the diagnostic and let me have them and I'll incorporate them as VID/PID specific variants
The button bitmap is as follows:
BIT 0 Button R/R1
BIT 1 Button start/options
BIT 2 Button home
BIT 3 Button select/share
BIT 4 Button L/L1
BIT 5 Button down cursor
BIT 6 Button right cursor
BIT 7 Button up cursor
BIT 8 Button left cursor
BIT 9 Right shoulder button 2/R2
BIT 10 Button x/triangle
BIT 11 Button a/circle
BIT 12 Button y/square
BIT 13 Button b/cross
BIT 14 Left should button 2/L2
BIT 15 Touchpad

  Quote  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;
if(report[5] & 0x20)b|=1<<11;
if(report[5] & 0x40)b|=1<<13;
if(report[5] & 0x80)b|=1<<12;
if(report[6] & 1)b|=1<<4;
if(report[6] & 2)b|=1;
if(report[6] & 0x10)b|=1<<3;
if(report[6] & 0x20)b|=1<<1;
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;
if((b ^ nunstruct[n].x0) & nunstruct[n].x1){
nunfoundc[n]=1;
}
nunstruct[n].x0=b;
}
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;
if(report[5] & 0x20)b|=1<<11;
if(report[5] & 0x40)b|=1<<13;
if(report[5] & 0x80)b|=1<<12;
if(report[6] & 1)b|=1<<4;
if(report[6] & 2)b|=1;
if(report[6] & 0x10)b|=1<<3;
if(report[6] & 0x20)b|=1<<1;
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;
if((b ^ nunstruct[n].x0) & nunstruct[n].x1){
nunfoundc[n]=1;
}
nunstruct[n].x0=b;
}

Edited 2025-02-03 01:34 by matherp
 
matherp
Guru

Joined: 11/12/2012
Location: United Kingdom
Posts: 9512
Posted: 04:45pm 02 Feb 2025
Copy link to clipboard 
Print this post

Here is an idea.

new command

GAMEPAD MAP array%(3,16)

// flexible configuration of gamepads
// each element in the array represents the bit in the bitmap  - ? device(gamepad n,B)
// first array element is the index into the USB report
// second element is the value related to the bit
// third element is mode
// mode 0: bit is bit not used
// mode 1: bit is set if 1
// mode 2: bit is set if 0
// mode 3: bit is set if value greater than
// mode 4: bit is set if value less than

You can already retrieve the PID/VID of a connected device with MM.INFO(USB VID n) and MM.INFO(USB PID n)

So, the code can upload the relevant mapping based on the PID/VID of the device connected. We can build a library of DIM arrays by VID PID
 
thwill

Guru

Joined: 16/09/2019
Location: United Kingdom
Posts: 4136
Posted: 04:56pm 02 Feb 2025
Copy link to clipboard 
Print this post

Before you reinvent the wheel Peter can you read the USB device's GUID or is that specific to particular OS / driver implementations ?

SDL has a standard mapping somewhat like you propose, e.g. for my Buffalo gamepad it is:
"0300c2f8830500006020000010010000,iBuffalo SNES Controller,a:b0,b:b1,back:b6,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,rightshoulder:b5,start:b7,x:b2,y:b3,hint:SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,platform:Linux"


And there are graphical tools that allow a user to generate these for any attached controller by pressing the buttons when prompted.

So if this were portable ...

Best wishes,

Tom
Edited 2025-02-03 02:57 by thwill
MMBasic for Linux, Game*Mite, CMM2 Welcome Tape, Creaky old text adventures
 
matherp
Guru

Joined: 11/12/2012
Location: United Kingdom
Posts: 9512
Posted: 05:36pm 02 Feb 2025
Copy link to clipboard 
Print this post

I've no idea how you parse that. The only thing I can get from a controller is its report description. For my gamepad it is as follows - nothing useful on button allocations

  Quote  0x05, 0x01,        // Usage Page (Generic Desktop Ctrls)
0x09, 0x04,        // Usage (Joystick)
0xA1, 0x01,        // Collection (Application)
0xA1, 0x02,        //   Collection (Logical)
0x75, 0x08,        //     Report Size (8)
0x95, 0x02,        //     Report Count (2)
0x15, 0x00,        //     Logical Minimum (0)
0x26, 0xFF, 0x00,  //     Logical Maximum (255)
0x35, 0x00,        //     Physical Minimum (0)
0x46, 0xFF, 0x00,  //     Physical Maximum (255)
0x09, 0x30,        //     Usage (X)
0x09, 0x31,        //     Usage (Y)
0x81, 0x02,        //     Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
0x95, 0x03,        //     Report Count (3)
0x81, 0x01,        //     Input (Const,Array,Abs,No Wrap,Linear,Preferred State,No Null Position)
0x75, 0x01,        //     Report Size (1)
0x95, 0x04,        //     Report Count (4)
0x15, 0x00,        //     Logical Minimum (0)
0x25, 0x01,        //     Logical Maximum (1)
0x35, 0x00,        //     Physical Minimum (0)
0x45, 0x01,        //     Physical Maximum (1)
0x81, 0x01,        //     Input (Const,Array,Abs,No Wrap,Linear,Preferred State,No Null Position)
0x65, 0x00,        //     Unit (None)
0x75, 0x01,        //     Report Size (1)
0x95, 0x0A,        //     Report Count (10)
0x25, 0x01,        //     Logical Maximum (1)
0x45, 0x01,        //     Physical Maximum (1)
0x05, 0x09,        //     Usage Page (Button)
0x19, 0x01,        //     Usage Minimum (0x01)
0x29, 0x0A,        //     Usage Maximum (0x0A)
0x81, 0x02,        //     Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
0x06, 0x00, 0xFF,  //     Usage Page (Vendor Defined 0xFF00)
0x75, 0x01,        //     Report Size (1)
0x95, 0x0A,        //     Report Count (10)
0x25, 0x01,        //     Logical Maximum (1)
0x45, 0x01,        //     Physical Maximum (1)
0x09, 0x01,        //     Usage (0x01)
0x81, 0x02,        //     Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
0xC0,              //   End Collection
0xA1, 0x02,        //   Collection (Logical)
0x75, 0x08,        //     Report Size (8)
0x95, 0x07,        //     Report Count (7)
0x46, 0xFF, 0x00,  //     Physical Maximum (255)
0x26, 0xFF, 0x00,  //     Logical Maximum (255)
0x09, 0x02,        //     Usage (0x02)
0x91, 0x02,        //     Output (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
0xC0,              //   End Collection
0xC0,              // End Collection
0x81, 0x03,        // Input (Const,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
0x15, 0x00,        // Logical Minimum (0)
0x26, 0xFF, 0x00,  // Logical Maximum (255)
0x05, 0x01,        // Usage Page (Generic Desktop Ctrls)
0x09, 0x01,        // Usage (Pointer)
0xA1, 0x00,        // Collection (Physical)
0x75, 0x08,        //   Report Size (8)
0x95, 0x04,        //   Report Count (4)
0x35, 0x00,        //   Physical Minimum (0)
0x46, 0xFF, 0x00,  //   Physical Maximum (255)
0x09, 0x30,        //   Usage (X)
0x09, 0x31,        //   Usage (Y)
0x09, 0x32,        //   Usage (Z)
0x09, 0x35,        //   Usage (Rz)
0x81, 0x02,        //   Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
0xC0,              // End Collection
0x05, 0x01,        // Usage Page (Generic Desktop Ctrls)
0x75, 0x08,        // Report Size (8)
0x95, 0x27,        // Report Count (39)
0x09, 0x01,        // Usage (Pointer)
0x81, 0x02,        // Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
0x75, 0x08,        // Report Size (8)
0x95, 0x30,        // Report Count (48)
0x09, 0x01,        // Usage (Pointer)
0x91, 0x02,        // Output (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
0x75, 0x08,        // Report Size (8)
0x95, 0x30,        // Report Count (48)
0x09, 0x01,        // Usage (Pointer)
0xB1, 0x02,        // Feature (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
0xC0,              // End Collection
0xA1, 0x02,        // Collection (Logical)
0x85, 0x02,        // Report ID (2)
0x75, 0x08,        // Report Size (8)
0x95, 0x30,        // Report Count (48)
0x09, 0x01,        // Usage (Pointer)
0xB1, 0x02,        // Feature (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
0xC0,              // End Collection
0xA1, 0x02,        // Collection (Logical)
0x85, 0xEE,        // Report ID (-18)
0x75, 0x08,        // Report Size (8)
0x95, 0x30,        // Report Count (48)
0x09, 0x01,        // Usage (Pointer)
0xB1, 0x02,        // Feature (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
0xC0,              // End Collection
0xA1, 0x02,        // Collection (Logical)
0x85, 0xEF,        // Report ID (-17)
0x75, 0x08,        // Report Size (8)
0x95, 0x30,        // Report Count (48)
0x09, 0x01,        // Usage (Pointer)
0xB1, 0x02,        // Feature (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
0xC0,              // End Collection

Edited 2025-02-03 03:40 by matherp
 
thwill

Guru

Joined: 16/09/2019
Location: United Kingdom
Posts: 4136
Posted: 06:26pm 02 Feb 2025
Copy link to clipboard 
Print this post

OK, the GUID is generated by SDL but is stable across Windows and Linux which I assume means it must be generated from data gathered from the USB device. I'll see whether I can get to the bottom of it, but not with any great urgency as my time for play this week has run out. I'm fairly certain that if we can find a way to re-use the SDL mapping we should since there is a large database of mappings for existing controllers plus GUI tools for generating new ones for unknown controllers.

Thanks for your help Peter,

Tom
MMBasic for Linux, Game*Mite, CMM2 Welcome Tape, Creaky old text adventures
 
matherp
Guru

Joined: 11/12/2012
Location: United Kingdom
Posts: 9512
Posted: 07:15pm 02 Feb 2025
Copy link to clipboard 
Print this post

  Quote  
how do i interpret this

"0300c2f8830500006020000010010000,iBuffalo SNES Controller,a:b0,b:b1,back:b6,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,rightshoulder:b5,start:b7,x:b2,y:b3,hint:SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,platform:Linux"
This looks like a controller configuration file for the iBuffalo SNES Controller on a Linux system. Here's a breakdown of what each part means:

0300:c2f8:8830:50000602000001001000: This is the unique identifier for the device.

iBuffalo SNES Controller: The name of the controller.

a:b0, b:b1, back:b6, dpdown:+a1, dpleft:-a0, dpright:+a0, dpup:-a1: These lines define the button mappings for the controller. For example, a:b0 means button a is mapped to button 0.

leftshoulder:b4, rightshoulder:b5, start:b7, x:b2, y:b3: More button mappings.

hint:SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1: This is a hint to use button labels instead of numbers.

platform:Linux: Specifies the platform the configuration is for.

Does this help clarify things for you?


The bit I can't get to is the relationship between buttons and the device descriptor

  Quote  decimal 5, 1, 9, 4, 161, 1, 161, 2, 117, 8, 149, 2, 21, 0, 38, 255, 0, 53, 0, 70, 255, 0, 9, 48, 9, 49, 129, 2, 149, 3, 129, 1, 117, 1, 149, 4, 21, 0, 37, 1, 53, 0, 69, 1, 129, 1, 101, 0, 117, 1, 149, 10, 37, 1, 69, 1, 5, 9, 25, 1, 41, 10, 129, 2, 6, 0, 255, 117, 1, 149, 10, 37, 1, 69, 1, 9, 1, 129, 2, 192, 161, 2, 117, 8, 149, 7, 70, 255, 0, 38, 255, 0, 9, 2, 145, 2, 192
Got it, let's break down this USB report descriptor. I'll interpret each part so you can understand how it defines a gamepad:

USB Report Descriptor Breakdown
Usage Page and Usage:

05 01: Usage Page (Generic Desktop Controls)

09 04: Usage (Joystick)

Collection:

A1 01: Collection (Application)

A1 02: Collection (Logical)

Button Logical Parameters:

117 8: Report Size (8 bits)

149 2: Report Count (2 bytes)

21 0: Logical Minimum (0)

38 255 0: Logical Maximum (255)

Joystick Axes Logical Parameters:

53 0: Physical Minimum (0)

70 255 0: Physical Maximum (255)

9 48: Usage (X-axis)

9 49: Usage (Y-axis)

129 2: Input (Data, Variable, Absolute)

149 3: Report Count (3 bytes)

129 1: Input (Constant)

Button and Axes Report Size and Count:

117 1: Report Size (1 bit)

149 4: Report Count (4 bits)

21 0: Logical Minimum (0)

37 1: Logical Maximum (1)

53 0: Physical Minimum (0)

69 1: Physical Maximum (1)

129 1: Input (Constant)

101 0: Padding

117 1: Report Size (1 bit)

149 10: Report Count (10 bits)

37 1: Logical Maximum (1)

69 1: Physical Maximum (1)

5 9: Usage Page (Button)

25 1: Usage Minimum (Button 1)

41 10: Usage Maximum (Button 10)

129 2: Input (Data, Variable, Absolute)

Vendor-Specific Page:

6 0 255: Usage Page (Vendor-Specific)

117 1: Report Size (1 bit)

149 10: Report Count (10 bits)

37 1: Logical Maximum (1)

69 1: Physical Maximum (1)

9 1: Usage

129 2: Input (Data, Variable, Absolute)

End Collection:

192: End Collection

Additional Logical Collection:

161 2: Collection (Logical)

117 8: Report Size (8 bits)

149 7: Report Count (7 bytes)

70 255 0: Physical Maximum (255)

38 255 0: Logical Maximum (255)

9 2: Usage

145 2: Output (Data, Variable, Absolute)

192: End Collection

Interpretation
Axes: The descriptor specifies 2 axes (X and Y) with 8-bit values, ranging from 0 to 255.

Buttons: There are 10 buttons, each represented by 1 bit.

Padding: Additional bits are included to align the report size.
 
thwill

Guru

Joined: 16/09/2019
Location: United Kingdom
Posts: 4136
Posted: 08:25pm 02 Feb 2025
Copy link to clipboard 
Print this post

I'm assuming the quoted sections are output from an AI ?

Are you comparing like with like ? The SDL controller string is from my Buffalo controller but the device report is presumably from your generic gamepad ?

If it helps there are a whole lot of SDL controller strings here:

       https://github.com/mdqinc/SDL_GameControllerDB/blob/master/gamecontrollerdb.txt

And instructions on how to generate one for a specific controller here:

       https://github.com/mdqinc/SDL_GameControllerDB

Tom
MMBasic for Linux, Game*Mite, CMM2 Welcome Tape, Creaky old text adventures
 
karlelch

Senior Member

Joined: 30/10/2014
Location: Germany
Posts: 205
Posted: 11:17pm 02 Feb 2025
Copy link to clipboard 
Print this post

Hi both

I was the one requesting support for other gamepads and who was suggesting code. The whole gamepad business is frustrating; every vender seem to have their own codes and a somewhat different way of reporting the data. My „Xbox“ gamepad in addition can emulate different modes, partially depending on what the host responds when it is plugged in …….

I am not sure there is a sensible way of capturing these mappings in a big table - like in SDL. But maybe there is a way in between, leaving it to the user to figure the data out: there could be a callback that provides the report size and data of an event and leaves it to the programmer to parse the data and assign it to an output array that is standardised and the used by MMBasic to report gamepad events by the standard functions.

Best
Thomas
 
Mixtel90

Guru

Joined: 05/10/2019
Location: United Kingdom
Posts: 7106
Posted: 08:14am 03 Feb 2025
Copy link to clipboard 
Print this post

[mumble mode]
I tried to fix that with a flexible I2C design especially for us, that we had full control over. Would anyone listen?  ;)

[Foul ol' RRon mode]
I tole em. Bugrit! Millennium hand and shrimp.
[/Foul ol' Ron mode]

Wanders off to get some more dried frog pills...

[/mumble mode]


Foul ol' Ron made a guest appearance courtesy of Terry Pratchett.
Mick

Zilog Inside! nascom.info for Nascom & Gemini
Preliminary MMBasic docs & my PCB designs
 
thwill

Guru

Joined: 16/09/2019
Location: United Kingdom
Posts: 4136
Posted: 12:07pm 03 Feb 2025
Copy link to clipboard 
Print this post

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,

Tom
Edited 2025-02-03 22:09 by thwill
MMBasic for Linux, Game*Mite, CMM2 Welcome Tape, Creaky old text adventures
 
thwill

Guru

Joined: 16/09/2019
Location: United Kingdom
Posts: 4136
Posted: 09:41am 05 Feb 2025
Copy link to clipboard 
Print this post

Hello Peter,

Assuming you haven't "given up" in boredom, disgust or frustration (all understandable) did you miss:

  thwill said  The latest PicoMite.zip above just reports an "invalid address, resetting" error when I call the DEVICE(GAMEPAD <id>) function.


Best wishes,

Tom
MMBasic for Linux, Game*Mite, CMM2 Welcome Tape, Creaky old text adventures
 
Mixtel90

Guru

Joined: 05/10/2019
Location: United Kingdom
Posts: 7106
Posted: 09:49am 05 Feb 2025
Copy link to clipboard 
Print this post

Looks up the Buffalo pad on Amazon:

"Currently unavailable.
We don't know when or if this item will be back in stock."
Mick

Zilog Inside! nascom.info for Nascom & Gemini
Preliminary MMBasic docs & my PCB designs
 
     Page 1 of 2    
Print this page
© JAQ Software 2025