diff --git a/decompiler/config/all-types.gc b/decompiler/config/all-types.gc index bd7313a585..ec87b74519 100644 --- a/decompiler/config/all-types.gc +++ b/decompiler/config/all-types.gc @@ -4223,13 +4223,13 @@ (deftype cpad-list (basic) ((num-cpads int32 :offset-assert 4) - (cpads cpad-info 2 :offset-assert 8) ;; guess + (cpads cpad-info 4 :offset-assert 8) ;; guess, modified from 2->4 for PC 4-pad support ) (:methods (new (symbol type) _type_ 0)) :method-count-assert 9 - :size-assert #x10 - :flag-assert #x900000010 + :size-assert #x18 + :flag-assert #x900000018 ) ;; - Functions diff --git a/game/system/newpad.cpp b/game/system/newpad.cpp index a7ecc31ff4..7931b15624 100644 --- a/game/system/newpad.cpp +++ b/game/system/newpad.cpp @@ -32,7 +32,8 @@ bool g_gamepad_buttons[CONTROLLER_COUNT][(int)Button::Max] = {{0}}; float g_gamepad_analogs[CONTROLLER_COUNT][(int)Analog::Max] = {{0}}; struct GamepadState { - int gamepad_idx[CONTROLLER_COUNT] = {-1, -1}; + int gamepad_idx[CONTROLLER_COUNT] = {-1, -1, -1, -1}; + bool glfw_joystick_used[GLFW_JOYSTICK_LAST + 1] = {false}; } g_gamepads; // input mode for controller mapping @@ -275,25 +276,29 @@ void check_gamepads() { auto check_pad = [](int pad) { // -> bool if (g_gamepads.gamepad_idx[pad] == -1) { for (int i = GLFW_JOYSTICK_1; i <= GLFW_JOYSTICK_LAST; i++) { - if (pad == 1 && i == g_gamepads.gamepad_idx[0]) + if (g_gamepads.glfw_joystick_used[i]) { continue; + } if (glfwJoystickPresent(i) && glfwJoystickIsGamepad(i)) { g_gamepads.gamepad_idx[pad] = i; - lg::info("Using joystick {}: {}, {}", i, glfwGetJoystickName(i), glfwGetGamepadName(i)); + g_gamepads.glfw_joystick_used[i] = true; + lg::info("Using joystick {} for pad {}: {}, {}", i, pad, glfwGetJoystickName(i), + glfwGetGamepadName(i)); break; } } } else if (!glfwJoystickPresent(g_gamepads.gamepad_idx[pad])) { - lg::info("Pad {} has been disconnected", pad); + lg::info("Pad {} / joystick {} has been disconnected", pad, g_gamepads.gamepad_idx[pad]); + g_gamepads.glfw_joystick_used[g_gamepads.gamepad_idx[pad]] = false; g_gamepads.gamepad_idx[pad] = -1; return false; } return true; // pad already exists or was created }; - if (check_pad(0)) - check_pad(1); - else - g_gamepads.gamepad_idx[1] = -1; + + for (int i = 0; i < CONTROLLER_COUNT; i++) { + check_pad(i); + } } void initialize() { @@ -318,12 +323,6 @@ void clear_pad(int pad) { void update_gamepads() { check_gamepads(); - if (g_gamepads.gamepad_idx[0] == -1) { - clear_pad(0); - clear_pad(1); - return; - } - constexpr std::pair gamepad_map[] = { {Button::Select, GLFW_GAMEPAD_BUTTON_BACK}, {Button::L3, GLFW_GAMEPAD_BUTTON_LEFT_THUMB}, @@ -362,12 +361,12 @@ void update_gamepads() { } }; - read_pad_state(0); - - if (g_gamepads.gamepad_idx[1] != -1) - read_pad_state(1); - else - clear_pad(1); + for (int i = 0; i < CONTROLLER_COUNT; i++) { + if (g_gamepads.gamepad_idx[i] != -1) + read_pad_state(i); + else + clear_pad(i); + } } int rumble(int pad, float slow_motor, float fast_motor) { diff --git a/game/system/newpad.h b/game/system/newpad.h index 378edd8208..0d5d994e54 100644 --- a/game/system/newpad.h +++ b/game/system/newpad.h @@ -19,7 +19,7 @@ namespace Pad { -static constexpr int CONTROLLER_COUNT = 2; // support 2 controllers. +static constexpr int CONTROLLER_COUNT = 4; // support 4 controllers. enum class Analog { Left_X = 0, diff --git a/goal_src/jak1/engine/ps2/pad.gc b/goal_src/jak1/engine/ps2/pad.gc index 90032db363..07f0ff8453 100644 --- a/goal_src/jak1/engine/ps2/pad.gc +++ b/goal_src/jak1/engine/ps2/pad.gc @@ -147,27 +147,29 @@ ) ) -;; List of controllers. It always has 2 controllers. +;; List of controllers. It always has 4 controllers. (deftype cpad-list (basic) ((num-cpads int32 :offset-assert 4) - (cpads cpad-info 2 :offset-assert 8) + (cpads cpad-info 4 :offset-assert 8) ;; modified from 2->4 for PC 4-pad support ) (:methods (new (symbol type) _type_ 0) ) :method-count-assert 9 - :size-assert #x10 - :flag-assert #x900000010 + :size-assert #x18 + :flag-assert #x900000018 ) (defmethod new cpad-list ((allocation symbol) (type-to-make type)) - "Create a cpad-list for 2 controllers. It's fine to do this even if one or both controllers + "Create a cpad-list for 4 controllers. It's fine to do this even if controllers aren't connected yet. " (let ((gp-0 (object-new allocation type-to-make (the-as int (-> type-to-make size))))) - (set! (-> gp-0 num-cpads) 2) + (set! (-> gp-0 num-cpads) 4) (set! (-> gp-0 cpads 0) (new 'global 'cpad-info 0)) (set! (-> gp-0 cpads 1) (new 'global 'cpad-info 1)) + (set! (-> gp-0 cpads 2) (new 'global 'cpad-info 2)) + (set! (-> gp-0 cpads 3) (new 'global 'cpad-info 3)) gp-0 ) ) @@ -261,10 +263,10 @@ (none) ) -;; the two controllers +;; the four controllers (define *cpad-list* (new 'global 'cpad-list)) -;; weird leftover debug thing, enabling overrides the x position of both sticks on both controllers. +;; weird leftover debug thing, enabling overrides the x position of both sticks on all controllers. (define *cpad-debug* #f) (#if PC_PORT