Skip to content

Commit 7457857

Browse files
committed
Fixed input from the MayFlash GameCube adapter with version 7 firmware
1 parent 1ec12b3 commit 7457857

File tree

1 file changed

+52
-54
lines changed

1 file changed

+52
-54
lines changed

src/joystick/hidapi/SDL_hidapi_gamecube.c

Lines changed: 52 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,9 @@
3131
#ifdef SDL_JOYSTICK_HIDAPI_GAMECUBE
3232

3333
// Define this if you want to log all packets from the controller
34-
// #define DEBUG_GAMECUBE_PROTOCOL
34+
#if 0
35+
#define DEBUG_GAMECUBE_PROTOCOL
36+
#endif
3537

3638
#define MAX_CONTROLLERS 4
3739

@@ -120,22 +122,15 @@ static bool HIDAPI_DriverGameCube_InitDevice(SDL_HIDAPI_Device *device)
120122
}
121123
device->context = ctx;
122124

123-
ctx->joysticks[0] = 0;
124-
ctx->joysticks[1] = 0;
125-
ctx->joysticks[2] = 0;
126-
ctx->joysticks[3] = 0;
127125
ctx->rumble[0] = rumbleMagic;
128-
ctx->useRumbleBrake = false;
129126

130127
if (device->vendor_id != USB_VENDOR_NINTENDO) {
131128
ctx->pc_mode = true;
132129
}
133130

134131
if (ctx->pc_mode) {
135-
for (i = 0; i < MAX_CONTROLLERS; ++i) {
136-
ResetAxisRange(ctx, i);
137-
HIDAPI_JoystickConnected(device, &ctx->joysticks[i]);
138-
}
132+
ResetAxisRange(ctx, 0);
133+
HIDAPI_JoystickConnected(device, &ctx->joysticks[0]);
139134
} else {
140135
// This is all that's needed to initialize the device. Really!
141136
if (SDL_hid_write(device->dev, &initMagic, sizeof(initMagic)) != sizeof(initMagic)) {
@@ -205,69 +200,61 @@ static void HIDAPI_DriverGameCube_SetDevicePlayerIndex(SDL_HIDAPI_Device *device
205200
{
206201
}
207202

208-
static void HIDAPI_DriverGameCube_HandleJoystickPacket(SDL_HIDAPI_Device *device, SDL_DriverGameCube_Context *ctx, const Uint8 *packet, int size)
203+
static void HIDAPI_DriverGameCube_HandleJoystickPacket(SDL_HIDAPI_Device *device, SDL_DriverGameCube_Context *ctx, const Uint8 *packet, bool invert_c_stick)
209204
{
210205
SDL_Joystick *joystick;
211-
Uint8 i, v;
206+
const Uint8 i = 0; // We have a separate context for each connected controller in PC mode, just use the first index
207+
Uint8 v;
212208
Sint16 axis_value;
213209
Uint64 timestamp = SDL_GetTicksNS();
214210

215-
if (size != 10) {
216-
return; // How do we handle this packet?
217-
}
218-
219-
i = packet[0] - 1;
220-
if (i >= MAX_CONTROLLERS) {
221-
return; // How do we handle this packet?
222-
}
223-
224211
joystick = SDL_GetJoystickFromID(ctx->joysticks[i]);
225212
if (!joystick) {
226213
// Hasn't been opened yet, skip
227214
return;
228215
}
229216

230-
#define READ_BUTTON(off, flag, button) \
231-
SDL_SendJoystickButton( \
232-
timestamp, \
233-
joystick, \
234-
button, \
217+
#define READ_BUTTON(off, flag, button) \
218+
SDL_SendJoystickButton( \
219+
timestamp, \
220+
joystick, \
221+
button, \
235222
((packet[off] & flag) != 0));
236-
READ_BUTTON(1, 0x02, 0) // A
237-
READ_BUTTON(1, 0x04, 1) // B
238-
READ_BUTTON(1, 0x08, 3) // Y
239-
READ_BUTTON(1, 0x01, 2) // X
240-
READ_BUTTON(2, 0x80, 4) // DPAD_LEFT
241-
READ_BUTTON(2, 0x20, 5) // DPAD_RIGHT
242-
READ_BUTTON(2, 0x40, 6) // DPAD_DOWN
243-
READ_BUTTON(2, 0x10, 7) // DPAD_UP
244-
READ_BUTTON(2, 0x02, 8) // START
245-
READ_BUTTON(1, 0x80, 9) // RIGHTSHOULDER
223+
READ_BUTTON(0, 0x02, 0) // A
224+
READ_BUTTON(0, 0x04, 1) // B
225+
READ_BUTTON(0, 0x08, 3) // Y
226+
READ_BUTTON(0, 0x01, 2) // X
227+
READ_BUTTON(1, 0x80, 4) // DPAD_LEFT
228+
READ_BUTTON(1, 0x20, 5) // DPAD_RIGHT
229+
READ_BUTTON(1, 0x40, 6) // DPAD_DOWN
230+
READ_BUTTON(1, 0x10, 7) // DPAD_UP
231+
READ_BUTTON(1, 0x02, 8) // START
232+
READ_BUTTON(0, 0x80, 9) // RIGHTSHOULDER
246233
/* These two buttons are for the bottoms of the analog triggers.
247234
* More than likely, you're going to want to read the axes instead!
248235
* -flibit
249236
*/
250-
READ_BUTTON(1, 0x20, 10) // TRIGGERRIGHT
251-
READ_BUTTON(1, 0x10, 11) // TRIGGERLEFT
237+
READ_BUTTON(0, 0x20, 10) // TRIGGERRIGHT
238+
READ_BUTTON(0, 0x10, 11) // TRIGGERLEFT
252239
#undef READ_BUTTON
253240

254-
#define READ_AXIS(off, axis, invert) \
255-
v = invert ? (0xff - packet[off]) : packet[off]; \
256-
if (v < ctx->min_axis[i * SDL_GAMEPAD_AXIS_COUNT + axis]) \
257-
ctx->min_axis[i * SDL_GAMEPAD_AXIS_COUNT + axis] = v; \
258-
if (v > ctx->max_axis[i * SDL_GAMEPAD_AXIS_COUNT + axis]) \
259-
ctx->max_axis[i * SDL_GAMEPAD_AXIS_COUNT + axis] = v; \
241+
#define READ_AXIS(off, axis, invert) \
242+
v = (invert) ? (0xff - packet[off]) : packet[off]; \
243+
if (v < ctx->min_axis[i * SDL_GAMEPAD_AXIS_COUNT + axis]) \
244+
ctx->min_axis[i * SDL_GAMEPAD_AXIS_COUNT + axis] = v; \
245+
if (v > ctx->max_axis[i * SDL_GAMEPAD_AXIS_COUNT + axis]) \
246+
ctx->max_axis[i * SDL_GAMEPAD_AXIS_COUNT + axis] = v; \
260247
axis_value = (Sint16)HIDAPI_RemapVal(v, ctx->min_axis[i * SDL_GAMEPAD_AXIS_COUNT + axis], ctx->max_axis[i * SDL_GAMEPAD_AXIS_COUNT + axis], SDL_MIN_SINT16, SDL_MAX_SINT16); \
261-
SDL_SendJoystickAxis( \
262-
timestamp, \
263-
joystick, \
248+
SDL_SendJoystickAxis( \
249+
timestamp, \
250+
joystick, \
264251
axis, axis_value);
265-
READ_AXIS(3, SDL_GAMEPAD_AXIS_LEFTX, 0)
266-
READ_AXIS(4, SDL_GAMEPAD_AXIS_LEFTY, 1)
267-
READ_AXIS(6, SDL_GAMEPAD_AXIS_RIGHTX, 0)
268-
READ_AXIS(5, SDL_GAMEPAD_AXIS_RIGHTY, 1)
269-
READ_AXIS(7, SDL_GAMEPAD_AXIS_LEFT_TRIGGER, 0)
270-
READ_AXIS(8, SDL_GAMEPAD_AXIS_RIGHT_TRIGGER, 0)
252+
READ_AXIS(2, SDL_GAMEPAD_AXIS_LEFTX, 0)
253+
READ_AXIS(3, SDL_GAMEPAD_AXIS_LEFTY, 1)
254+
READ_AXIS(5, SDL_GAMEPAD_AXIS_RIGHTX, invert_c_stick ? 1 : 0)
255+
READ_AXIS(4, SDL_GAMEPAD_AXIS_RIGHTY, invert_c_stick ? 0 : 1)
256+
READ_AXIS(6, SDL_GAMEPAD_AXIS_LEFT_TRIGGER, 0)
257+
READ_AXIS(7, SDL_GAMEPAD_AXIS_RIGHT_TRIGGER, 0)
271258
#undef READ_AXIS
272259
}
273260

@@ -366,7 +353,18 @@ static bool HIDAPI_DriverGameCube_UpdateDevice(SDL_HIDAPI_Device *device)
366353
HIDAPI_DumpPacket("Nintendo GameCube packet: size = %d", packet, size);
367354
#endif
368355
if (ctx->pc_mode) {
369-
HIDAPI_DriverGameCube_HandleJoystickPacket(device, ctx, packet, size);
356+
if (size == 10) {
357+
// This is the older firmware
358+
// The first byte is the index of the connected controller
359+
// The C stick has an inverted value range compared to the left stick
360+
HIDAPI_DriverGameCube_HandleJoystickPacket(device, ctx, &packet[1], true);
361+
} else if (size == 9) {
362+
// This is the newer firmware (version 0x7)
363+
// The C stick has the same value range compared to the left stick
364+
HIDAPI_DriverGameCube_HandleJoystickPacket(device, ctx, packet, false);
365+
} else {
366+
// How do we handle this packet?
367+
}
370368
} else {
371369
HIDAPI_DriverGameCube_HandleNintendoPacket(device, ctx, packet, size);
372370
}

0 commit comments

Comments
 (0)