From b906f77b370430d9742c4cbab9eda035c382031e Mon Sep 17 00:00:00 2001 From: fgsfds Date: Fri, 18 Aug 2023 12:26:55 +0200 Subject: [PATCH] port: added rumble scale and support for 2 extra buttons also fixed some warnings --- include/PR/os_cont.h | 4 ++ port/fast3d/gfx_api.h | 3 ++ port/include/input.h | 27 +++++++------- port/include/video.h | 4 +- port/src/config.c | 1 + port/src/input.c | 86 ++++++++++++++++++++++++++++--------------- port/src/libultra.c | 2 +- port/src/video.c | 12 +++++- src/game/bondmove.c | 2 +- 9 files changed, 95 insertions(+), 46 deletions(-) diff --git a/include/PR/os_cont.h b/include/PR/os_cont.h index 15ee60f3f..8f3029b40 100644 --- a/include/PR/os_cont.h +++ b/include/PR/os_cont.h @@ -127,6 +127,8 @@ typedef struct { #define CONT_DOWN 0x0400 #define CONT_LEFT 0x0200 #define CONT_RIGHT 0x0100 +#define CONT_EXTRA1 0x0080 +#define CONT_EXTRA0 0x0040 #define CONT_L 0x0020 #define CONT_R 0x0010 #define CONT_E 0x0008 @@ -150,6 +152,8 @@ typedef struct { #define L_CBUTTONS CONT_C #define R_CBUTTONS CONT_F #define D_CBUTTONS CONT_D +#define X_BUTTON CONT_EXTRA0 +#define Y_BUTTON CONT_EXTRA1 /* Controller error number */ diff --git a/port/fast3d/gfx_api.h b/port/fast3d/gfx_api.h index fdb5035ce..9c2151a11 100644 --- a/port/fast3d/gfx_api.h +++ b/port/fast3d/gfx_api.h @@ -6,6 +6,9 @@ #include #endif +#include "gfx_rendering_api.h" +#include "gfx_window_manager_api.h" + struct XYWidthHeight { int16_t x, y; uint32_t width, height; diff --git a/port/include/input.h b/port/include/input.h index 6f0a5efe4..7080fb97a 100644 --- a/port/include/input.h +++ b/port/include/input.h @@ -6,7 +6,6 @@ #define INPUT_MAX_CONTROLLERS MAXCONTROLLERS #define INPUT_MAX_CONTROLLER_BUTTONS 32 -#define INPUT_RUMBLE_STRENGTH 0.333f #define CONT_STICK_XNEG 0x10000 #define CONT_STICK_XPOS 0x20000 @@ -50,8 +49,8 @@ enum contkey { CK_C_U, CK_RTRIG, CK_LTRIG, - CK_EXTRA0, // gap in CONT_ - CK_EXTRA1, // gap in CONT_ + CK_X, // gap in CONT_ + CK_Y, // gap in CONT_ CK_DPAD_R, CK_DPAD_L, CK_DPAD_D, @@ -85,11 +84,14 @@ s32 inputControllerMask(void); // vk is a value from the virtkey enum above s32 inputKeyPressed(u32 vk); -// bind virtkey vk to n64 pad #idx's button/axis nbtn as represented by its contkey value -// if bind is -1, picks a bind slot automatically -void inputKeyBind(s32 idx, u32 cbtn, s32 bind, u32 vk); +// idx is controller index, contbtn is one of the CONT_ constants +s32 inputButtonPressed(s32 idx, u16 contbtn); -// 0 strength turns it off +// bind virtkey vk to n64 pad #idx's button/axis ck as represented by its contkey value +// if bind is -1, picks a bind slot automatically +void inputKeyBind(s32 idx, u32 ck, s32 bind, u32 vk); + +// strength is 0 .. 1; 0 strength turns it off void inputRumble(s32 idx, f32 strength, f32 time); // locks the mouse cursor in the window and makes it invisible if argument is true @@ -98,15 +100,14 @@ void inputLockMouse(s32 lock); // returns the current state of the above s32 inputMouseIsLocked(void); -// returns mouse position in window +// returns mouse position in native viewport coordinates (ie, 320x240 most of the time) void inputMouseGetPosition(s32 *x, s32 *y); -// returns changes in mouse position since last frame -void inputMouseGetDelta(s32 *dx, s32 *dy); - -// returns changes in mouse position since last frame, in normalized window coordinates scaled by sensitivity -void inputMouseGetNormalizedDelta(f32 *dx, f32 *dy); +// returns changes in mouse position since last frame, in window coordinates +void inputMouseGetRawDelta(s32 *dx, s32 *dy); +// returns changes in mouse position since last frame, scaled by sensitivity +void inputMouseGetScaledDelta(f32 *dx, f32 *dy); // call this every frame void inputUpdate(void); diff --git a/port/include/video.h b/port/include/video.h index 730605909..f5bb2b52e 100644 --- a/port/include/video.h +++ b/port/include/video.h @@ -12,7 +12,9 @@ void videoEndFrame(void); void *videoGetWindowHandle(void); -void videoUpdateNativeResolution(const int w, const int h); +void videoUpdateNativeResolution(s32 w, s32 h); +s32 videoGetNativeWidth(void); +s32 videoGetNativeHeight(void); s32 videoGetWidth(void); s32 videoGetHeight(void); diff --git a/port/src/config.c b/port/src/config.c index 4ba500ea9..0404ddbb6 100644 --- a/port/src/config.c +++ b/port/src/config.c @@ -42,6 +42,7 @@ struct configentry { { "Input.LStickDeadzone", CONFIG_S32, { .s32val = 4096 } }, { "Input.RStickDeadzone", CONFIG_S32, { .s32val = 4096 } }, { "Input.SwapSticks", CONFIG_S32, { .s32val = 1 } }, + { "Input.RumbleScale", CONFIG_F32, { .f32val = 0.333f } }, /* 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 8835f586e..a533233c0 100644 --- a/port/src/input.c +++ b/port/src/input.c @@ -11,7 +11,6 @@ #define DEFAULT_DEADZONE 4096 static SDL_GameController *pads[INPUT_MAX_CONTROLLERS]; -static SDL_Haptic *haptics[INPUT_MAX_CONTROLLERS]; static u32 binds[MAXCONTROLLERS][CK_TOTAL_COUNT][MAX_BINDS]; // [i][CK_][b] = [VK_] static s32 connectedMask = 0; @@ -25,6 +24,8 @@ static u32 mouseButtons; static f32 mouseSensX = 1.5f; static f32 mouseSensY = 1.5f; +static f32 rumbleScale = 0.333f; + // NOTE: by default this gets inverted for 1.2 static u32 axisMap[2][2] = { { SDL_CONTROLLER_AXIS_LEFTX, SDL_CONTROLLER_AXIS_LEFTY }, @@ -33,11 +34,14 @@ static u32 axisMap[2][2] = { static u32 deadzone[2] = { DEFAULT_DEADZONE, DEFAULT_DEADZONE }; -void inputSetDefaultKeyBinds(void) { +void inputSetDefaultKeyBinds(void) +{ // TODO: make VK constants for all these static const u32 kbbinds[][3] = { { CK_A, SDL_SCANCODE_Q, 0 }, { CK_B, SDL_SCANCODE_E, 0 }, + { CK_X, SDL_SCANCODE_TAB, 0 }, + { CK_Y, SDL_SCANCODE_R, 0 }, { CK_RTRIG, VK_MOUSE_RIGHT, SDL_SCANCODE_Z }, { CK_LTRIG, VK_MOUSE_X1, SDL_SCANCODE_X }, { CK_ZTRIG, VK_MOUSE_LEFT, SDL_SCANCODE_SPACE }, @@ -55,6 +59,8 @@ void inputSetDefaultKeyBinds(void) { static const u32 joybinds[][2] = { { CK_A, SDL_CONTROLLER_BUTTON_A }, { CK_B, SDL_CONTROLLER_BUTTON_B }, + { CK_X, SDL_CONTROLLER_BUTTON_X }, + { CK_Y, SDL_CONTROLLER_BUTTON_Y }, { CK_LTRIG, SDL_CONTROLLER_BUTTON_LEFTSHOULDER }, { CK_RTRIG, SDL_CONTROLLER_BUTTON_RIGHTSHOULDER }, { CK_ZTRIG, VK_JOY1_LTRIG - VK_JOY1_BEGIN }, @@ -97,14 +103,7 @@ s32 inputInit(void) if (SDL_IsGameController(jidx)) { pads[cidx] = SDL_GameControllerOpen(jidx); if (pads[cidx]) { - SDL_Haptic *hap = SDL_HapticOpen(jidx); - if (hap) { - if (SDL_HapticRumbleSupported(hap) && (SDL_HapticRumbleInit(hap) == 0)) { - haptics[cidx] = hap; - } else { - SDL_HapticClose(hap); - } - } + SDL_GameControllerSetPlayerIndex(pads[cidx], cidx); ret |= 1 << cidx; ++cidx; } @@ -117,6 +116,8 @@ s32 inputInit(void) mouseSensX = configGetFloat("Input.MouseSpeedX", 1.5f); mouseSensY = configGetFloat("Input.MouseSpeedY", 1.5f); + rumbleScale = configGetFloat("Input.RumbleScale", 0.333f); + deadzone[0] = configGetInt("Input.LStickDeadzone", DEFAULT_DEADZONE); deadzone[1] = configGetInt("Input.RStickDeadzone", DEFAULT_DEADZONE); @@ -226,6 +227,7 @@ void inputUpdate(void) for (s32 i = 0; i < INPUT_MAX_CONTROLLERS; ++i) { if (pads[i] && !SDL_GameControllerGetAttached(pads[i])) { // this controller has been disconnected, nuke it + SDL_GameControllerSetPlayerIndex(pads[i], -1); SDL_GameControllerClose(pads[i]); pads[i] = NULL; // don't clear the first controller @@ -251,18 +253,20 @@ s32 inputRumbleSupported(s32 idx) if (idx < 0 || idx >= INPUT_MAX_CONTROLLERS) { return 0; } - return !!haptics[idx]; + return SDL_GameControllerHasRumble(pads[idx]); } void inputRumble(s32 idx, f32 strength, f32 time) { - if (idx < 0 || idx >= INPUT_MAX_CONTROLLERS || !haptics[idx]) { + if (idx < 0 || idx >= INPUT_MAX_CONTROLLERS || !pads[idx]) { return; } - if (strength <= 0.f) { - SDL_HapticRumbleStop(haptics[idx]); - } else { - SDL_HapticRumblePlay(haptics[idx], strength, (u32)(time * 1000.f)); + if (SDL_GameControllerHasRumble(pads[idx])) { + if (strength < 0.f) { + strength = 0.f; + } + strength *= 65535.f; + SDL_GameControllerRumble(pads[idx], (u16)strength, (u16)strength, (u32)(time * 1000.f)); } } @@ -271,14 +275,15 @@ s32 inputControllerMask(void) return connectedMask; } -void inputKeyBind(s32 idx, u32 cbtn, s32 bind, u32 vk) { - if (idx < 0 || idx >= INPUT_MAX_CONTROLLERS || bind >= MAX_BINDS || cbtn >= CK_TOTAL_COUNT) { +void inputKeyBind(s32 idx, u32 ck, s32 bind, u32 vk) +{ + if (idx < 0 || idx >= INPUT_MAX_CONTROLLERS || bind >= MAX_BINDS || ck >= CK_TOTAL_COUNT) { return; } if (bind < 0) { for (s32 i = 0; i < MAX_BINDS; ++i) { - if (binds[idx][cbtn][i] == 0) { + if (binds[idx][ck][i] == 0) { bind = i; break; } @@ -288,7 +293,7 @@ void inputKeyBind(s32 idx, u32 cbtn, s32 bind, u32 vk) { } } - binds[idx][cbtn][bind] = vk; + binds[idx][ck][bind] = vk; } s32 inputKeyPressed(u32 vk) @@ -315,28 +320,51 @@ s32 inputKeyPressed(u32 vk) return 0; } -void inputLockMouse(s32 lock) { +static inline u16 inputContToContKey(const u16 cont) +{ + if (cont == 0) { + return 0; + } + // just a log2 to convert CONT_* to their indices + return 32 - __builtin_clz(cont - 1); +} + +s32 inputButtonPressed(s32 idx, u16 contbtn) +{ + if (idx < 0 || idx >= INPUT_MAX_CONTROLLERS) { + return 0; + } + + return inputBindPressed(idx, inputContToContKey(contbtn)); +} + +void inputLockMouse(s32 lock) +{ mouseLocked = !!lock; SDL_SetRelativeMouseMode(mouseLocked); } -s32 inputMouseIsLocked(void) { +s32 inputMouseIsLocked(void) +{ return mouseLocked; } -void inputMouseGetPosition(s32 *x, s32 *y) { - if (x) *x = mouseX; - if (y) *y = mouseY; +void inputMouseGetPosition(s32 *x, s32 *y) +{ + if (x) *x = mouseX * videoGetNativeWidth() / videoGetWidth(); + if (y) *y = mouseY * videoGetNativeHeight() / videoGetHeight(); } -void inputMouseGetDelta(s32 *dx, s32 *dy) { +void inputMouseGetRawDelta(s32 *dx, s32 *dy) +{ if (dx) *dx = mouseDX; if (dy) *dy = mouseDY; } -void inputMouseGetNormalizedDelta(f32 *dx, f32 *dy) { +void inputMouseGetScaledDelta(f32 *dx, f32 *dy) +{ s32 w, h; SDL_GetWindowSize(videoGetWindowHandle(), &w, &h); - if (dx) *dx = mouseSensX * (float)mouseDX / 100.0f; - if (dy) *dy = mouseSensY * (float)mouseDY / 100.0f; + if (dx) *dx = mouseSensX * (f32)mouseDX / 100.0f; + if (dy) *dy = mouseSensY * (f32)mouseDY / 100.0f; } diff --git a/port/src/libultra.c b/port/src/libultra.c index 0f179a9d0..952a21207 100644 --- a/port/src/libultra.c +++ b/port/src/libultra.c @@ -236,7 +236,7 @@ s32 __osMotorAccess(OSPfs *pfs, s32 cmd) return PFS_ERR_NOPACK; } - const f32 strength = (cmd == MOTOR_START) ? INPUT_RUMBLE_STRENGTH : 0.f; + const f32 strength = (f32)(cmd == MOTOR_START); inputRumble(pfs->channel, strength, 5.f); // hope someone turns it off in those 5 seconds return 0; diff --git a/port/src/video.c b/port/src/video.c index f84b7263b..07e0fbf5d 100644 --- a/port/src/video.c +++ b/port/src/video.c @@ -94,12 +94,22 @@ void *videoGetWindowHandle(void) return NULL; } -void videoUpdateNativeResolution(const int w, const int h) +void videoUpdateNativeResolution(s32 w, s32 h) { gfx_current_native_viewport.width = w; gfx_current_native_viewport.height = h; } +s32 videoGetNativeWidth(void) +{ + return gfx_current_native_viewport.width; +} + +s32 videoGetNativeHeight(void) +{ + return gfx_current_native_viewport.height; +} + s32 videoGetWidth(void) { return gfx_current_dimensions.width; diff --git a/src/game/bondmove.c b/src/game/bondmove.c index dc69e168f..70249bd3e 100644 --- a/src/game/bondmove.c +++ b/src/game/bondmove.c @@ -698,7 +698,7 @@ void bmoveProcessInput(bool allowc1x, bool allowc1y, bool allowc1buttons, bool i #ifndef PLATFORM_N64 if ((PLAYERCOUNT() == 1) && inputMouseIsLocked()) { - inputMouseGetNormalizedDelta(&movedata.freelookdx, &movedata.freelookdy); + inputMouseGetScaledDelta(&movedata.freelookdx, &movedata.freelookdy); } #endif