diff --git a/source/build/include/baselayer.h b/source/build/include/baselayer.h index ac56fb730..2d0da3fbd 100644 --- a/source/build/include/baselayer.h +++ b/source/build/include/baselayer.h @@ -230,6 +230,7 @@ void mouseSetCallback(void (*callback)(int32_t,int32_t)); void joySetCallback(void (*callback)(int32_t,int32_t)); const char *keyGetName(int32_t num); const char *joyGetName(int32_t what, int32_t num); // what: 0=axis, 1=button, 2=hat +void joyScanDevices(void); char keyGetScan(void); char keyGetChar(void); diff --git a/source/build/src/sdlayer.cpp b/source/build/src/sdlayer.cpp index ace92afef..47c09c113 100644 --- a/source/build/src/sdlayer.cpp +++ b/source/build/src/sdlayer.cpp @@ -825,6 +825,103 @@ static void LoadSDLControllerDB() } #endif +void joyScanDevices() +{ + inputdevices &= ~4; + + if (controller) + { + SDL_GameControllerClose(controller); + controller = nullptr; + } + if (joydev) + { + SDL_JoystickClose(joydev); + joydev = nullptr; + } + + int numjoysticks = SDL_NumJoysticks(); + if (numjoysticks < 1) + { + buildputs("No game controllers found\n"); + } + else + { + buildputs("Game controllers:\n"); + for (int i = 0; i < numjoysticks; i++) + { + const char * name; +#if SDL_MAJOR_VERSION >= 2 + if (SDL_IsGameController(i)) + name = SDL_GameControllerNameForIndex(i); + else +#endif + name = SDL_JoystickNameForIndex(i); + + buildprintf(" %d. %s\n", i+1, name); + } + +#if SDL_MAJOR_VERSION >= 2 + for (int i = 0; i < numjoysticks; i++) + { + if ((controller = SDL_GameControllerOpen(i))) + { + buildprintf("Using controller %s\n", SDL_GameControllerName(controller)); + + joystick.numAxes = SDL_CONTROLLER_AXIS_MAX; + joystick.numButtons = SDL_CONTROLLER_BUTTON_MAX; + joystick.numHats = 0; + joystick.isGameController = 1; + + Xfree(joystick.pAxis); + joystick.pAxis = (int32_t *)Xcalloc(joystick.numAxes, sizeof(int32_t)); + Xfree(joystick.pHat); + joystick.pHat = nullptr; + + inputdevices |= 4; + + return; + } + } +#endif + + for (int i = 0; i < numjoysticks; i++) + { + if ((joydev = SDL_JoystickOpen(i))) + { + buildprintf("Using joystick %s\n", SDL_JoystickName(joydev)); + + // KEEPINSYNC duke3d/src/gamedefs.h, mact/include/_control.h + joystick.numAxes = min(9, SDL_JoystickNumAxes(joydev)); + joystick.numButtons = min(32, SDL_JoystickNumButtons(joydev)); + joystick.numHats = min((36-joystick.numButtons)/4,SDL_JoystickNumHats(joydev)); + joystick.isGameController = 0; + + initprintf("Joystick %d has %d axes, %d buttons, and %d hat(s).\n", i+1, joystick.numAxes, joystick.numButtons, joystick.numHats); + + Xfree(joystick.pAxis); + joystick.pAxis = (int32_t *)Xcalloc(joystick.numAxes, sizeof(int32_t)); + + Xfree(joystick.pHat); + if (joystick.numHats) + joystick.pHat = (int32_t *)Xcalloc(joystick.numHats, sizeof(int32_t)); + else + joystick.pHat = nullptr; + + for (int j = 0; j < joystick.numHats; j++) + joystick.pHat[j] = -1; // center + + SDL_JoystickEventState(SDL_ENABLE); + inputdevices |= 4; + + return; + } + } + + buildputs("No controllers are usable\n"); + } +} + // // initinput() -- init input system // @@ -878,76 +975,7 @@ int32_t initinput(void) LoadSDLControllerDB(); #endif - int numjoysticks = SDL_NumJoysticks(); - if (numjoysticks < 1) - { - buildputs("No game controllers found\n"); - } - else - { - buildputs("Game controllers:\n"); - for (i = 0; i < numjoysticks; i++) - { - const char * name; -#if SDL_MAJOR_VERSION >= 2 - if (SDL_IsGameController(i)) - name = SDL_GameControllerNameForIndex(i); - else -#endif - name = SDL_JoystickNameForIndex(i); - - buildprintf(" %d. %s\n", i+1, name); - } - -#if SDL_MAJOR_VERSION >= 2 - for (i = 0; i < numjoysticks; i++) - { - if ((controller = SDL_GameControllerOpen(i))) - { - buildprintf("Using controller %s\n", SDL_GameControllerName(controller)); - - inputdevices |= 4; - - joystick.numAxes = SDL_CONTROLLER_AXIS_MAX; - joystick.numButtons = SDL_CONTROLLER_BUTTON_MAX; - joystick.numHats = 0; - joystick.isGameController = 1; - - joystick.pAxis = (int32_t *)Xcalloc(joystick.numAxes, sizeof(int32_t)); - - return 0; - } - } -#endif - - for (i = 0; i < numjoysticks; i++) - { - if ((joydev = SDL_JoystickOpen(i))) - { - buildprintf("Using joystick %s\n", SDL_JoystickName(joydev)); - - SDL_JoystickEventState(SDL_ENABLE); - inputdevices |= 4; - - // KEEPINSYNC duke3d/src/gamedefs.h, mact/include/_control.h - joystick.numAxes = min(9, SDL_JoystickNumAxes(joydev)); - joystick.numButtons = min(32, SDL_JoystickNumButtons(joydev)); - joystick.numHats = min((36-joystick.numButtons)/4,SDL_JoystickNumHats(joydev)); - initprintf("Joystick %d has %d axes, %d buttons, and %d hat(s).\n", i+1, joystick.numAxes, joystick.numButtons, joystick.numHats); - - joystick.pAxis = (int32_t *)Xcalloc(joystick.numAxes, sizeof(int32_t)); - - if (joystick.numHats) - joystick.pHat = (int32_t *)Xcalloc(joystick.numHats, sizeof(int32_t)); - - for (i = 0; i < joystick.numHats; i++) joystick.pHat[i] = -1; // centre - - return 0; - } - } - - buildputs("No controllers are usable\n"); - } + joyScanDevices(); } return 0; diff --git a/source/build/src/winlayer.cpp b/source/build/src/winlayer.cpp index d2763ab5a..074e66061 100644 --- a/source/build/src/winlayer.cpp +++ b/source/build/src/winlayer.cpp @@ -1150,6 +1150,10 @@ const char *joyGetName(int32_t what, int32_t num) } } +void joyScanDevices() +{ +} + // // AcquireInputDevices() -- (un)acquires the input devices // diff --git a/source/duke3d/src/menus.cpp b/source/duke3d/src/menus.cpp index c7b65a6ab..f349b9c86 100644 --- a/source/duke3d/src/menus.cpp +++ b/source/duke3d/src/menus.cpp @@ -3380,7 +3380,11 @@ static int32_t Menu_EntryOptionModify(MenuEntry_t *entry, int32_t newOption) else if (entry == &ME_MOUSESETUP_SMOOTH) CONTROL_SmoothMouse = ud.config.SmoothInput; else if (entry == &ME_JOYSTICK_ENABLE) + { + if (newOption) + CONTROL_ScanForControllers(); CONTROL_JoystickEnabled = (newOption && CONTROL_JoyPresent); + } else if (entry == &ME_JOYSTICKAXIS_ANALOG) CONTROL_MapAnalogAxis(M_JOYSTICKAXES.currentEntry, newOption, controldevice_joystick); else if (entry == &ME_NETOPTIONS_EPISODE) diff --git a/source/mact/include/control.h b/source/mact/include/control.h index c13e2673f..d404467b4 100644 --- a/source/mact/include/control.h +++ b/source/mact/include/control.h @@ -198,6 +198,8 @@ void CONTROL_MapAnalogAxis(int whichaxis, int whichanalog, controldevice device) void CONTROL_MapDigitalAxis(int32_t whichaxis, int32_t whichfunction, int32_t direction, controldevice device); void CONTROL_SetAnalogAxisScale(int32_t whichaxis, int32_t axisscale, controldevice device); +void CONTROL_ScanForControllers(void); + int32_t CONTROL_GetGameControllerDigitalAxisPos(int32_t axis); int32_t CONTROL_GetGameControllerDigitalAxisNeg(int32_t axis); void CONTROL_ClearGameControllerDigitalAxisPos(int32_t axis); diff --git a/source/mact/src/control.cpp b/source/mact/src/control.cpp index 679c476c4..cd79f6d4c 100644 --- a/source/mact/src/control.cpp +++ b/source/mact/src/control.cpp @@ -842,6 +842,19 @@ void CONTROL_GetInput(ControlInfo *info) inputchecked = 1; } +static void CONTROL_ResetJoystickValues() +{ + CONTROL_NumJoyAxes = min(MAXJOYAXES, joystick.numAxes); + CONTROL_NumJoyButtons = min(MAXJOYBUTTONS, joystick.numButtons + 4 * (joystick.numHats > 0)); + CONTROL_JoystickEnabled = CONTROL_JoyPresent = !!((inputdevices & 4) >> 2); +} + +void CONTROL_ScanForControllers() +{ + joyScanDevices(); + CONTROL_ResetJoystickValues(); +} + bool CONTROL_Startup(controltype which, int32_t(*TimeFunction)(void), int32_t ticspersecond) { UNREFERENCED_PARAMETER(which); @@ -866,9 +879,7 @@ bool CONTROL_Startup(controltype which, int32_t(*TimeFunction)(void), int32_t ti CONTROL_MousePresent = Mouse_Init(); CONTROL_MouseEnabled = CONTROL_MousePresent; - CONTROL_NumJoyAxes = min(MAXJOYAXES, joystick.numAxes); - CONTROL_NumJoyButtons = min(MAXJOYBUTTONS, joystick.numButtons + 4 * (joystick.numHats > 0)); - CONTROL_JoystickEnabled = CONTROL_JoyPresent = !!((inputdevices & 4) >> 2); + CONTROL_ResetJoystickValues(); #ifdef GEKKO if (CONTROL_MousePresent)