diff --git a/port/src/config.c b/port/src/config.c index c1f6d64d0..5d91c08b1 100644 --- a/port/src/config.c +++ b/port/src/config.c @@ -44,6 +44,8 @@ struct configentry { { "Input.RStickDeadzone", CONFIG_S32, { .s32val = 4096 } }, { "Input.SwapSticks", CONFIG_S32, { .s32val = 1 } }, { "Input.RumbleScale", CONFIG_F32, { .f32val = 0.333f } }, + { "Input.FirstGamepadNum", CONFIG_S32, { .s32val = 0 } }, + { "Input.FakeGamepads", CONFIG_S32, { .s32val = 0 } }, /* Game */ { "Game.BaseDir", CONFIG_STR, { .strval = "./data" } }, { "Game.MemorySize", CONFIG_S32, { .s32val = 16 } }, diff --git a/port/src/input.c b/port/src/input.c index 112dae8bf..ec038d4e8 100644 --- a/port/src/input.c +++ b/port/src/input.c @@ -137,16 +137,18 @@ static int inputEventFilter(void *data, SDL_Event *event) s32 inputInit(void) { if (!SDL_WasInit(SDL_INIT_GAMECONTROLLER)) { - if (SDL_InitSubSystem(SDL_INIT_GAMECONTROLLER) != 0) { - return -1; - } + SDL_InitSubSystem(SDL_INIT_GAMECONTROLLER); } const s32 numJoys = SDL_NumJoysticks(); s32 ret = 1; // always report first controller as connected - for (s32 jidx = 0, cidx = 0; jidx < numJoys && cidx < INPUT_MAX_CONTROLLERS; ++jidx) { + // if this is set to 1, keyboard will count as a separate controller on its own, + // so the first connected gamepad will go to player 2 instead of player 1 + const s32 cstart = configGetInt("Input.FirstGamepadNum", 0); + + for (s32 jidx = 0, cidx = cstart; jidx < numJoys && cidx < INPUT_MAX_CONTROLLERS; ++jidx) { if (SDL_IsGameController(jidx)) { pads[cidx] = SDL_GameControllerOpen(jidx); if (pads[cidx]) { @@ -179,6 +181,11 @@ s32 inputInit(void) axisMap[1][1] = SDL_CONTROLLER_AXIS_LEFTY; } + const s32 overrideMask = (1 << configGetInt("Input.FakeGamepads", 0)) - 1; + if (overrideMask) { + ret = overrideMask; + } + connectedMask = ret; return ret; @@ -288,7 +295,7 @@ s32 inputControllerConnected(s32 idx) if (idx < 0 || idx >= INPUT_MAX_CONTROLLERS) { return 0; } - return !idx || !!pads[idx]; // always report first controller as connected + return pads[idx] || (connectedMask & (1 << idx)); } s32 inputRumbleSupported(s32 idx)