From 18c15cc700ab534d89fa117a7c74d0da1cd5f217 Mon Sep 17 00:00:00 2001 From: UnknownShadow200 Date: Sat, 2 Sep 2023 17:46:16 +1000 Subject: [PATCH] Webclient: Support joysticks and ZL/ZR buttons for gamepad --- src/Menus.c | 3 +-- src/Program.c | 4 +-- src/Window_Web.c | 69 ++++++++++++++++++++++++++++++++++++------------ 3 files changed, 55 insertions(+), 21 deletions(-) diff --git a/src/Menus.c b/src/Menus.c index e0ee1965c..48a93666d 100644 --- a/src/Menus.c +++ b/src/Menus.c @@ -1813,9 +1813,8 @@ void LoadLevelScreen_Show(void) { } - /*########################################################################################################################* -*----------------------------------------------------EditHotkeyScreen-----------------------------------------------------* +*----------------------------------------------------BindSourcesScreen----------------------------------------------------* *#########################################################################################################################*/ static struct BindsSourceScreen { Screen_Body diff --git a/src/Program.c b/src/Program.c index 96e7b55f6..e16043dbb 100644 --- a/src/Program.c +++ b/src/Program.c @@ -77,8 +77,8 @@ static int RunProgram(int argc, char** argv) { #ifdef _MSC_VER /* NOTE: Make sure to comment this out before pushing a commit */ //cc_string rawArgs = String_FromConst("UnknownShadow200 fffff 127.0.0.1 25565"); - cc_string rawArgs = String_FromConst("UnknownShadow200"); - argsCount = String_UNSAFE_Split(&rawArgs, ' ', args, 4); + //cc_string rawArgs = String_FromConst("UnknownShadow200"); + //argsCount = String_UNSAFE_Split(&rawArgs, ' ', args, 4); #endif if (argsCount == 0) { diff --git a/src/Window_Web.c b/src/Window_Web.c index 237c2baa8..1aadbfe7f 100644 --- a/src/Window_Web.c +++ b/src/Window_Web.c @@ -525,27 +525,62 @@ static void ProcessPendingResize(void) { UpdateWindowBounds(); } -#define GetGamePadButton(i) i < numButtons ? ev->digitalButton[i] : 0 -static void ProcessGamePadInput(EmscriptenGamepadEvent* ev) { +/* https://www.w3.org/TR/gamepad/#dfn-standard-gamepad */ +#define GetGamepadButton(i) i < numButtons ? ev->digitalButton[i] : 0 +static void ProcessGamepadButtons(EmscriptenGamepadEvent* ev) { int numButtons = ev->numButtons; - Input.Sources |= INPUT_SOURCE_GAMEPAD; - /* https://www.w3.org/TR/gamepad/#dfn-standard-gamepad */ - Input_SetNonRepeatable(CCPAD_A, GetGamePadButton(0)); - Input_SetNonRepeatable(CCPAD_B, GetGamePadButton(1)); - Input_SetNonRepeatable(CCPAD_X, GetGamePadButton(2)); - Input_SetNonRepeatable(CCPAD_Y, GetGamePadButton(3)); + Input_SetNonRepeatable(CCPAD_A, GetGamepadButton(0)); + Input_SetNonRepeatable(CCPAD_B, GetGamepadButton(1)); + Input_SetNonRepeatable(CCPAD_X, GetGamepadButton(2)); + Input_SetNonRepeatable(CCPAD_Y, GetGamepadButton(3)); - Input_SetNonRepeatable(CCPAD_L, GetGamePadButton(4)); - Input_SetNonRepeatable(CCPAD_R, GetGamePadButton(5)); + Input_SetNonRepeatable(CCPAD_L, GetGamepadButton(4)); + Input_SetNonRepeatable(CCPAD_R, GetGamepadButton(5)); + Input_SetNonRepeatable(CCPAD_ZL, GetGamepadButton(6)); + Input_SetNonRepeatable(CCPAD_ZR, GetGamepadButton(7)); - Input_SetNonRepeatable(CCPAD_SELECT, GetGamePadButton(8)); - Input_SetNonRepeatable(CCPAD_START, GetGamePadButton(9)); + Input_SetNonRepeatable(CCPAD_SELECT, GetGamepadButton(8)); + Input_SetNonRepeatable(CCPAD_START, GetGamepadButton(9)); - Input_SetNonRepeatable(CCPAD_UP, GetGamePadButton(12)); - Input_SetNonRepeatable(CCPAD_DOWN, GetGamePadButton(13)); - Input_SetNonRepeatable(CCPAD_LEFT, GetGamePadButton(14)); - Input_SetNonRepeatable(CCPAD_RIGHT, GetGamePadButton(15)); + Input_SetNonRepeatable(CCPAD_UP, GetGamepadButton(12)); + Input_SetNonRepeatable(CCPAD_DOWN, GetGamepadButton(13)); + Input_SetNonRepeatable(CCPAD_LEFT, GetGamepadButton(14)); + Input_SetNonRepeatable(CCPAD_RIGHT, GetGamepadButton(15)); +} + +static void ProcessGamepadCamera(float x, float y, double delta) { + float scale = (delta * 60.0) * 8.0f; + + /* Deadzone adjustment */ + if (x >= -0.1 && x <= 0.1) x = 0; + if (y >= -0.1 && y <= 0.1) y = 0; + if (x == 0 && y == 0) return; + + Event_RaiseRawMove(&PointerEvents.RawMoved, x * scale, y * scale); +} + +static void ProcessGamepadMovement(float x, float y) { + /* Deadzone adjustment */ + if (x >= -0.1 && x <= 0.1) x = 0; + if (y >= -0.1 && y <= 0.1) y = 0; + if (x == 0 && y == 0) return; + + Input.JoystickMovement = true; + Input.JoystickAngle = Math_Atan2(x, y); +} + +static void ProcessGamepadInput(EmscriptenGamepadEvent* ev, double delta) { + Input.Sources |= INPUT_SOURCE_GAMEPAD; + Input.JoystickMovement = false; + ProcessGamepadButtons(ev); + + if (ev->numAxes >= 4) { + ProcessGamepadMovement(ev->axis[0], ev->axis[1]); + ProcessGamepadCamera( ev->axis[2], ev->axis[3], delta); + } else if (ev->numAxes >= 2) { + ProcessGamepadCamera(ev->axis[0], ev->axis[1], delta); + } } void Window_ProcessEvents(double delta) { @@ -559,7 +594,7 @@ void Window_ProcessEvents(double delta) { { EmscriptenGamepadEvent ev; res = emscripten_get_gamepad_status(i, &ev); - if (res == 0) ProcessGamePadInput(&ev); + if (res == 0) ProcessGamepadInput(&ev, delta); } }