From c48fd5f92024c5d46737f4ec735335ce7356327c Mon Sep 17 00:00:00 2001 From: Marcin Kurczewski Date: Mon, 28 Oct 2024 00:09:49 +0100 Subject: [PATCH] input: merge tr1 and tr2 inputs code --- data/tr2/ship/cfg/TR2X_gameflow.json5 | 4 + docs/tr2/CHANGELOG.md | 23 ++ docs/tr2/progress.svg | 56 ++-- docs/tr2/progress.txt | 54 ++-- .../game/input/backends/controller.c | 7 +- .../game/input/backends/internal.c | 0 .../game/input/backends/keyboard.c | 10 +- src/libtrx/game/input/common.c | 165 ++++++++++ .../include/libtrx/game/game_string.def | 4 + src/libtrx/include/libtrx/game/input.h | 3 +- .../libtrx}/game/input/backends/base.h | 2 +- .../libtrx}/game/input/backends/controller.h | 2 +- .../game/input/backends/controller_tr1.def | 0 .../game/input/backends/controller_tr2.def | 15 + .../libtrx}/game/input/backends/internal.h | 4 +- .../libtrx}/game/input/backends/keyboard.h | 2 +- .../game/input/backends/keyboard_tr1.def | 33 +- .../game/input/backends/keyboard_tr2.def | 45 +++ .../include/libtrx}/game/input/common.h | 10 +- src/libtrx/include/libtrx/game/input/role.h | 99 ++++++ .../include/libtrx}/game/input/state.h | 41 ++- src/libtrx/meson.build | 4 + src/tr1/game/game_string.def | 4 - src/tr1/game/{input/common.c => input.c} | 156 +-------- src/tr1/game/input.h | 2 +- src/tr1/game/input/role.h | 55 ---- src/tr1/meson.build | 5 +- src/tr2/config.c | 94 ++++++ src/tr2/config.h | 5 + src/tr2/config_map.c | 1 + src/tr2/config_map.def | 2 + src/tr2/decomp/decomp.c | 60 ++-- src/tr2/decomp/fmv.c | 6 +- src/tr2/decomp/stats.c | 5 + src/tr2/game/common.c | 223 +++++++++++++ src/tr2/game/demo.c | 2 +- src/tr2/game/game.c | 40 +++ src/tr2/game/game.h | 1 + src/tr2/game/gun/gun.c | 4 +- src/tr2/game/input.c | 229 ++++++------- src/tr2/game/input.h | 82 +---- src/tr2/game/inventory/common.c | 4 + src/tr2/game/option/option_controls.c | 75 ++++- src/tr2/game/shell.h | 8 +- src/tr2/game/{shell.c => shell/common.c} | 21 +- src/tr2/game/shell/common.h | 10 + src/tr2/game/shell/input.c | 305 ++++++++++++++++++ src/tr2/game/shell/input.h | 3 + src/tr2/game/ui/controllers/controls.c | 134 ++++---- src/tr2/game/ui/controllers/controls.h | 15 +- src/tr2/game/ui/widgets/controls_dialog.c | 1 - .../game/ui/widgets/controls_input_selector.c | 25 +- src/tr2/global/funcs.h | 11 - src/tr2/global/vars_decomp.h | 1 - src/tr2/inject_exec.c | 8 - src/tr2/meson.build | 4 +- src/tr2/specific/s_input.h | 6 - 57 files changed, 1499 insertions(+), 691 deletions(-) rename src/{tr1 => libtrx}/game/input/backends/controller.c (99%) rename src/{tr1 => libtrx}/game/input/backends/internal.c (100%) rename src/{tr1 => libtrx}/game/input/backends/keyboard.c (98%) create mode 100644 src/libtrx/game/input/common.c rename src/{tr1 => libtrx/include/libtrx}/game/input/backends/base.h (96%) rename src/{tr1 => libtrx/include/libtrx}/game/input/backends/controller.h (55%) rename src/{tr1 => libtrx/include/libtrx}/game/input/backends/controller_tr1.def (100%) create mode 100644 src/libtrx/include/libtrx/game/input/backends/controller_tr2.def rename src/{tr1 => libtrx/include/libtrx}/game/input/backends/internal.h (85%) rename src/{tr1 => libtrx/include/libtrx}/game/input/backends/keyboard.h (54%) rename src/{tr1 => libtrx/include/libtrx}/game/input/backends/keyboard_tr1.def (99%) create mode 100644 src/libtrx/include/libtrx/game/input/backends/keyboard_tr2.def rename src/{tr1 => libtrx/include/libtrx}/game/input/common.h (95%) create mode 100644 src/libtrx/include/libtrx/game/input/role.h rename src/{tr1 => libtrx/include/libtrx}/game/input/state.h (71%) rename src/tr1/game/{input/common.c => input.c} (63%) delete mode 100644 src/tr1/game/input/role.h create mode 100644 src/tr2/game/common.c rename src/tr2/game/{shell.c => shell/common.c} (94%) create mode 100644 src/tr2/game/shell/common.h create mode 100644 src/tr2/game/shell/input.c create mode 100644 src/tr2/game/shell/input.h delete mode 100644 src/tr2/specific/s_input.h diff --git a/data/tr2/ship/cfg/TR2X_gameflow.json5 b/data/tr2/ship/cfg/TR2X_gameflow.json5 index e7488071dd..e9fed26286 100644 --- a/data/tr2/ship/cfg/TR2X_gameflow.json5 +++ b/data/tr2/ship/cfg/TR2X_gameflow.json5 @@ -351,6 +351,10 @@ }, "game_strings": { + "CONTROL_CUSTOM_1": "Custom Scheme 1", + "CONTROL_CUSTOM_2": "Custom Scheme 2", + "CONTROL_CUSTOM_3": "Custom Scheme 3", + "CONTROL_DEFAULT_KEYS": "Default Keys", "MISC_OFF": "Off", "MISC_ON": "On", "OSD_AMBIGUOUS_INPUT_2": "Ambiguous input: %s and %s", diff --git a/docs/tr2/CHANGELOG.md b/docs/tr2/CHANGELOG.md index cb5d272b7c..7dd90638ed 100644 --- a/docs/tr2/CHANGELOG.md +++ b/docs/tr2/CHANGELOG.md @@ -1,4 +1,27 @@ ## [Unreleased](https://github.com/LostArtefacts/TRX/compare/tr2-0.5...develop) - ××××-××-×× +- changed the inputs backend from DirectX to SDL (#1695) + - improved controller support to match TR1X + - changed the number of custom layouts to 3 + - changed default key bindings according to the following table: + | Key | Old binding | New binding | Reason + | ----------------------------- | ----------- | ------------ | ----- + | Flare | Comma (,) | Period (.) | To maintain forward compatibility with TR3 + | Screenshot | S | Print Screen | To maintain compatibility with TR1X + | Toggle bilinear filter | F8 | F3 | To maintain compatibility with TR1X + | Toggle perspective filter | Shift+F8 | F4 | To maintain compatibility with TR1X + | Toggle z-buffer | F7 | F7 | Likely to be permanently enabled in the future + | Toggle triple buffering | Shift+F7 | **Removed** | Obscure setting, will be either removed or available via the ingame UI at some point + | Toggle dither | F11 | **Removed** | Obscure setting, will be either removed or available via the ingame UI at some point + | Toggle fullscreen | F12 | Alt-Enter | To maintain compatibility with TR1X + | Toggle rendering mode | Shift+F12 | F12 | No more conflict to require Shift + | Decrease resolution | F1 | Shift+F1 | F3 and F4 are already taken + | Increase resolution | F2 | F1 | F3 and F4 are already taken + | Decrease internal screen size | F3 | Shift+F2 | F3 and F4 are already taken + | Increase internal screen size | F4 | F2 | F3 and F4 are already taken + - removed "falling through" to the default layout, with the exception of keyboard arrows (matching TR1X behavior) + - removed hardcoded Shift+F7 key binding for toggling triple buffering + - removed hardcoded `0` key binding for flares + - removed hardcoded cooldown of 15 frames for medipacks - improved FMV mode appearance - removed black scanlines (#1729) - improved FMV mode behavior - stopped switching screen resolutions (#1729) - improved screenshots: now saved in the screenshots/ directory with level titles and timestamps as JPG or PNG, similar to TR1X (#1773) diff --git a/docs/tr2/progress.svg b/docs/tr2/progress.svg index 0964cc55c5..d82f99d425 100644 --- a/docs/tr2/progress.svg +++ b/docs/tr2/progress.svg @@ -69,10 +69,10 @@ Tomb2.exe progress according to the physical function order: -70.02% (871) · 27.57% (343) · 0% (0) · 2.41% (30) +70.90% (882) · 26.69% (332) · 0% (0) · 2.41% (30) - - + + @@ -961,19 +961,19 @@ bool __cdecl DInputCreate(void); void __cdecl DInputRelease(void); void __cdecl WinInReadKeyboard(LPVOID lpInputData); -DWORD __cdecl WinInReadJoystick(int32_t *x, int32_t *y); +DWORD __cdecl WinInReadJoystick(int32_t *x, int32_t *y); sub_4473A0 -bool __cdecl WinInputInit(void); -bool __cdecl DInputEnumDevices(JOYSTICK_LIST *joystickList); -BOOL __stdcall DInputEnumDevicesCallback(LPCDIDEVICEINSTANCE lpddi, LPVOID pvRef); +bool __cdecl WinInputInit(void); +bool __cdecl DInputEnumDevices(JOYSTICK_LIST *joystickList); +BOOL __stdcall DInputEnumDevicesCallback(LPCDIDEVICEINSTANCE lpddi, LPVOID pvRef); void __thiscall S_FlaggedString_Create(STRING_FLAGGED *string, int32_t size); -JOYSTICK_NODE *__cdecl GetJoystick(GUID *lpGuid); -void __cdecl DInputKeyboardCreate(void); -void __cdecl DInputKeyboardRelease(void); -bool __cdecl DInputJoystickCreate(void); -void __cdecl WinInStart(void); -void __cdecl WinInFinish(void); -void __cdecl WinInRunControlPanel(HWND hWnd); +JOYSTICK_NODE *__cdecl GetJoystick(GUID *lpGuid); +void __cdecl DInputKeyboardCreate(void); +void __cdecl DInputKeyboardRelease(void); +bool __cdecl DInputJoystickCreate(void); +void __cdecl WinInStart(void); +void __cdecl WinInFinish(void); +void __cdecl WinInRunControlPanel(HWND hWnd); void __cdecl IncreaseScreenSize(void); void __cdecl DecreaseScreenSize(void); void __cdecl setup_screen_size(void); @@ -1324,10 +1324,10 @@ Tomb2.exe progress according to the function sizes: -74.33% · 25.34% · 0% · 0.33% +74.70% · 24.97% · 0% · 0.33% - - + + @@ -1708,7 +1708,7 @@ void __cdecl Output_InsertPolygons(const int16_t *obj_ptr, int32_t clip); void __cdecl ControlBubble1(int16_t fx_num); void __cdecl Lara_SurfaceCollision(ITEM *item, COLL_INFO *coll); -DWORD __cdecl WinInReadJoystick(int32_t *x, int32_t *y); +DWORD __cdecl WinInReadJoystick(int32_t *x, int32_t *y); int32_t __cdecl Box_StalkBox(const ITEM *item, const ITEM *enemy, int16_t box_num); void __cdecl Gun_Rifle_FireShotgun(void); void __cdecl SphereOfDoom(int16_t item_num); @@ -1718,14 +1718,14 @@ void __cdecl Lara_State_SurfTread(ITEM *item, COLL_INFO *coll); void __cdecl Output_InsertRoom(const int16_t *obj_ptr, int32_t is_outside); void __cdecl Output_CalculateObjectLighting(const ITEM *item, const FRAME_INFO *frame); -BOOL __stdcall DInputEnumDevicesCallback(LPCDIDEVICEINSTANCE lpddi, LPVOID pvRef); +BOOL __stdcall DInputEnumDevicesCallback(LPCDIDEVICEINSTANCE lpddi, LPVOID pvRef); void __cdecl CalculateWibbleTable(void); void __cdecl Camera_RefreshFromTrigger(int16_t type, const int16_t *data); int32_t __cdecl Lara_TestWaterStepOut(ITEM *item, COLL_INFO *coll); int32_t __cdecl S_Audio_Sample_Play(int32_t sample_id, int32_t volume, int32_t pitch, int32_t pan, int32_t flags); void __cdecl Lara_TouchLava(ITEM *item); void __cdecl RenderFinish(bool need_to_clear_textures); -bool __cdecl DInputJoystickCreate(void); +bool __cdecl DInputJoystickCreate(void); void __cdecl S_InitialisePolyList(BOOL clear_back_buffer); void __cdecl Effect_Kill(int16_t fx_num); void __cdecl BigBowlControl(int16_t item_num); @@ -1770,7 +1770,7 @@ void __cdecl Output_InsertFlatRect(int32_t x0, int32_t y0, int32_t x1, int32_t y1, int32_t z, uint8_t color_idx); int32_t __cdecl Item_TestBoundsCollide(const ITEM *src_item, const ITEM *dst_item, int32_t radius); void __cdecl Lara_State_Wade(ITEM *item, COLL_INFO *coll); -void __cdecl DInputKeyboardCreate(void); +void __cdecl DInputKeyboardCreate(void); void __cdecl Room_GetNearbyRooms(int32_t x, int32_t y, int32_t z, int32_t r, int32_t h, int16_t room_num); void __cdecl Door_Control(int16_t item_num); BYTE __cdecl FindNearestPaletteEntry(RGB_888 *palette, int32_t red, int32_t green, int32_t blue, bool ignore_sys_palette); @@ -1961,7 +1961,7 @@ void __cdecl ControlExplosion1(int16_t fx_num); int32_t __cdecl Lara_DeflectEdge(ITEM *item, COLL_INFO *coll); void __cdecl SkidooDriver_Initialise(int16_t item_num); -bool __cdecl WinInputInit(void); +bool __cdecl WinInputInit(void); void __cdecl Random_Seed(void); void __cdecl Option_DoInventory(INVENTORY_ITEM *item); void __cdecl BellControl(int16_t item_num); @@ -2130,7 +2130,7 @@ void __cdecl Gun_Pistols_DrawMeshes(LARA_GUN_TYPE weapon_type); int32_t __cdecl MovableBlock_TestDestination(ITEM *item, int32_t block_height); void __cdecl ControlGunShot(int16_t fx_num); -JOYSTICK_NODE *__cdecl GetJoystick(GUID *lpGuid); +JOYSTICK_NODE *__cdecl GetJoystick(GUID *lpGuid); bool __cdecl OpenGameRegistryKey(LPCTSTR key); double __cdecl UT_Microseconds(void); void __cdecl Lara_State_Extra_StartAnim(ITEM *item, COLL_INFO *coll); @@ -2330,7 +2330,7 @@ void __cdecl S_DrawScreenFBox(int32_t sx, int32_t sy, int32_t z, int32_t width, int32_t height, BYTE color_idx, const GOURAUD_FILL *gour, uint16_t flags); void __cdecl Demo_GetInput(void); BOOL __cdecl Overlay_FlashCounter(void); -void __cdecl WinInStart(void); +void __cdecl WinInStart(void); void __cdecl ChandelierFX(ITEM *item); void __cdecl Overlay_DrawModeInfo(void); void __cdecl Inv_Ring_CalcAdders(RING_INFO *ring, int16_t rotation_duration); @@ -2354,7 +2354,7 @@ int32_t __cdecl S_Audio_Sample_CalculateSampleVolume(int32_t volume); LONG __cdecl SetRegistryBoolValue(LPCTSTR lpValueName, bool value); void __cdecl Text_AddOutline(TEXTSTRING *string, int16_t enable, int16_t color, uint16_t *gour_ptr, uint16_t flags); -void __cdecl DInputKeyboardRelease(void); +void __cdecl DInputKeyboardRelease(void); void __cdecl HWR_ResetTexSource(void); void __cdecl Overlay_MakeAmmoString(char *string); int32_t __cdecl CalculateWindowHeight(int32_t width, int32_t height); @@ -2379,7 +2379,7 @@ void __cdecl Inv_RemoveInventoryText(void); void __cdecl Sound_Shutdown(void); int16_t __cdecl Text_GetTextLength(const char *text); -bool __cdecl DInputEnumDevices(JOYSTICK_LIST *joystickList); +bool __cdecl DInputEnumDevices(JOYSTICK_LIST *joystickList); void __cdecl HWR_TexSource(HWR_TEXTURE_HANDLE tex_source); void __cdecl RubbleFX(ITEM *item); void __cdecl ExplosionFX(ITEM *item); @@ -2459,7 +2459,7 @@ int32_t __cdecl UT_MessageBox(LPCTSTR lpText, HWND hWnd); void __cdecl AssaultReset(ITEM *item); void __cdecl Text_SetScale(TEXTSTRING *string, int32_t scale_h, int32_t scale_v); -void __cdecl WinInRunControlPanel(HWND hWnd); +void __cdecl WinInRunControlPanel(HWND hWnd); sub_44E860 void __cdecl SE_GraphicsAdapterSet(HWND hwndDlg, DISPLAY_ADAPTER_NODE *adapter); void __cdecl S_Audio_Sample_OutCloseTrack(int32_t track_id); @@ -2500,7 +2500,7 @@ void __cdecl Text_RemoveOutline(TEXTSTRING *string); sub_44E880 void __cdecl ScreenPartialDump(void); -void __cdecl WinInFinish(void); +void __cdecl WinInFinish(void); void __cdecl S_FinishInventory(void); bool __cdecl IsNewRegistryKeyCreated(void); bool __cdecl S_PlayFMV(const char *file_name); diff --git a/docs/tr2/progress.txt b/docs/tr2/progress.txt index c1c3fde5c2..665f2eb294 100644 --- a/docs/tr2/progress.txt +++ b/docs/tr2/progress.txt @@ -379,20 +379,20 @@ typedef struct __unaligned { } VERTEX_INFO; typedef enum { // decompiled - INPUT_ROLE_FORWARD = 0, - INPUT_ROLE_BACK = 1, - INPUT_ROLE_LEFT = 2, - INPUT_ROLE_RIGHT = 3, - INPUT_ROLE_STEP_LEFT = 4, - INPUT_ROLE_STEP_RIGHT = 5, - INPUT_ROLE_SLOW = 6, - INPUT_ROLE_JUMP = 7, - INPUT_ROLE_ACTION = 8, - INPUT_ROLE_DRAW_WEAPON = 9, - INPUT_ROLE_FLARE = 10, - INPUT_ROLE_LOOK = 11, - INPUT_ROLE_ROLL = 12, - INPUT_ROLE_OPTION = 13, + INPUT_ROLE_FORWARD = 0, + INPUT_ROLE_BACK = 1, + INPUT_ROLE_LEFT = 2, + INPUT_ROLE_RIGHT = 3, + INPUT_ROLE_STEP_L = 4, + INPUT_ROLE_STEP_R = 5, + INPUT_ROLE_SLOW = 6, + INPUT_ROLE_JUMP = 7, + INPUT_ROLE_ACTION = 8, + INPUT_ROLE_DRAW = 9, + INPUT_ROLE_USE_FLARE = 10, + INPUT_ROLE_LOOK = 11, + INPUT_ROLE_ROLL = 12, + INPUT_ROLE_OPTION = 13, } INPUT_ROLE; typedef struct __unaligned { @@ -3865,19 +3865,19 @@ typedef enum { 0x004471F0 0x0022 +R bool __cdecl DInputCreate(void); 0x00447220 0x001A +R void __cdecl DInputRelease(void); 0x00447240 0x005A +R void __cdecl WinInReadKeyboard(LPVOID lpInputData); -0x004472A0 0x00F3 -R DWORD __cdecl WinInReadJoystick(int32_t *x, int32_t *y); +0x004472A0 0x00F3 +R DWORD __cdecl WinInReadJoystick(int32_t *x, int32_t *y); 0x004473A0 0x0005 x sub_4473A0 -0x004473B0 0x007F -R bool __cdecl WinInputInit(void); -0x00447430 0x0024 -R bool __cdecl DInputEnumDevices(JOYSTICK_LIST *joystickList); -0x00447460 0x00E8 -R BOOL __stdcall DInputEnumDevicesCallback(LPCDIDEVICEINSTANCE lpddi, LPVOID pvRef); +0x004473B0 0x007F +R bool __cdecl WinInputInit(void); +0x00447430 0x0024 +R bool __cdecl DInputEnumDevices(JOYSTICK_LIST *joystickList); +0x00447460 0x00E8 +R BOOL __stdcall DInputEnumDevicesCallback(LPCDIDEVICEINSTANCE lpddi, LPVOID pvRef); 0x00447550 0x001F + void __thiscall S_FlaggedString_Create(STRING_FLAGGED *string, int32_t size); -0x00447570 0x004E -R JOYSTICK_NODE *__cdecl GetJoystick(GUID *lpGuid); -0x004475C0 0x00C9 -R void __cdecl DInputKeyboardCreate(void); -0x00447690 0x0029 -R void __cdecl DInputKeyboardRelease(void); -0x004476C0 0x00E4 -R bool __cdecl DInputJoystickCreate(void); -0x004477B0 0x002D -R void __cdecl WinInStart(void); -0x004477E0 0x000F -R void __cdecl WinInFinish(void); -0x004477F0 0x0017 -R void __cdecl WinInRunControlPanel(HWND hWnd); +0x00447570 0x004E +R JOYSTICK_NODE *__cdecl GetJoystick(GUID *lpGuid); +0x004475C0 0x00C9 +R void __cdecl DInputKeyboardCreate(void); +0x00447690 0x0029 +R void __cdecl DInputKeyboardRelease(void); +0x004476C0 0x00E4 +R bool __cdecl DInputJoystickCreate(void); +0x004477B0 0x002D +R void __cdecl WinInStart(void); +0x004477E0 0x000F +R void __cdecl WinInFinish(void); +0x004477F0 0x0017 +R void __cdecl WinInRunControlPanel(HWND hWnd); 0x00447810 0x0062 *R void __cdecl IncreaseScreenSize(void); 0x00447880 0x0062 *R void __cdecl DecreaseScreenSize(void); 0x004478F0 0x009F *R void __cdecl setup_screen_size(void); @@ -4455,7 +4455,7 @@ typedef enum { 0x0051A108 - uint8_t g_DIKeys[256]; 0x0051A208 + int32_t g_Input; 0x0051A20C - int8_t g_IsVidModeLock; -0x0051A210 - int32_t g_JoyKeys; +0x0051A210 + int32_t g_JoyKeys; 0x0051A214 + int32_t g_JoyXPos; 0x0051A218 + int32_t g_JoyYPos; 0x0051A220 + int32_t g_MediPackCooldown; @@ -4511,7 +4511,7 @@ typedef enum { 0x00526314 - int16_t g_CineFrameIdx; 0x00526320 - CAMERA_INFO g_Camera; 0x005263CC - BOX_INFO *g_Boxes; -0x004D855C - LPDIRECTINPUT g_DInput; +0x004D855C + LPDIRECTINPUT g_DInput; 0x004D8560 - LPDIRECTINPUTDEVICE IDID_SysKeyboard; 0x0051BDA0 - BOOL g_IsTitleLoaded; 0x004D7980 - int32_t g_Inv_ExtraData[8]; diff --git a/src/tr1/game/input/backends/controller.c b/src/libtrx/game/input/backends/controller.c similarity index 99% rename from src/tr1/game/input/backends/controller.c rename to src/libtrx/game/input/backends/controller.c index 3231f99d64..96db85255a 100644 --- a/src/tr1/game/input/backends/controller.c +++ b/src/libtrx/game/input/backends/controller.c @@ -1,8 +1,7 @@ #include "game/input/backends/controller.h" #include "game/input/backends/internal.h" - -#include +#include "log.h" #include #include @@ -31,6 +30,8 @@ static BUILTIN_CONTROLLER_LAYOUT m_BuiltinLayout[] = { { role, { button_type, { bind }, axis_dir } }, #if TR_VERSION == 1 #include "game/input/backends/controller_tr1.def" +#elif TR_VERSION == 1 + #include "game/input/backends/controller_tr2.def" #endif // guard { -1, { 0, { 0 }, 0 } }, @@ -385,6 +386,8 @@ static bool M_CustomUpdate(INPUT_STATE *const result, const INPUT_LAYOUT layout) } #if TR_VERSION == 1 result->menu_back |= M_JoyBtn(SDL_CONTROLLER_BUTTON_Y); +#elif TR_VERSION == 2 + result->menu_back |= M_JoyBtn(SDL_CONTROLLER_BUTTON_Y); #endif return true; } diff --git a/src/tr1/game/input/backends/internal.c b/src/libtrx/game/input/backends/internal.c similarity index 100% rename from src/tr1/game/input/backends/internal.c rename to src/libtrx/game/input/backends/internal.c diff --git a/src/tr1/game/input/backends/keyboard.c b/src/libtrx/game/input/backends/keyboard.c similarity index 98% rename from src/tr1/game/input/backends/keyboard.c rename to src/libtrx/game/input/backends/keyboard.c index 12bfe6063c..c40e261a49 100644 --- a/src/tr1/game/input/backends/keyboard.c +++ b/src/libtrx/game/input/backends/keyboard.c @@ -11,14 +11,16 @@ typedef struct { SDL_Scancode scancode; } BUILTIN_KEYBOARD_LAYOUT; -const Uint8 *m_KeyboardState; +const Uint8 *m_KeyboardState = NULL; static bool m_Conflicts[INPUT_LAYOUT_NUMBER_OF][INPUT_ROLE_NUMBER_OF] = { 0 }; static BUILTIN_KEYBOARD_LAYOUT m_BuiltinLayout[] = { // clang-format off #define INPUT_KEYBOARD_ASSIGN(role, key) { role, key }, #if TR_VERSION == 1 -#include "keyboard_tr1.def" +#include "game/input/backends/keyboard_tr1.def" +#elif TR_VERSION == 2 +#include "game/input/backends/keyboard_tr2.def" #endif { -1, SDL_SCANCODE_UNKNOWN }, // clang-format on @@ -381,6 +383,10 @@ static bool M_CustomUpdate(INPUT_STATE *const result, const INPUT_LAYOUT layout) // we only do this for keyboard input #if TR_VERSION == 1 result->menu_confirm |= result->action; +#elif TR_VERSION == 2 + result->menu_confirm |= result->action; + result->toggle_fullscreen = + KEY_DOWN(SDL_SCANCODE_RETURN) && KEY_DOWN(SDL_SCANCODE_LALT); #endif return true; } diff --git a/src/libtrx/game/input/common.c b/src/libtrx/game/input/common.c new file mode 100644 index 0000000000..99caec1ce0 --- /dev/null +++ b/src/libtrx/game/input/common.c @@ -0,0 +1,165 @@ +#include "game/input/common.h" + +#include "game/clock.h" +#include "game/game_string.h" +#include "game/input/backends/controller.h" +#include "game/input/backends/keyboard.h" + +#include + +INPUT_STATE g_Input = { 0 }; +INPUT_STATE g_InputDB = { 0 }; +INPUT_STATE g_OldInputDB = { 0 }; + +static bool m_ListenMode = false; + +static bool m_IsRoleHardcoded[INPUT_ROLE_NUMBER_OF] = { + 0, +#if TR_VERSION == 1 + [INPUT_ROLE_UNBIND_KEY] = 1, + [INPUT_ROLE_RESET_BINDINGS] = 1, + [INPUT_ROLE_PERSPECTIVE] = 1, +#endif + [INPUT_ROLE_MENU_CONFIRM] = 1, + [INPUT_ROLE_MENU_BACK] = 1, + [INPUT_ROLE_MENU_LEFT] = 1, + [INPUT_ROLE_MENU_RIGHT] = 1, + [INPUT_ROLE_MENU_UP] = 1, + [INPUT_ROLE_MENU_DOWN] = 1, +}; + +static const GAME_STRING_ID m_LayoutMap[INPUT_LAYOUT_NUMBER_OF] = { + [INPUT_LAYOUT_DEFAULT] = GS_ID(CONTROL_DEFAULT_KEYS), + [INPUT_LAYOUT_CUSTOM_1] = GS_ID(CONTROL_CUSTOM_1), + [INPUT_LAYOUT_CUSTOM_2] = GS_ID(CONTROL_CUSTOM_2), + [INPUT_LAYOUT_CUSTOM_3] = GS_ID(CONTROL_CUSTOM_3), +}; + +static INPUT_BACKEND_IMPL *M_GetBackend(INPUT_BACKEND backend); + +static INPUT_BACKEND_IMPL *M_GetBackend(const INPUT_BACKEND backend) +{ + switch (backend) { + case INPUT_BACKEND_KEYBOARD: + return &g_Input_Keyboard; + case INPUT_BACKEND_CONTROLLER: + return &g_Input_Controller; + } + return NULL; +} + +void Input_Init(void) +{ + if (g_Input_Keyboard.init != NULL) { + g_Input_Keyboard.init(); + } + if (g_Input_Controller.init != NULL) { + g_Input_Controller.init(); + } +} + +void Input_Shutdown(void) +{ + if (g_Input_Keyboard.shutdown != NULL) { + g_Input_Keyboard.shutdown(); + } + if (g_Input_Controller.shutdown != NULL) { + g_Input_Controller.shutdown(); + } +} + +void Input_InitController(void) +{ + if (g_Input_Controller.init != NULL) { + g_Input_Controller.init(); + } +} + +void Input_ShutdownController(void) +{ + if (g_Input_Controller.shutdown != NULL) { + g_Input_Controller.shutdown(); + } +} + +bool Input_IsRoleRebindable(const INPUT_ROLE role) +{ + return !m_IsRoleHardcoded[role]; +} + +bool Input_IsPressed( + const INPUT_BACKEND backend, const INPUT_LAYOUT layout, + const INPUT_ROLE role) +{ + return M_GetBackend(backend)->is_pressed(layout, role); +} + +bool Input_IsKeyConflicted( + const INPUT_BACKEND backend, const INPUT_LAYOUT layout, + const INPUT_ROLE role) +{ + return M_GetBackend(backend)->is_role_conflicted(layout, role); +} + +bool Input_ReadAndAssignRole( + const INPUT_BACKEND backend, const INPUT_LAYOUT layout, + const INPUT_ROLE role) +{ + return M_GetBackend(backend)->read_and_assign(layout, role); +} + +void Input_UnassignRole( + const INPUT_BACKEND backend, const INPUT_LAYOUT layout, + const INPUT_ROLE role) +{ + M_GetBackend(backend)->unassign_role(layout, role); +} + +const char *Input_GetKeyName( + const INPUT_BACKEND backend, const INPUT_LAYOUT layout, + const INPUT_ROLE role) +{ + return M_GetBackend(backend)->get_name(layout, role); +} + +void Input_ResetLayout(const INPUT_BACKEND backend, const INPUT_LAYOUT layout) +{ + return M_GetBackend(backend)->reset_layout(layout); +} + +void Input_EnterListenMode(void) +{ + m_ListenMode = true; +} + +void Input_ExitListenMode(void) +{ + m_ListenMode = false; + Input_Update(); + g_OldInputDB.any = g_Input.any; + g_InputDB.any = g_Input.any; +} + +bool Input_IsInListenMode(void) +{ + return m_ListenMode; +} + +bool Input_AssignFromJSONObject( + const INPUT_BACKEND backend, const INPUT_LAYOUT layout, + JSON_OBJECT *const bind_obj) +{ + return M_GetBackend(backend)->assign_from_json_object(layout, bind_obj); +} + +bool Input_AssignToJSONObject( + const INPUT_BACKEND backend, const INPUT_LAYOUT layout, + JSON_OBJECT *const bind_obj, const INPUT_ROLE role) +{ + return M_GetBackend(backend)->assign_to_json_object(layout, bind_obj, role); +} + +const char *Input_GetLayoutName(const INPUT_LAYOUT layout) +{ + return GameString_Get(m_LayoutMap[layout]); +} diff --git a/src/libtrx/include/libtrx/game/game_string.def b/src/libtrx/include/libtrx/game/game_string.def index 4877870d2c..0b0c9c7236 100644 --- a/src/libtrx/include/libtrx/game/game_string.def +++ b/src/libtrx/include/libtrx/game/game_string.def @@ -45,3 +45,7 @@ GS_DEFINE(OSD_AMBIGUOUS_INPUT_2, "Ambiguous input: %s and %s") GS_DEFINE(OSD_AMBIGUOUS_INPUT_3, "Ambiguous input: %s, %s, ...") GS_DEFINE(OSD_UI_ON, "UI enabled") GS_DEFINE(OSD_UI_OFF, "UI disabled") +GS_DEFINE(CONTROL_DEFAULT_KEYS, "Default Keys") +GS_DEFINE(CONTROL_CUSTOM_1, "Custom Scheme 1") +GS_DEFINE(CONTROL_CUSTOM_2, "Custom Scheme 2") +GS_DEFINE(CONTROL_CUSTOM_3, "Custom Scheme 3") diff --git a/src/libtrx/include/libtrx/game/input.h b/src/libtrx/include/libtrx/game/input.h index 4f5d68ef07..6982f1d168 100644 --- a/src/libtrx/include/libtrx/game/input.h +++ b/src/libtrx/include/libtrx/game/input.h @@ -1,4 +1,3 @@ #pragma once -extern void Input_EnterListenMode(void); -extern void Input_ExitListenMode(void); +#include "input/common.h" diff --git a/src/tr1/game/input/backends/base.h b/src/libtrx/include/libtrx/game/input/backends/base.h similarity index 96% rename from src/tr1/game/input/backends/base.h rename to src/libtrx/include/libtrx/game/input/backends/base.h index da73ebbed7..8c379eeafa 100644 --- a/src/tr1/game/input/backends/base.h +++ b/src/libtrx/include/libtrx/game/input/backends/base.h @@ -1,6 +1,6 @@ #pragma once -#include "game/input/common.h" +#include "../common.h" #include diff --git a/src/tr1/game/input/backends/controller.h b/src/libtrx/include/libtrx/game/input/backends/controller.h similarity index 55% rename from src/tr1/game/input/backends/controller.h rename to src/libtrx/include/libtrx/game/input/backends/controller.h index 39b0574e49..1ac9b08147 100644 --- a/src/tr1/game/input/backends/controller.h +++ b/src/libtrx/include/libtrx/game/input/backends/controller.h @@ -1,3 +1,3 @@ -#include "game/input/backends/base.h" +#include "base.h" extern INPUT_BACKEND_IMPL g_Input_Controller; diff --git a/src/tr1/game/input/backends/controller_tr1.def b/src/libtrx/include/libtrx/game/input/backends/controller_tr1.def similarity index 100% rename from src/tr1/game/input/backends/controller_tr1.def rename to src/libtrx/include/libtrx/game/input/backends/controller_tr1.def diff --git a/src/libtrx/include/libtrx/game/input/backends/controller_tr2.def b/src/libtrx/include/libtrx/game/input/backends/controller_tr2.def new file mode 100644 index 0000000000..eccd854906 --- /dev/null +++ b/src/libtrx/include/libtrx/game/input/backends/controller_tr2.def @@ -0,0 +1,15 @@ +INPUT_CONTROLLER_ASSIGN(INPUT_ROLE_UP, BT_BUTTON, SDL_CONTROLLER_BUTTON_DPAD_UP, 0) +INPUT_CONTROLLER_ASSIGN(INPUT_ROLE_DOWN, BT_BUTTON, SDL_CONTROLLER_BUTTON_DPAD_DOWN, 0) +INPUT_CONTROLLER_ASSIGN(INPUT_ROLE_LEFT, BT_BUTTON, SDL_CONTROLLER_BUTTON_DPAD_LEFT, 0) +INPUT_CONTROLLER_ASSIGN(INPUT_ROLE_RIGHT, BT_BUTTON, SDL_CONTROLLER_BUTTON_DPAD_RIGHT, 0) +INPUT_CONTROLLER_ASSIGN(INPUT_ROLE_STEP_L, BT_AXIS, SDL_CONTROLLER_AXIS_TRIGGERLEFT, 1) +INPUT_CONTROLLER_ASSIGN(INPUT_ROLE_STEP_R, BT_AXIS, SDL_CONTROLLER_AXIS_TRIGGERRIGHT, 1) +INPUT_CONTROLLER_ASSIGN(INPUT_ROLE_SLOW, BT_BUTTON, SDL_CONTROLLER_BUTTON_RIGHTSHOULDER, 0) +INPUT_CONTROLLER_ASSIGN(INPUT_ROLE_JUMP, BT_BUTTON, SDL_CONTROLLER_BUTTON_X, 0) +INPUT_CONTROLLER_ASSIGN(INPUT_ROLE_ACTION, BT_BUTTON, SDL_CONTROLLER_BUTTON_A, 0) +INPUT_CONTROLLER_ASSIGN(INPUT_ROLE_DRAW, BT_BUTTON, SDL_CONTROLLER_BUTTON_Y, 0) +INPUT_CONTROLLER_ASSIGN(INPUT_ROLE_LOOK, BT_BUTTON, SDL_CONTROLLER_BUTTON_LEFTSHOULDER, 0) +INPUT_CONTROLLER_ASSIGN(INPUT_ROLE_ROLL, BT_BUTTON, SDL_CONTROLLER_BUTTON_B, 0) +INPUT_CONTROLLER_ASSIGN(INPUT_ROLE_OPTION, BT_BUTTON, SDL_CONTROLLER_BUTTON_BACK, 0) +INPUT_CONTROLLER_ASSIGN(INPUT_ROLE_MENU_CONFIRM, BT_BUTTON, SDL_CONTROLLER_BUTTON_A, 0) +INPUT_CONTROLLER_ASSIGN(INPUT_ROLE_MENU_BACK, BT_BUTTON, SDL_CONTROLLER_BUTTON_B, 0) diff --git a/src/tr1/game/input/backends/internal.h b/src/libtrx/include/libtrx/game/input/backends/internal.h similarity index 85% rename from src/tr1/game/input/backends/internal.h rename to src/libtrx/include/libtrx/game/input/backends/internal.h index acb0336100..eac5f999ea 100644 --- a/src/tr1/game/input/backends/internal.h +++ b/src/libtrx/include/libtrx/game/input/backends/internal.h @@ -1,7 +1,7 @@ #pragma once -#include "game/input/backends/base.h" -#include "game/input/common.h" +#include "../common.h" +#include "base.h" void Input_UpdateFromBackend( INPUT_STATE *const result, INPUT_LAYOUT layout, diff --git a/src/tr1/game/input/backends/keyboard.h b/src/libtrx/include/libtrx/game/input/backends/keyboard.h similarity index 54% rename from src/tr1/game/input/backends/keyboard.h rename to src/libtrx/include/libtrx/game/input/backends/keyboard.h index 8a18e61f36..e1b99b49ec 100644 --- a/src/tr1/game/input/backends/keyboard.h +++ b/src/libtrx/include/libtrx/game/input/backends/keyboard.h @@ -1,3 +1,3 @@ -#include "game/input/backends/base.h" +#include "base.h" extern INPUT_BACKEND_IMPL g_Input_Keyboard; diff --git a/src/tr1/game/input/backends/keyboard_tr1.def b/src/libtrx/include/libtrx/game/input/backends/keyboard_tr1.def similarity index 99% rename from src/tr1/game/input/backends/keyboard_tr1.def rename to src/libtrx/include/libtrx/game/input/backends/keyboard_tr1.def index c7361be049..639c6738bd 100644 --- a/src/tr1/game/input/backends/keyboard_tr1.def +++ b/src/libtrx/include/libtrx/game/input/backends/keyboard_tr1.def @@ -2,46 +2,51 @@ INPUT_KEYBOARD_ASSIGN(INPUT_ROLE_UP, SDL_SCANCODE_UP) INPUT_KEYBOARD_ASSIGN(INPUT_ROLE_DOWN, SDL_SCANCODE_DOWN) INPUT_KEYBOARD_ASSIGN(INPUT_ROLE_LEFT, SDL_SCANCODE_LEFT) INPUT_KEYBOARD_ASSIGN(INPUT_ROLE_RIGHT, SDL_SCANCODE_RIGHT) -INPUT_KEYBOARD_ASSIGN(INPUT_ROLE_STEP_L, SDL_SCANCODE_DELETE) -INPUT_KEYBOARD_ASSIGN(INPUT_ROLE_STEP_R, SDL_SCANCODE_PAGEDOWN) -INPUT_KEYBOARD_ASSIGN(INPUT_ROLE_SLOW, SDL_SCANCODE_RSHIFT) INPUT_KEYBOARD_ASSIGN(INPUT_ROLE_JUMP, SDL_SCANCODE_RALT) -INPUT_KEYBOARD_ASSIGN(INPUT_ROLE_ACTION, SDL_SCANCODE_RCTRL) INPUT_KEYBOARD_ASSIGN(INPUT_ROLE_DRAW, SDL_SCANCODE_SPACE) +INPUT_KEYBOARD_ASSIGN(INPUT_ROLE_ACTION, SDL_SCANCODE_RCTRL) +INPUT_KEYBOARD_ASSIGN(INPUT_ROLE_SLOW, SDL_SCANCODE_RSHIFT) INPUT_KEYBOARD_ASSIGN(INPUT_ROLE_LOOK, SDL_SCANCODE_KP_0) +INPUT_KEYBOARD_ASSIGN(INPUT_ROLE_STEP_L, SDL_SCANCODE_DELETE) +INPUT_KEYBOARD_ASSIGN(INPUT_ROLE_STEP_R, SDL_SCANCODE_PAGEDOWN) INPUT_KEYBOARD_ASSIGN(INPUT_ROLE_ROLL, SDL_SCANCODE_END) -INPUT_KEYBOARD_ASSIGN(INPUT_ROLE_OPTION, SDL_SCANCODE_ESCAPE) + +INPUT_KEYBOARD_ASSIGN(INPUT_ROLE_PAUSE, SDL_SCANCODE_P) +INPUT_KEYBOARD_ASSIGN(INPUT_ROLE_ENTER_CONSOLE, SDL_SCANCODE_SLASH) +INPUT_KEYBOARD_ASSIGN(INPUT_ROLE_SAVE, SDL_SCANCODE_F5) +INPUT_KEYBOARD_ASSIGN(INPUT_ROLE_LOAD, SDL_SCANCODE_F6) + INPUT_KEYBOARD_ASSIGN(INPUT_ROLE_FLY_CHEAT, SDL_SCANCODE_O) INPUT_KEYBOARD_ASSIGN(INPUT_ROLE_ITEM_CHEAT, SDL_SCANCODE_I) INPUT_KEYBOARD_ASSIGN(INPUT_ROLE_LEVEL_SKIP_CHEAT, SDL_SCANCODE_L) INPUT_KEYBOARD_ASSIGN(INPUT_ROLE_TURBO_CHEAT, SDL_SCANCODE_TAB) -INPUT_KEYBOARD_ASSIGN(INPUT_ROLE_PAUSE, SDL_SCANCODE_P) +INPUT_KEYBOARD_ASSIGN(INPUT_ROLE_CAMERA_UP, SDL_SCANCODE_Q) +INPUT_KEYBOARD_ASSIGN(INPUT_ROLE_CAMERA_DOWN, SDL_SCANCODE_E) INPUT_KEYBOARD_ASSIGN(INPUT_ROLE_CAMERA_FORWARD, SDL_SCANCODE_W) INPUT_KEYBOARD_ASSIGN(INPUT_ROLE_CAMERA_BACK, SDL_SCANCODE_S) INPUT_KEYBOARD_ASSIGN(INPUT_ROLE_CAMERA_LEFT, SDL_SCANCODE_A) INPUT_KEYBOARD_ASSIGN(INPUT_ROLE_CAMERA_RIGHT, SDL_SCANCODE_D) +INPUT_KEYBOARD_ASSIGN(INPUT_ROLE_CHANGE_TARGET, SDL_SCANCODE_Z) + INPUT_KEYBOARD_ASSIGN(INPUT_ROLE_EQUIP_PISTOLS, SDL_SCANCODE_1) INPUT_KEYBOARD_ASSIGN(INPUT_ROLE_EQUIP_SHOTGUN, SDL_SCANCODE_2) INPUT_KEYBOARD_ASSIGN(INPUT_ROLE_EQUIP_MAGNUMS, SDL_SCANCODE_3) INPUT_KEYBOARD_ASSIGN(INPUT_ROLE_EQUIP_UZIS, SDL_SCANCODE_4) INPUT_KEYBOARD_ASSIGN(INPUT_ROLE_USE_SMALL_MEDI, SDL_SCANCODE_8) INPUT_KEYBOARD_ASSIGN(INPUT_ROLE_USE_BIG_MEDI, SDL_SCANCODE_9) -INPUT_KEYBOARD_ASSIGN(INPUT_ROLE_SAVE, SDL_SCANCODE_F5) -INPUT_KEYBOARD_ASSIGN(INPUT_ROLE_LOAD, SDL_SCANCODE_F6) + INPUT_KEYBOARD_ASSIGN(INPUT_ROLE_FPS, SDL_SCANCODE_F2) INPUT_KEYBOARD_ASSIGN(INPUT_ROLE_BILINEAR, SDL_SCANCODE_F3) -INPUT_KEYBOARD_ASSIGN(INPUT_ROLE_ENTER_CONSOLE, SDL_SCANCODE_SLASH) -INPUT_KEYBOARD_ASSIGN(INPUT_ROLE_CHANGE_TARGET, SDL_SCANCODE_Z) INPUT_KEYBOARD_ASSIGN(INPUT_ROLE_TOGGLE_UI, SDL_SCANCODE_H) -INPUT_KEYBOARD_ASSIGN(INPUT_ROLE_CAMERA_UP, SDL_SCANCODE_Q) -INPUT_KEYBOARD_ASSIGN(INPUT_ROLE_CAMERA_DOWN, SDL_SCANCODE_E) INPUT_KEYBOARD_ASSIGN(INPUT_ROLE_TOGGLE_PHOTO_MODE, SDL_SCANCODE_F1) INPUT_KEYBOARD_ASSIGN(INPUT_ROLE_UNBIND_KEY, SDL_SCANCODE_BACKSPACE) INPUT_KEYBOARD_ASSIGN(INPUT_ROLE_RESET_BINDINGS, SDL_SCANCODE_R) INPUT_KEYBOARD_ASSIGN(INPUT_ROLE_PERSPECTIVE, SDL_SCANCODE_F4) + +INPUT_KEYBOARD_ASSIGN(INPUT_ROLE_OPTION, SDL_SCANCODE_ESCAPE) +INPUT_KEYBOARD_ASSIGN(INPUT_ROLE_MENU_BACK, SDL_SCANCODE_ESCAPE) +INPUT_KEYBOARD_ASSIGN(INPUT_ROLE_MENU_CONFIRM, SDL_SCANCODE_RETURN) INPUT_KEYBOARD_ASSIGN(INPUT_ROLE_MENU_UP, SDL_SCANCODE_UP) INPUT_KEYBOARD_ASSIGN(INPUT_ROLE_MENU_DOWN, SDL_SCANCODE_DOWN) INPUT_KEYBOARD_ASSIGN(INPUT_ROLE_MENU_LEFT, SDL_SCANCODE_LEFT) INPUT_KEYBOARD_ASSIGN(INPUT_ROLE_MENU_RIGHT, SDL_SCANCODE_RIGHT) -INPUT_KEYBOARD_ASSIGN(INPUT_ROLE_MENU_CONFIRM, SDL_SCANCODE_RETURN) -INPUT_KEYBOARD_ASSIGN(INPUT_ROLE_MENU_BACK, SDL_SCANCODE_ESCAPE) diff --git a/src/libtrx/include/libtrx/game/input/backends/keyboard_tr2.def b/src/libtrx/include/libtrx/game/input/backends/keyboard_tr2.def new file mode 100644 index 0000000000..070c361e90 --- /dev/null +++ b/src/libtrx/include/libtrx/game/input/backends/keyboard_tr2.def @@ -0,0 +1,45 @@ +INPUT_KEYBOARD_ASSIGN(INPUT_ROLE_UP, SDL_SCANCODE_UP) +INPUT_KEYBOARD_ASSIGN(INPUT_ROLE_DOWN, SDL_SCANCODE_DOWN) +INPUT_KEYBOARD_ASSIGN(INPUT_ROLE_LEFT, SDL_SCANCODE_LEFT) +INPUT_KEYBOARD_ASSIGN(INPUT_ROLE_RIGHT, SDL_SCANCODE_RIGHT) +INPUT_KEYBOARD_ASSIGN(INPUT_ROLE_JUMP, SDL_SCANCODE_RALT) +INPUT_KEYBOARD_ASSIGN(INPUT_ROLE_DRAW, SDL_SCANCODE_SPACE) +INPUT_KEYBOARD_ASSIGN(INPUT_ROLE_ACTION, SDL_SCANCODE_RCTRL) +INPUT_KEYBOARD_ASSIGN(INPUT_ROLE_SLOW, SDL_SCANCODE_RSHIFT) +INPUT_KEYBOARD_ASSIGN(INPUT_ROLE_LOOK, SDL_SCANCODE_KP_0) +INPUT_KEYBOARD_ASSIGN(INPUT_ROLE_STEP_L, SDL_SCANCODE_DELETE) +INPUT_KEYBOARD_ASSIGN(INPUT_ROLE_STEP_R, SDL_SCANCODE_PAGEDOWN) +INPUT_KEYBOARD_ASSIGN(INPUT_ROLE_ROLL, SDL_SCANCODE_END) + +INPUT_KEYBOARD_ASSIGN(INPUT_ROLE_ENTER_CONSOLE, SDL_SCANCODE_SLASH) +INPUT_KEYBOARD_ASSIGN(INPUT_ROLE_SAVE, SDL_SCANCODE_F5) +INPUT_KEYBOARD_ASSIGN(INPUT_ROLE_LOAD, SDL_SCANCODE_F6) + +INPUT_KEYBOARD_ASSIGN(INPUT_ROLE_EQUIP_PISTOLS, SDL_SCANCODE_1) +INPUT_KEYBOARD_ASSIGN(INPUT_ROLE_EQUIP_SHOTGUN, SDL_SCANCODE_2) +INPUT_KEYBOARD_ASSIGN(INPUT_ROLE_EQUIP_MAGNUMS, SDL_SCANCODE_3) +INPUT_KEYBOARD_ASSIGN(INPUT_ROLE_EQUIP_UZIS, SDL_SCANCODE_4) +INPUT_KEYBOARD_ASSIGN(INPUT_ROLE_EQUIP_HARPOON, SDL_SCANCODE_5) +INPUT_KEYBOARD_ASSIGN(INPUT_ROLE_EQUIP_M16, SDL_SCANCODE_6) +INPUT_KEYBOARD_ASSIGN(INPUT_ROLE_EQUIP_GRENADE_LAUNCHER, SDL_SCANCODE_7) +INPUT_KEYBOARD_ASSIGN(INPUT_ROLE_USE_SMALL_MEDI, SDL_SCANCODE_8) +INPUT_KEYBOARD_ASSIGN(INPUT_ROLE_USE_BIG_MEDI, SDL_SCANCODE_9) +INPUT_KEYBOARD_ASSIGN(INPUT_ROLE_USE_FLARE, SDL_SCANCODE_COMMA) + +INPUT_KEYBOARD_ASSIGN(INPUT_ROLE_SCREENSHOT, SDL_SCANCODE_PRINTSCREEN) +INPUT_KEYBOARD_ASSIGN(INPUT_ROLE_SWITCH_RESOLUTION, SDL_SCANCODE_F1) +INPUT_KEYBOARD_ASSIGN(INPUT_ROLE_SWITCH_INTERNAL_SCREEN_SIZE, SDL_SCANCODE_F2) +INPUT_KEYBOARD_ASSIGN(INPUT_ROLE_TOGGLE_BILINEAR_FILTER, SDL_SCANCODE_F3) +INPUT_KEYBOARD_ASSIGN(INPUT_ROLE_TOGGLE_PERSPECTIVE_FILTER, SDL_SCANCODE_F4) +INPUT_KEYBOARD_ASSIGN(INPUT_ROLE_TOGGLE_Z_BUFFER, SDL_SCANCODE_F7) +INPUT_KEYBOARD_ASSIGN(INPUT_ROLE_TOGGLE_DITHER, SDL_SCANCODE_UNKNOWN) +INPUT_KEYBOARD_ASSIGN(INPUT_ROLE_TOGGLE_FULLSCREEN, SDL_SCANCODE_UNKNOWN) +INPUT_KEYBOARD_ASSIGN(INPUT_ROLE_TOGGLE_RENDERING_MODE, SDL_SCANCODE_F12) + +INPUT_KEYBOARD_ASSIGN(INPUT_ROLE_OPTION, SDL_SCANCODE_ESCAPE) +INPUT_KEYBOARD_ASSIGN(INPUT_ROLE_MENU_BACK, SDL_SCANCODE_ESCAPE) +INPUT_KEYBOARD_ASSIGN(INPUT_ROLE_MENU_CONFIRM, SDL_SCANCODE_RETURN) +INPUT_KEYBOARD_ASSIGN(INPUT_ROLE_MENU_UP, SDL_SCANCODE_UP) +INPUT_KEYBOARD_ASSIGN(INPUT_ROLE_MENU_DOWN, SDL_SCANCODE_DOWN) +INPUT_KEYBOARD_ASSIGN(INPUT_ROLE_MENU_LEFT, SDL_SCANCODE_LEFT) +INPUT_KEYBOARD_ASSIGN(INPUT_ROLE_MENU_RIGHT, SDL_SCANCODE_RIGHT) diff --git a/src/tr1/game/input/common.h b/src/libtrx/include/libtrx/game/input/common.h similarity index 95% rename from src/tr1/game/input/common.h rename to src/libtrx/include/libtrx/game/input/common.h index 3899c6439f..ec5e1f5833 100644 --- a/src/tr1/game/input/common.h +++ b/src/libtrx/include/libtrx/game/input/common.h @@ -1,9 +1,8 @@ #pragma once -#include "game/input/role.h" -#include "game/input/state.h" - -#include +#include "../../json.h" +#include "role.h" +#include "state.h" #include #include @@ -74,6 +73,9 @@ void Input_EnterListenMode(void); // Enables updating g_Input. void Input_ExitListenMode(void); +// Checks whether updates are disabled. +bool Input_IsInListenMode(void); + // Restores the user configuration by converting the JSON object back into the // original input layout. bool Input_AssignFromJSONObject( diff --git a/src/libtrx/include/libtrx/game/input/role.h b/src/libtrx/include/libtrx/game/input/role.h new file mode 100644 index 0000000000..bcbf948070 --- /dev/null +++ b/src/libtrx/include/libtrx/game/input/role.h @@ -0,0 +1,99 @@ +#pragma once + +typedef enum { +// clang-format off +#if TR_VERSION == 1 + INPUT_ROLE_UP = 0, + INPUT_ROLE_DOWN = 1, + INPUT_ROLE_LEFT = 2, + INPUT_ROLE_RIGHT = 3, + INPUT_ROLE_STEP_L = 4, + INPUT_ROLE_STEP_R = 5, + INPUT_ROLE_SLOW = 6, + INPUT_ROLE_JUMP = 7, + INPUT_ROLE_ACTION = 8, + INPUT_ROLE_DRAW = 9, + INPUT_ROLE_LOOK = 10, + INPUT_ROLE_ROLL = 11, + INPUT_ROLE_OPTION = 12, + INPUT_ROLE_FLY_CHEAT = 13, + INPUT_ROLE_ITEM_CHEAT = 14, + INPUT_ROLE_LEVEL_SKIP_CHEAT = 15, + INPUT_ROLE_TURBO_CHEAT = 16, + INPUT_ROLE_PAUSE = 17, + INPUT_ROLE_CAMERA_FORWARD = 18, + INPUT_ROLE_CAMERA_BACK = 19, + INPUT_ROLE_CAMERA_LEFT = 20, + INPUT_ROLE_CAMERA_RIGHT = 21, + INPUT_ROLE_CAMERA_RESET = 22, + INPUT_ROLE_EQUIP_PISTOLS = 23, + INPUT_ROLE_EQUIP_SHOTGUN = 24, + INPUT_ROLE_EQUIP_MAGNUMS = 25, + INPUT_ROLE_EQUIP_UZIS = 26, + INPUT_ROLE_USE_SMALL_MEDI = 27, + INPUT_ROLE_USE_BIG_MEDI = 28, + INPUT_ROLE_SAVE = 29, + INPUT_ROLE_LOAD = 30, + INPUT_ROLE_FPS = 31, + INPUT_ROLE_BILINEAR = 32, + INPUT_ROLE_ENTER_CONSOLE = 33, + INPUT_ROLE_CHANGE_TARGET = 34, + INPUT_ROLE_TOGGLE_UI = 35, + INPUT_ROLE_CAMERA_UP = 36, + INPUT_ROLE_CAMERA_DOWN = 37, + INPUT_ROLE_TOGGLE_PHOTO_MODE = 38, + INPUT_ROLE_UNBIND_KEY = 39, + INPUT_ROLE_RESET_BINDINGS = 40, + INPUT_ROLE_PERSPECTIVE = 42, + INPUT_ROLE_MENU_CONFIRM = 43, + INPUT_ROLE_MENU_BACK = 44, + INPUT_ROLE_MENU_LEFT = 45, + INPUT_ROLE_MENU_UP = 46, + INPUT_ROLE_MENU_DOWN = 47, + INPUT_ROLE_MENU_RIGHT = 48, +#elif TR_VERSION == 2 + INPUT_ROLE_UP = 0, + INPUT_ROLE_DOWN = 1, + INPUT_ROLE_LEFT = 2, + INPUT_ROLE_RIGHT = 3, + INPUT_ROLE_STEP_L = 4, + INPUT_ROLE_STEP_R = 5, + INPUT_ROLE_SLOW = 6, + INPUT_ROLE_JUMP = 7, + INPUT_ROLE_ACTION = 8, + INPUT_ROLE_DRAW = 9, + INPUT_ROLE_USE_FLARE = 10, + INPUT_ROLE_LOOK = 11, + INPUT_ROLE_ROLL = 12, + INPUT_ROLE_OPTION = 13, + INPUT_ROLE_ENTER_CONSOLE = 14, + INPUT_ROLE_MENU_CONFIRM = 15, + INPUT_ROLE_MENU_BACK = 16, + INPUT_ROLE_MENU_LEFT = 17, + INPUT_ROLE_MENU_UP = 18, + INPUT_ROLE_MENU_DOWN = 19, + INPUT_ROLE_MENU_RIGHT = 20, + INPUT_ROLE_SCREENSHOT = 21, + INPUT_ROLE_EQUIP_PISTOLS = 22, + INPUT_ROLE_EQUIP_SHOTGUN = 23, + INPUT_ROLE_EQUIP_MAGNUMS = 24, + INPUT_ROLE_EQUIP_UZIS = 25, + INPUT_ROLE_EQUIP_HARPOON = 26, + INPUT_ROLE_EQUIP_M16 = 27, + INPUT_ROLE_EQUIP_GRENADE_LAUNCHER = 28, + INPUT_ROLE_USE_SMALL_MEDI = 29, + INPUT_ROLE_USE_BIG_MEDI = 30, + INPUT_ROLE_SAVE = 31, + INPUT_ROLE_LOAD = 32, + INPUT_ROLE_SWITCH_RESOLUTION = 33, + INPUT_ROLE_SWITCH_INTERNAL_SCREEN_SIZE = 34, + INPUT_ROLE_TOGGLE_BILINEAR_FILTER = 35, + INPUT_ROLE_TOGGLE_PERSPECTIVE_FILTER = 36, + INPUT_ROLE_TOGGLE_Z_BUFFER = 37, + INPUT_ROLE_TOGGLE_DITHER = 38, + INPUT_ROLE_TOGGLE_FULLSCREEN = 39, + INPUT_ROLE_TOGGLE_RENDERING_MODE = 40, +#endif + INPUT_ROLE_NUMBER_OF, + // clang-format on +} INPUT_ROLE; diff --git a/src/tr1/game/input/state.h b/src/libtrx/include/libtrx/game/input/state.h similarity index 71% rename from src/tr1/game/input/state.h rename to src/libtrx/include/libtrx/game/input/state.h index 8d2e4f2cfb..2ecc70fde2 100644 --- a/src/tr1/game/input/state.h +++ b/src/libtrx/include/libtrx/game/input/state.h @@ -13,14 +13,17 @@ typedef union INPUT_STATE { uint64_t draw : 1; uint64_t action : 1; uint64_t slow : 1; - uint64_t option : 1; uint64_t look : 1; uint64_t step_left : 1; uint64_t step_right : 1; uint64_t roll : 1; + uint64_t pause : 1; + uint64_t enter_console : 1; uint64_t save : 1; uint64_t load : 1; + +#if TR_VERSION == 1 uint64_t fly_cheat : 1; uint64_t item_cheat : 1; uint64_t level_skip_cheat : 1; @@ -32,24 +35,48 @@ typedef union INPUT_STATE { uint64_t camera_left : 1; uint64_t camera_right : 1; uint64_t camera_reset : 1; + uint64_t change_target : 1; +#endif + uint64_t equip_pistols : 1; uint64_t equip_shotgun : 1; uint64_t equip_magnums : 1; uint64_t equip_uzis : 1; +#if TR_VERSION == 2 + uint64_t equip_harpoon : 1; + uint64_t equip_m16 : 1; + uint64_t equip_grenade_launcher : 1; +#endif uint64_t use_small_medi : 1; uint64_t use_big_medi : 1; +#if TR_VERSION == 2 + uint64_t use_flare : 1; +#endif + +#if TR_VERSION == 1 uint64_t toggle_bilinear_filter : 1; uint64_t toggle_perspective_filter : 1; uint64_t toggle_fps_counter : 1; + uint64_t toggle_ui : 1; + uint64_t toggle_photo_mode : 1; +#elif TR_VERSION == 2 + uint64_t screenshot : 1; + uint64_t switch_resolution : 1; + uint64_t switch_internal_screen_size : 1; + uint64_t toggle_bilinear_filter : 1; + uint64_t toggle_perspective_filter : 1; + uint64_t toggle_z_buffer : 1; + uint64_t toggle_dither : 1; + uint64_t toggle_fullscreen : 1; + uint64_t toggle_rendering_mode : 1; +#endif + + uint64_t option : 1; + uint64_t menu_back : 1; + uint64_t menu_confirm : 1; uint64_t menu_up : 1; uint64_t menu_down : 1; uint64_t menu_left : 1; uint64_t menu_right : 1; - uint64_t menu_confirm : 1; - uint64_t menu_back : 1; - uint64_t enter_console : 1; - uint64_t change_target : 1; - uint64_t toggle_ui : 1; - uint64_t toggle_photo_mode : 1; }; } INPUT_STATE; diff --git a/src/libtrx/meson.build b/src/libtrx/meson.build index 31939a157e..fa7180ad3a 100644 --- a/src/libtrx/meson.build +++ b/src/libtrx/meson.build @@ -90,6 +90,10 @@ sources = [ 'game/console/common.c', 'game/console/history.c', 'game/game_string.c', + 'game/input/backends/controller.c', + 'game/input/backends/internal.c', + 'game/input/backends/keyboard.c', + 'game/input/common.c', 'game/items.c', 'game/objects/common.c', 'game/objects/names.c', diff --git a/src/tr1/game/game_string.def b/src/tr1/game/game_string.def index 5e92519b31..6128011030 100644 --- a/src/tr1/game/game_string.def +++ b/src/tr1/game/game_string.def @@ -44,10 +44,6 @@ GS_DEFINE(SOUND_SET_VOLUMES, "Set Volumes") GS_DEFINE(CONTROL_CUSTOMIZE, "Customize Controls") GS_DEFINE(CONTROL_KEYBOARD, "Keyboard") GS_DEFINE(CONTROL_CONTROLLER, "Controller") -GS_DEFINE(CONTROL_DEFAULT_KEYS, "Default Keys") -GS_DEFINE(CONTROL_CUSTOM_1, "Custom Scheme 1") -GS_DEFINE(CONTROL_CUSTOM_2, "Custom Scheme 2") -GS_DEFINE(CONTROL_CUSTOM_3, "Custom Scheme 3") GS_DEFINE(CONTROL_RESET_DEFAULTS, "Reset All: Hold %s") GS_DEFINE(CONTROL_UNBIND, "Unbind: Hold %s") GS_DEFINE(KEYMAP_RUN, "Run") diff --git a/src/tr1/game/input/common.c b/src/tr1/game/input.c similarity index 63% rename from src/tr1/game/input/common.c rename to src/tr1/game/input.c index 2dd53101e5..1bcf0b4e14 100644 --- a/src/tr1/game/input/common.c +++ b/src/tr1/game/input.c @@ -1,33 +1,20 @@ -#include "game/input/common.h" +#include "game/input.h" #include "config.h" #include "game/clock.h" -#include "game/game_string.h" -#include "game/input/backends/controller.h" -#include "game/input/backends/keyboard.h" #include "global/vars.h" -#include +#include +#include +#include #define DELAY_FRAMES 12 #define HOLD_FRAMES 3 -INPUT_STATE g_Input = { 0 }; -INPUT_STATE g_InputDB = { 0 }; -INPUT_STATE g_OldInputDB = { 0 }; - static int32_t m_HoldBack = 0; static int32_t m_HoldForward = 0; -static bool m_ListenMode = false; -static const GAME_STRING_ID m_LayoutMap[INPUT_LAYOUT_NUMBER_OF] = { - [INPUT_LAYOUT_DEFAULT] = GS_ID(CONTROL_DEFAULT_KEYS), - [INPUT_LAYOUT_CUSTOM_1] = GS_ID(CONTROL_CUSTOM_1), - [INPUT_LAYOUT_CUSTOM_2] = GS_ID(CONTROL_CUSTOM_2), - [INPUT_LAYOUT_CUSTOM_3] = GS_ID(CONTROL_CUSTOM_3), -}; static INPUT_STATE M_GetDebounced(INPUT_STATE input); -static INPUT_BACKEND_IMPL *M_GetBackend(INPUT_BACKEND backend); static void M_UpdateFromBackend( INPUT_STATE *s, const INPUT_BACKEND_IMPL *backend, int32_t layout); @@ -63,17 +50,6 @@ static INPUT_STATE M_GetDebounced(const INPUT_STATE input) return result; } -static INPUT_BACKEND_IMPL *M_GetBackend(const INPUT_BACKEND backend) -{ - switch (backend) { - case INPUT_BACKEND_KEYBOARD: - return &g_Input_Keyboard; - case INPUT_BACKEND_CONTROLLER: - return &g_Input_Controller; - } - return NULL; -} - static void M_UpdateFromBackend( INPUT_STATE *const s, const INPUT_BACKEND_IMPL *const backend, const int32_t layout) @@ -91,7 +67,7 @@ static void M_UpdateFromBackend( s->draw |= backend->is_pressed(layout, INPUT_ROLE_DRAW); s->look |= backend->is_pressed(layout, INPUT_ROLE_LOOK); s->roll |= backend->is_pressed(layout, INPUT_ROLE_ROLL); - s->option |= backend->is_pressed(layout, INPUT_ROLE_OPTION); + s->pause |= backend->is_pressed(layout, INPUT_ROLE_PAUSE); s->toggle_photo_mode |= backend->is_pressed(layout, INPUT_ROLE_TOGGLE_PHOTO_MODE); s->camera_up |= backend->is_pressed(layout, INPUT_ROLE_CAMERA_UP); @@ -115,6 +91,7 @@ static void M_UpdateFromBackend( s->use_small_medi |= backend->is_pressed(layout, INPUT_ROLE_USE_SMALL_MEDI); s->use_big_medi |= backend->is_pressed(layout, INPUT_ROLE_USE_BIG_MEDI); + s->option |= backend->is_pressed(layout, INPUT_ROLE_OPTION); s->menu_up |= backend->is_pressed(layout, INPUT_ROLE_MENU_UP); s->menu_down |= backend->is_pressed(layout, INPUT_ROLE_MENU_DOWN); s->menu_left |= backend->is_pressed(layout, INPUT_ROLE_MENU_LEFT); @@ -134,49 +111,6 @@ static void M_UpdateFromBackend( backend->custom_update(s, layout); } -void Input_Init(void) -{ - if (g_Input_Keyboard.init != NULL) { - g_Input_Keyboard.init(); - } - if (g_Input_Controller.init != NULL) { - g_Input_Controller.init(); - } -} - -void Input_Shutdown(void) -{ - if (g_Input_Keyboard.shutdown != NULL) { - g_Input_Keyboard.shutdown(); - } - if (g_Input_Controller.shutdown != NULL) { - g_Input_Controller.shutdown(); - } -} - -void Input_InitController(void) -{ - if (g_Input_Controller.init != NULL) { - g_Input_Controller.init(); - } -} - -void Input_ShutdownController(void) -{ - if (g_Input_Controller.shutdown != NULL) { - g_Input_Controller.shutdown(); - } -} - -bool Input_IsRoleRebindable(const INPUT_ROLE role) -{ - return role != INPUT_ROLE_UNBIND_KEY && role != INPUT_ROLE_RESET_BINDINGS - && role != INPUT_ROLE_PERSPECTIVE && role != INPUT_ROLE_MENU_CONFIRM - && role != INPUT_ROLE_MENU_BACK && role != INPUT_ROLE_MENU_LEFT - && role != INPUT_ROLE_MENU_RIGHT && role != INPUT_ROLE_MENU_UP - && role != INPUT_ROLE_MENU_DOWN; -} - void Input_Update(void) { g_Input.any = 0; @@ -224,80 +158,8 @@ void Input_Update(void) g_InputDB = M_GetDebounced(g_Input); - if (m_ListenMode) { - g_Input = (INPUT_STATE) { 0 }; - g_InputDB = (INPUT_STATE) { 0 }; + if (Input_IsInListenMode()) { + g_Input.any = 0; + g_InputDB.any = 0; } } - -bool Input_IsPressed( - const INPUT_BACKEND backend, const INPUT_LAYOUT layout, - const INPUT_ROLE role) -{ - return M_GetBackend(backend)->is_pressed(layout, role); -} - -bool Input_IsKeyConflicted( - const INPUT_BACKEND backend, const INPUT_LAYOUT layout, - const INPUT_ROLE role) -{ - return M_GetBackend(backend)->is_role_conflicted(layout, role); -} - -bool Input_ReadAndAssignRole( - const INPUT_BACKEND backend, const INPUT_LAYOUT layout, - const INPUT_ROLE role) -{ - return M_GetBackend(backend)->read_and_assign(layout, role); -} - -void Input_UnassignRole( - const INPUT_BACKEND backend, const INPUT_LAYOUT layout, - const INPUT_ROLE role) -{ - M_GetBackend(backend)->unassign_role(layout, role); -} - -const char *Input_GetLayoutName(const INPUT_LAYOUT layout) -{ - return GameString_Get(m_LayoutMap[layout]); -} - -const char *Input_GetKeyName( - const INPUT_BACKEND backend, const INPUT_LAYOUT layout, - const INPUT_ROLE role) -{ - return M_GetBackend(backend)->get_name(layout, role); -} - -void Input_ResetLayout(const INPUT_BACKEND backend, const INPUT_LAYOUT layout) -{ - return M_GetBackend(backend)->reset_layout(layout); -} - -void Input_EnterListenMode(void) -{ - m_ListenMode = true; -} - -void Input_ExitListenMode(void) -{ - m_ListenMode = false; - Input_Update(); - g_OldInputDB.any = g_Input.any; - g_InputDB.any = g_Input.any; -} - -bool Input_AssignFromJSONObject( - const INPUT_BACKEND backend, const INPUT_LAYOUT layout, - JSON_OBJECT *const bind_obj) -{ - return M_GetBackend(backend)->assign_from_json_object(layout, bind_obj); -} - -bool Input_AssignToJSONObject( - const INPUT_BACKEND backend, const INPUT_LAYOUT layout, - JSON_OBJECT *const bind_obj, const INPUT_ROLE role) -{ - return M_GetBackend(backend)->assign_to_json_object(layout, bind_obj, role); -} diff --git a/src/tr1/game/input.h b/src/tr1/game/input.h index 0a971adf34..6f2d02c9ba 100644 --- a/src/tr1/game/input.h +++ b/src/tr1/game/input.h @@ -1,3 +1,3 @@ #pragma once -#include "game/input/common.h" +#include diff --git a/src/tr1/game/input/role.h b/src/tr1/game/input/role.h deleted file mode 100644 index 6454f07fc5..0000000000 --- a/src/tr1/game/input/role.h +++ /dev/null @@ -1,55 +0,0 @@ -#pragma once - -typedef enum { - // clang-format off - INPUT_ROLE_UP = 0, - INPUT_ROLE_DOWN = 1, - INPUT_ROLE_LEFT = 2, - INPUT_ROLE_RIGHT = 3, - INPUT_ROLE_STEP_L = 4, - INPUT_ROLE_STEP_R = 5, - INPUT_ROLE_SLOW = 6, - INPUT_ROLE_JUMP = 7, - INPUT_ROLE_ACTION = 8, - INPUT_ROLE_DRAW = 9, - INPUT_ROLE_LOOK = 10, - INPUT_ROLE_ROLL = 11, - INPUT_ROLE_OPTION = 12, - INPUT_ROLE_FLY_CHEAT = 13, - INPUT_ROLE_ITEM_CHEAT = 14, - INPUT_ROLE_LEVEL_SKIP_CHEAT = 15, - INPUT_ROLE_TURBO_CHEAT = 16, - INPUT_ROLE_PAUSE = 17, - INPUT_ROLE_CAMERA_FORWARD = 18, - INPUT_ROLE_CAMERA_BACK = 19, - INPUT_ROLE_CAMERA_LEFT = 20, - INPUT_ROLE_CAMERA_RIGHT = 21, - INPUT_ROLE_CAMERA_RESET = 22, - INPUT_ROLE_EQUIP_PISTOLS = 23, - INPUT_ROLE_EQUIP_SHOTGUN = 24, - INPUT_ROLE_EQUIP_MAGNUMS = 25, - INPUT_ROLE_EQUIP_UZIS = 26, - INPUT_ROLE_USE_SMALL_MEDI = 27, - INPUT_ROLE_USE_BIG_MEDI = 28, - INPUT_ROLE_SAVE = 29, - INPUT_ROLE_LOAD = 30, - INPUT_ROLE_FPS = 31, - INPUT_ROLE_BILINEAR = 32, - INPUT_ROLE_ENTER_CONSOLE = 33, - INPUT_ROLE_CHANGE_TARGET = 34, - INPUT_ROLE_TOGGLE_UI = 35, - INPUT_ROLE_CAMERA_UP = 36, - INPUT_ROLE_CAMERA_DOWN = 37, - INPUT_ROLE_TOGGLE_PHOTO_MODE = 38, - INPUT_ROLE_UNBIND_KEY = 39, - INPUT_ROLE_RESET_BINDINGS = 40, - INPUT_ROLE_PERSPECTIVE = 42, - INPUT_ROLE_MENU_CONFIRM = 43, - INPUT_ROLE_MENU_BACK = 44, - INPUT_ROLE_MENU_LEFT = 45, - INPUT_ROLE_MENU_UP = 46, - INPUT_ROLE_MENU_DOWN = 47, - INPUT_ROLE_MENU_RIGHT = 48, - INPUT_ROLE_NUMBER_OF, - // clang-format on -} INPUT_ROLE; diff --git a/src/tr1/meson.build b/src/tr1/meson.build index 5497e2d4fd..fc15c295ef 100644 --- a/src/tr1/meson.build +++ b/src/tr1/meson.build @@ -139,10 +139,7 @@ sources = [ 'game/gun/gun_pistols.c', 'game/gun/gun_rifle.c', 'game/inject.c', - 'game/input/backends/controller.c', - 'game/input/backends/internal.c', - 'game/input/backends/keyboard.c', - 'game/input/common.c', + 'game/input.c', 'game/interpolation.c', 'game/inventory/inventory.c', 'game/inventory/inventory_func.c', diff --git a/src/tr2/config.c b/src/tr2/config.c index f24bf7326c..4e6d248303 100644 --- a/src/tr2/config.c +++ b/src/tr2/config.c @@ -1,13 +1,105 @@ #include "config.h" #include "config_map.h" +#include "game/input.h" #include +#include +#include + CONFIG g_Config = { 0 }; static const char *m_ConfigPath = "cfg/TR2X.json5"; +static void M_LoadInputConfig(JSON_OBJECT *root_obj); +static void M_LoadInputLayout( + JSON_OBJECT *parent_obj, INPUT_BACKEND backend, INPUT_LAYOUT layout); +static void M_DumpInputConfig(JSON_OBJECT *root_obj); +static void M_DumpInputLayout( + JSON_OBJECT *parent_obj, INPUT_BACKEND backend, INPUT_LAYOUT layout); + +static void M_LoadInputConfig(JSON_OBJECT *const root_obj) +{ + JSON_OBJECT *const input_obj = JSON_ObjectGetObject(root_obj, "input"); + if (input_obj == NULL) { + return; + } + + JSON_OBJECT *const keyboard_obj = + JSON_ObjectGetObject(input_obj, "keyboard"); + JSON_OBJECT *const controller_obj = + JSON_ObjectGetObject(input_obj, "controller"); + for (INPUT_LAYOUT layout = INPUT_LAYOUT_CUSTOM_1; + layout < INPUT_LAYOUT_NUMBER_OF; layout++) { + if (keyboard_obj != NULL) { + M_LoadInputLayout(keyboard_obj, INPUT_BACKEND_KEYBOARD, layout); + } + if (controller_obj != NULL) { + M_LoadInputLayout(controller_obj, INPUT_BACKEND_CONTROLLER, layout); + } + } +} + +static void M_LoadInputLayout( + JSON_OBJECT *const parent_obj, const INPUT_BACKEND backend, + const INPUT_LAYOUT layout) +{ + char layout_name[20]; + sprintf(layout_name, "layout_%d", layout); + JSON_ARRAY *const arr = JSON_ObjectGetArray(parent_obj, layout_name); + if (arr == NULL) { + return; + } + + for (size_t i = 0; i < arr->length; i++) { + JSON_OBJECT *const bind_obj = JSON_ArrayGetObject(arr, i); + assert(bind_obj != NULL); + Input_AssignFromJSONObject(backend, layout, bind_obj); + } +} + +static void M_DumpInputConfig(JSON_OBJECT *const root_obj) +{ + JSON_OBJECT *const input_obj = JSON_ObjectNew(); + JSON_OBJECT *const keyboard_obj = JSON_ObjectNew(); + JSON_OBJECT *const controller_obj = JSON_ObjectNew(); + JSON_ObjectAppendObject(root_obj, "input", input_obj); + JSON_ObjectAppendObject(input_obj, "keyboard", keyboard_obj); + JSON_ObjectAppendObject(input_obj, "controller", controller_obj); + for (INPUT_LAYOUT layout = INPUT_LAYOUT_CUSTOM_1; + layout < INPUT_LAYOUT_NUMBER_OF; layout++) { + M_DumpInputLayout(keyboard_obj, INPUT_BACKEND_KEYBOARD, layout); + M_DumpInputLayout(controller_obj, INPUT_BACKEND_CONTROLLER, layout); + } +} + +static void M_DumpInputLayout( + JSON_OBJECT *const parent_obj, const INPUT_BACKEND backend, + const INPUT_LAYOUT layout) +{ + JSON_ARRAY *const arr = JSON_ArrayNew(); + + bool has_elements = false; + for (INPUT_ROLE role = 0; role < INPUT_ROLE_NUMBER_OF; role++) { + JSON_OBJECT *const bind_obj = JSON_ObjectNew(); + if (Input_AssignToJSONObject(backend, layout, bind_obj, role)) { + has_elements = true; + JSON_ArrayAppendObject(arr, bind_obj); + } else { + JSON_ObjectFree(bind_obj); + } + } + + if (has_elements) { + char layout_name[20]; + sprintf(layout_name, "layout_%d", layout); + JSON_ObjectAppendArray(parent_obj, layout_name, arr); + } else { + JSON_ArrayFree(arr); + } +} + const char *Config_GetPath(void) { return m_ConfigPath; @@ -16,11 +108,13 @@ const char *Config_GetPath(void) void Config_LoadFromJSON(JSON_OBJECT *root_obj) { ConfigFile_LoadOptions(root_obj, g_ConfigOptionMap); + M_LoadInputConfig(root_obj); } void Config_DumpToJSON(JSON_OBJECT *root_obj) { ConfigFile_DumpOptions(root_obj, g_ConfigOptionMap); + M_DumpInputConfig(root_obj); } void Config_Sanitize(void) diff --git a/src/tr2/config.h b/src/tr2/config.h index b8b244920b..c3302c164e 100644 --- a/src/tr2/config.h +++ b/src/tr2/config.h @@ -8,6 +8,11 @@ typedef struct { bool loaded; + struct { + int32_t keyboard_layout; + int32_t controller_layout; + } input; + struct { bool fix_m16_accuracy; } gameplay; diff --git a/src/tr2/config_map.c b/src/tr2/config_map.c index 82a3299d2b..954102af9a 100644 --- a/src/tr2/config_map.c +++ b/src/tr2/config_map.c @@ -6,6 +6,7 @@ #include // import order guard +#include "game/input.h" #include "global/types.h" const CONFIG_OPTION g_ConfigOptionMap[] = { diff --git a/src/tr2/config_map.def b/src/tr2/config_map.def index addba8f0fc..270ded5973 100644 --- a/src/tr2/config_map.def +++ b/src/tr2/config_map.def @@ -1,2 +1,4 @@ CFG_BOOL(g_Config, gameplay.fix_m16_accuracy, true) CFG_ENUM(g_Config, rendering.screenshot_format, SCREENSHOT_FORMAT_JPEG, SCREENSHOT_FORMAT) +CFG_INT32(g_Config, input.keyboard_layout, INPUT_LAYOUT_DEFAULT) +CFG_INT32(g_Config, input.controller_layout, INPUT_LAYOUT_DEFAULT) diff --git a/src/tr2/decomp/decomp.c b/src/tr2/decomp/decomp.c index f70e22d5ae..a7c51786e5 100644 --- a/src/tr2/decomp/decomp.c +++ b/src/tr2/decomp/decomp.c @@ -29,7 +29,6 @@ #include "global/funcs.h" #include "global/vars.h" #include "lib/ddraw.h" -#include "lib/dinput.h" #include "specific/s_flagged_string.h" #include @@ -39,8 +38,8 @@ #include #include +#include #include -#include #include #define IDI_MAINICON 100 @@ -193,12 +192,10 @@ int32_t __cdecl GameInit(void) Music_Shutdown(); UT_InitAccurateTimer(); // clang-format off - Sound_Init(); return WinVidInit() && Direct3DInit() && RenderInit() && InitTextures() - && WinInputInit() && TIME_Init() && HWR_Init() && BGND_Init(); @@ -280,31 +277,15 @@ int32_t __cdecl RenderErrorBox(int32_t error_code) bool __cdecl DInputCreate(void) { - return SUCCEEDED(DirectInputCreate(g_GameModule, 1280, &g_DInput, NULL)); + return true; } void __cdecl DInputRelease(void) { - if (g_DInput) { - IDirectInput_Release(g_DInput); - g_DInput = NULL; - } } void __cdecl WinInReadKeyboard(uint8_t *input_data) { - if (SUCCEEDED(IDirectInputDevice_GetDeviceState( - IDID_SysKeyboard, 256, input_data))) { - return; - } - - if (SUCCEEDED(IDirectInputDevice_Acquire(IDID_SysKeyboard)) - && SUCCEEDED(IDirectInputDevice_GetDeviceState( - IDID_SysKeyboard, 256, input_data))) { - return; - } - - memset(input_data, 0, 256); } int32_t __cdecl WinGameStart(void) @@ -312,7 +293,6 @@ int32_t __cdecl WinGameStart(void) // try { WinVidStart(); RenderStart(true); - WinInStart(); // } catch (int32_t error) { // return error; // } @@ -963,15 +943,14 @@ int32_t __cdecl Game_Cutscene_Control(const int32_t nframes) return 4; } - if (Input_Update()) { - return 3; - } + Input_Update(); if (g_InputDB.action) { return 1; } if (g_InputDB.option) { return 2; } + Shell_ProcessInput(); g_DynamicLightCount = 0; @@ -2043,8 +2022,11 @@ bool __cdecl DDrawCreate(LPGUID lpGUID) return false; } - g_DDraw->lpVtbl->SetCooperativeLevel( - g_DDraw, g_GameWindowHandle, DDSCL_NORMAL); + if (FAILED(g_DDraw->lpVtbl->SetCooperativeLevel( + g_DDraw, g_GameWindowHandle, DDSCL_NORMAL))) { + return false; + } + return true; } @@ -2617,6 +2599,19 @@ bool __cdecl WinVidCreateGameWindow(void) return false; } + int32_t result = SDL_Init(SDL_INIT_EVENTS | SDL_INIT_VIDEO); + if (result < 0) { + Shell_ExitSystemFmt( + "Error while calling SDL_Init: 0x%lx, %s", result, SDL_GetError()); + return false; + } + + SDL_Window *sdl_window = SDL_CreateWindowFrom(g_GameWindowHandle); + if (sdl_window == NULL) { + Shell_ExitSystemFmt("Failed to create SDL window: %s", SDL_GetError()); + return false; + } + RECT rect; GetWindowRect(g_GameWindowHandle, &rect); g_GameWindowX = rect.left; @@ -2772,14 +2767,8 @@ void __cdecl S_LoadSettings(void) } GetRegistryFloatValue("Sizer", &g_GameSizerCopy, 1.0); - GetRegistryBinaryValue( - "Layout", (uint8_t *)&g_Layout[1], - sizeof(uint16_t) * INPUT_ROLE_NUMBER_OF, 0); - CloseGameRegistryKey(); - Input_CheckConflictsWithDefaults(); - Sound_SetMasterVolume(6 * g_OptionSoundVolume + 4); if (g_OptionMusicVolume) { @@ -2796,9 +2785,6 @@ void __cdecl S_SaveSettings(void) SetRegistryDwordValue("SoundFxVolume", g_OptionSoundVolume); SetRegistryDwordValue("DetailLevel", g_DetailLevel); SetRegistryFloatValue("Sizer", g_GameSizerCopy); - SetRegistryBinaryValue( - "Layout", (uint8_t *)&g_Layout[1], - sizeof(uint16_t) * INPUT_ROLE_NUMBER_OF); CloseGameRegistryKey(); } @@ -2810,6 +2796,7 @@ void __cdecl S_Wait(int32_t frames, const BOOL input_check) break; } Input_Update(); + Shell_ProcessInput(); int32_t passed; do { @@ -2821,6 +2808,7 @@ void __cdecl S_Wait(int32_t frames, const BOOL input_check) while (frames > 0) { Input_Update(); + Shell_ProcessInput(); if (input_check && g_Input.any) { break; } diff --git a/src/tr2/decomp/fmv.c b/src/tr2/decomp/fmv.c index 02bb1e485c..6d599adc11 100644 --- a/src/tr2/decomp/fmv.c +++ b/src/tr2/decomp/fmv.c @@ -362,10 +362,8 @@ void __cdecl WinPlayFMV(const char *const file_name, const bool is_playback) WinVidSpinMessageLoop(false); - if (Input_Update()) { - Video_Stop(video); - break; - } + Input_Update(); + Shell_ProcessInput(); if (g_InputDB.option) { Video_Stop(video); break; diff --git a/src/tr2/decomp/stats.c b/src/tr2/decomp/stats.c index c824b46f64..bf7dfc98fa 100644 --- a/src/tr2/decomp/stats.c +++ b/src/tr2/decomp/stats.c @@ -4,6 +4,7 @@ #include "game/music.h" #include "game/overlay.h" #include "game/requester.h" +#include "game/shell.h" #include "game/text.h" #include "global/funcs.h" #include "global/types.h" @@ -315,6 +316,7 @@ int32_t __cdecl LevelStats(const int32_t level_num) while (g_Input.menu_confirm) { Input_Update(); + Shell_ProcessInput(); } while (true) { @@ -322,6 +324,7 @@ int32_t __cdecl LevelStats(const int32_t level_num) S_CopyBufferToScreen(); Input_Update(); + Shell_ProcessInput(); if (g_GF_OverrideDir != (GAME_FLOW_DIR)-1) { break; @@ -361,6 +364,7 @@ int32_t __cdecl GameStats(const int32_t level_num) Overlay_HideGameInfo(); while (g_Input.menu_confirm) { Input_Update(); + Shell_ProcessInput(); } while (true) { @@ -368,6 +372,7 @@ int32_t __cdecl GameStats(const int32_t level_num) S_CopyBufferToScreen(); Input_Update(); + Shell_ProcessInput(); if (g_GF_OverrideDir != (GAME_FLOW_DIR)-1) { break; diff --git a/src/tr2/game/common.c b/src/tr2/game/common.c new file mode 100644 index 0000000000..ec62eb8237 --- /dev/null +++ b/src/tr2/game/common.c @@ -0,0 +1,223 @@ +#include "config.h" +#include "decomp/decomp.h" +#include "game/console/common.h" +#include "game/demo.h" +#include "game/game_string.h" +#include "game/gamebuf.h" +#include "game/gameflow.h" +#include "game/gameflow/reader.h" +#include "game/input.h" +#include "game/music.h" +#include "game/shell.h" +#include "game/sound.h" +#include "game/text.h" +#include "global/funcs.h" +#include "global/vars.h" + +#include +#include +#include + +#include +#include +#include + +#define GAMEBUF_MEM_CAP 0x380000 + +// TODO: refactor the hell out of me +BOOL __cdecl Shell_Main(void) +{ + g_HiRes = 0; + g_ScreenSizer = 0; + g_GameSizer = 1.0; + g_GameSizerCopy = 1.0; + + GameString_Init(); + EnumMap_Init(); + Config_Init(); + Text_Init(); + UI_Init(); + Console_Init(); + + Sound_Init(); + Music_Init(); + Input_Init(); + + Config_Read(); + if (!S_InitialiseSystem()) { + return false; + } + + if (!GF_LoadScriptFile("data\\tombPC.dat")) { + Shell_ExitSystem("GameMain: could not load script file"); + return false; + } + + if (!GF_N_Load("cfg/TR2X_gameflow.json5")) { + Shell_ExitSystem("GameMain: could not load new script file"); + return false; + } + + InitialiseStartInfo(); + S_FrontEndCheck(); + S_LoadSettings(); + + g_HiRes = -1; + GameBuf_Init(GAMEBUF_MEM_CAP); + g_HiRes = 0; + + TempVideoAdjust(1, 1.0); + + g_IsVidModeLock = 1; + S_DisplayPicture("data\\legal.pcx", 0); + S_InitialisePolyList(0); + S_CopyBufferToScreen(); + S_OutputPolyList(); + S_DumpScreen(); + FadeToPal(30, g_GamePalette8); + S_Wait(180, 1); + S_FadeToBlack(); + S_DontDisplayPicture(); + g_IsVidModeLock = 0; + + const bool is_frontend_fail = GF_DoFrontendSequence(); + if (g_IsGameToExit) { + Config_Write(); + return true; + } + + if (is_frontend_fail) { + strcpy(g_ErrorMessage, "GameMain: failed in GF_DoFrontendSequence()"); + return false; + } + + S_FadeToBlack(); + int16_t gf_option = g_GameFlow.first_option; + g_NoInputCounter = 0; + + bool is_loop_continued = true; + while (is_loop_continued) { + const int16_t gf_dir = gf_option & 0xFF00; + const int16_t gf_param = gf_option & 0x00FF; + + switch (gf_dir) { + case GFD_START_GAME: + if (g_GameFlow.single_level >= 0) { + gf_option = + GF_DoLevelSequence(g_GameFlow.single_level, GFL_NORMAL); + } else { + if (gf_param > g_GameFlow.num_levels) { + sprintf( + g_ErrorMessage, + "GameMain: STARTGAME with invalid level number (%d)", + gf_param); + return false; + } + gf_option = GF_DoLevelSequence(gf_param, GFL_NORMAL); + } + break; + + case GFD_START_SAVED_GAME: + S_LoadGame(&g_SaveGame, sizeof(SAVEGAME_INFO), gf_param); + if (g_SaveGame.current_level > g_GameFlow.num_levels) { + sprintf( + g_ErrorMessage, + "GameMain: STARTSAVEDGAME with invalid level number (%d)", + g_SaveGame.current_level); + return false; + } + gf_option = GF_DoLevelSequence(g_SaveGame.current_level, GFL_SAVED); + break; + + case GFD_START_CINE: + Game_Cutscene_Start(gf_param); + gf_option = GFD_EXIT_TO_TITLE; + break; + + case GFD_START_DEMO: + gf_option = Demo_Control(-1); + break; + + case GFD_LEVEL_COMPLETE: + gf_option = LevelCompleteSequence(); + break; + + case GFD_EXIT_TO_TITLE: + case GFD_EXIT_TO_OPTION: + if (g_GameFlow.title_disabled) { + if (g_GameFlow.title_replace < 0 + || g_GameFlow.title_replace == GFD_EXIT_TO_TITLE) { + strcpy( + g_ErrorMessage, + "GameMain Failed: Title disabled & no replacement"); + return false; + } + gf_option = g_GameFlow.title_replace; + } else { + gf_option = TitleSequence(); + g_GF_StartGame = 1; + } + break; + + default: + is_loop_continued = false; + break; + } + } + + S_SaveSettings(); + GameBuf_Shutdown(); + EnumMap_Shutdown(); + GameString_Shutdown(); + return true; +} + +void __cdecl Shell_Cleanup(void) +{ + Music_Shutdown(); +} + +void __cdecl Shell_ExitSystem(const char *message) +{ + GameBuf_Shutdown(); + strcpy(g_ErrorMessage, message); + Shell_Shutdown(); + Shell_Cleanup(); + exit(1); +} + +void __cdecl Shell_ExitSystemFmt(const char *fmt, ...) +{ + va_list va; + va_start(va, fmt); + int32_t size = vsnprintf(NULL, 0, fmt, va) + 1; + char *message = Memory_Alloc(size); + va_end(va); + + va_start(va, fmt); + vsnprintf(message, size, fmt, va); + va_end(va); + + Shell_ExitSystem(message); + + Memory_FreePointer(&message); +} + +void Shell_ProcessEvents(void) +{ + SDL_Event e; + while ((SDL_PollEvent(&e)) != 0) { + if (e.type == SDL_QUIT) { + g_IsMessageLoopClosed = true; + g_IsGameWindowMinimized = true; + g_StopInventory = true; + } + } +} + +void Shell_ProcessInput(void) +{ + if (g_InputDB.screenshot) { + Screenshot(g_PrimaryBufferSurface); + } +} diff --git a/src/tr2/game/demo.c b/src/tr2/game/demo.c index d94b8a8298..e81b7bb26c 100644 --- a/src/tr2/game/demo.c +++ b/src/tr2/game/demo.c @@ -127,7 +127,6 @@ bool __cdecl Demo_GetInput(void) { if (g_DemoCount >= MAX_DEMO_SIZE) { return false; - ; } const int32_t input = g_DemoPtr[g_DemoCount]; @@ -135,6 +134,7 @@ bool __cdecl Demo_GetInput(void) return false; } + // TODO g_Input.any = input; g_InputDB.any = g_Input.any & ~m_OldDemoInputDB.any; m_OldDemoInputDB = g_Input; diff --git a/src/tr2/game/game.c b/src/tr2/game/game.c index 00bd394bfc..e077afe01f 100644 --- a/src/tr2/game/game.c +++ b/src/tr2/game/game.c @@ -5,11 +5,13 @@ #include "game/demo.h" #include "game/gameflow/gameflow_new.h" #include "game/input.h" +#include "game/inventory/backpack.h" #include "game/inventory/common.h" #include "game/lara/control.h" #include "game/music.h" #include "game/overlay.h" #include "game/room_draw.h" +#include "game/shell.h" #include "game/sound.h" #include "game/text.h" #include "global/funcs.h" @@ -43,6 +45,8 @@ int32_t __cdecl Game_Control(int32_t nframes, const bool demo_mode) } Input_Update(); + Shell_ProcessInput(); + Game_ProcessInput(); if (demo_mode) { if (g_InputDB.any) { @@ -316,3 +320,39 @@ bool Game_IsPlayable(void) return true; } + +void Game_ProcessInput(void) +{ + if (g_GameInfo.current_level.type == GFL_DEMO) { + return; + } + + if (g_InputDB.equip_pistols && Inv_RequestItem(O_PISTOL_OPTION)) { + g_Lara.request_gun_type = LGT_PISTOLS; + } else if (g_InputDB.equip_shotgun && Inv_RequestItem(O_SHOTGUN_OPTION)) { + g_Lara.request_gun_type = LGT_SHOTGUN; + } else if (g_InputDB.equip_magnums && Inv_RequestItem(O_MAGNUM_OPTION)) { + g_Lara.request_gun_type = LGT_MAGNUMS; + } else if (g_InputDB.equip_uzis && Inv_RequestItem(O_UZI_OPTION)) { + g_Lara.request_gun_type = LGT_UZIS; + } else if (g_InputDB.equip_harpoon && Inv_RequestItem(O_HARPOON_OPTION)) { + g_Lara.request_gun_type = LGT_HARPOON; + } else if (g_InputDB.equip_m16 && Inv_RequestItem(O_M16_OPTION)) { + g_Lara.request_gun_type = LGT_M16; + } else if ( + g_InputDB.equip_grenade_launcher && Inv_RequestItem(O_GRENADE_OPTION)) { + g_Lara.request_gun_type = LGT_GRENADE; + } + + if (g_InputDB.use_small_medi && Inv_RequestItem(O_SMALL_MEDIPACK_OPTION)) { + Lara_UseItem(O_SMALL_MEDIPACK_OPTION); + } + if (g_InputDB.use_big_medi && Inv_RequestItem(O_LARGE_MEDIPACK_OPTION)) { + Lara_UseItem(O_LARGE_MEDIPACK_OPTION); + } + + if (g_GameFlow.load_save_disabled) { + g_Input.save = 0; + g_Input.load = 0; + } +} diff --git a/src/tr2/game/game.h b/src/tr2/game/game.h index 660899baa6..4a7ff9a742 100644 --- a/src/tr2/game/game.h +++ b/src/tr2/game/game.h @@ -8,3 +8,4 @@ int32_t __cdecl Game_DrawCinematic(void); int16_t __cdecl Game_Start(int32_t level_num, GAMEFLOW_LEVEL_TYPE level_type); int32_t __cdecl Game_Loop(bool demo_mode); bool Game_IsPlayable(void); +void Game_ProcessInput(void); diff --git a/src/tr2/game/gun/gun.c b/src/tr2/game/gun/gun.c index e18c8f197e..2f3e33146b 100644 --- a/src/tr2/game/gun/gun.c +++ b/src/tr2/game/gun/gun.c @@ -42,7 +42,7 @@ void __cdecl Gun_Control(void) } else if (g_Lara.gun_status == LGS_ARMLESS) { if (g_Input.draw) { g_Lara.request_gun_type = g_Lara.last_gun_type; - } else if (g_InputDB.flare) { + } else if (g_InputDB.use_flare) { if (g_Lara.gun_type == LGT_FLARE) { g_Lara.gun_status = LGS_UNDRAW; } else if (Inv_RequestItem(O_FLARES_ITEM)) { @@ -78,7 +78,7 @@ void __cdecl Gun_Control(void) } } } else if (g_Lara.gun_status == LGS_READY) { - if ((g_InputDB.flare) && Inv_RequestItem(O_FLARES_ITEM)) { + if (g_InputDB.use_flare && Inv_RequestItem(O_FLARES_ITEM)) { g_Lara.request_gun_type = LGT_FLARE; } diff --git a/src/tr2/game/input.c b/src/tr2/game/input.c index c8795d2118..487c9899ea 100644 --- a/src/tr2/game/input.c +++ b/src/tr2/game/input.c @@ -1,57 +1,20 @@ #include "game/input.h" +#include "config.h" #include "game/console/common.h" +#include "game/shell.h" #include "global/funcs.h" #include "global/vars.h" -#include "specific/s_input.h" - -static const char *m_KeyNames[] = { - NULL, "ESC", "1", "2", "3", "4", "5", "6", - "7", "8", "9", "0", "-", "+", "BKSP", "TAB", - "Q", "W", "E", "R", "T", "Y", "U", "I", - "O", "P", "<", ">", "RET", "CTRL", "A", "S", - "D", "F", "G", "H", "J", "K", "L", ";", - "'", "`", "SHIFT", "#", "Z", "X", "C", "V", - "B", "N", "M", ",", ".", "/", "SHIFT", "PADx", - "ALT", "SPACE", "CAPS", NULL, NULL, NULL, NULL, NULL, - NULL, NULL, NULL, NULL, NULL, "NMLK", NULL, "PAD7", - "PAD8", "PAD9", "PAD-", "PAD4", "PAD5", "PAD6", "PAD+", "PAD1", - "PAD2", "PAD3", "PAD0", "PAD.", NULL, NULL, "\\", NULL, - NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, - NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, - NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, - NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, - NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, - NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, - NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, - NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, - NULL, NULL, NULL, NULL, "ENTER", "CTRL", NULL, NULL, - NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, - NULL, NULL, "SHIFT", NULL, NULL, NULL, NULL, NULL, - NULL, NULL, NULL, NULL, NULL, "PAD/", NULL, NULL, - "ALT", NULL, NULL, NULL, NULL, NULL, NULL, NULL, - NULL, NULL, NULL, NULL, NULL, NULL, NULL, "HOME", - "UP", "PGUP", NULL, "LEFT", NULL, "RIGHT", NULL, "END", - "DOWN", "PGDN", "INS", "DEL", NULL, NULL, NULL, NULL, - NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, - NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, - NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, - NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, - NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, - "JOY1", "JOY2", "JOY3", "JOY4", "JOY5", "JOY6", "JOY7", "JOY8", - "JOY9", "JOY10", "JOY11", "JOY12", "JOY13", "JOY14", "JOY15", "JOY16", -}; - -INPUT_STATE g_Input = { 0 }; -INPUT_STATE g_InputDB = { 0 }; -INPUT_STATE g_OldInputDB = { 0 }; -bool g_ConflictLayout[INPUT_ROLE_NUMBER_OF] = { false }; - -static bool m_ListenMode = false; - -static INPUT_STATE __cdecl M_GetDebounced(INPUT_STATE input); - -static INPUT_STATE __cdecl M_GetDebounced(const INPUT_STATE input) + +#include +#include +#include + +static INPUT_STATE M_GetDebounced(INPUT_STATE input); +static void M_UpdateFromBackend( + INPUT_STATE *s, const INPUT_BACKEND_IMPL *backend, INPUT_LAYOUT layout); + +static INPUT_STATE M_GetDebounced(const INPUT_STATE input) { INPUT_STATE result; result.any = input.any & ~g_OldInputDB.any; @@ -60,102 +23,116 @@ static INPUT_STATE __cdecl M_GetDebounced(const INPUT_STATE input) return result; } -bool Input_Update(void) +static void M_UpdateFromBackend( + INPUT_STATE *const s, const INPUT_BACKEND_IMPL *const backend, + const INPUT_LAYOUT layout) +{ + // clang-format off + s->forward |= backend->is_pressed(layout, INPUT_ROLE_UP); + s->back |= backend->is_pressed(layout, INPUT_ROLE_DOWN); + s->left |= backend->is_pressed(layout, INPUT_ROLE_LEFT); + s->right |= backend->is_pressed(layout, INPUT_ROLE_RIGHT); + s->step_left |= backend->is_pressed(layout, INPUT_ROLE_STEP_L); + s->step_right |= backend->is_pressed(layout, INPUT_ROLE_STEP_R); + s->slow |= backend->is_pressed(layout, INPUT_ROLE_SLOW); + s->jump |= backend->is_pressed(layout, INPUT_ROLE_JUMP); + s->action |= backend->is_pressed(layout, INPUT_ROLE_ACTION); + s->draw |= backend->is_pressed(layout, INPUT_ROLE_DRAW); + s->look |= backend->is_pressed(layout, INPUT_ROLE_LOOK); + s->roll |= backend->is_pressed(layout, INPUT_ROLE_ROLL); + + s->enter_console |= backend->is_pressed(layout, INPUT_ROLE_ENTER_CONSOLE); + s->save |= backend->is_pressed(layout, INPUT_ROLE_SAVE); + s->load |= backend->is_pressed(layout, INPUT_ROLE_LOAD); + + s->equip_pistols |= backend->is_pressed(layout, INPUT_ROLE_EQUIP_PISTOLS); + s->equip_shotgun |= backend->is_pressed(layout, INPUT_ROLE_EQUIP_SHOTGUN); + s->equip_magnums |= backend->is_pressed(layout, INPUT_ROLE_EQUIP_MAGNUMS); + s->equip_uzis |= backend->is_pressed(layout, INPUT_ROLE_EQUIP_UZIS); + s->equip_harpoon |= backend->is_pressed(layout, INPUT_ROLE_EQUIP_HARPOON); + s->equip_m16 |= backend->is_pressed(layout, INPUT_ROLE_EQUIP_M16); + s->equip_grenade_launcher |= backend->is_pressed(layout, INPUT_ROLE_EQUIP_GRENADE_LAUNCHER); + s->use_flare |= backend->is_pressed(layout, INPUT_ROLE_USE_FLARE); + s->use_small_medi |= backend->is_pressed(layout, INPUT_ROLE_USE_SMALL_MEDI); + s->use_big_medi |= backend->is_pressed(layout, INPUT_ROLE_USE_BIG_MEDI); + + s->option |= backend->is_pressed(layout, INPUT_ROLE_OPTION); + s->menu_up |= backend->is_pressed(layout, INPUT_ROLE_MENU_UP); + s->menu_down |= backend->is_pressed(layout, INPUT_ROLE_MENU_DOWN); + s->menu_left |= backend->is_pressed(layout, INPUT_ROLE_MENU_LEFT); + s->menu_right |= backend->is_pressed(layout, INPUT_ROLE_MENU_RIGHT); + s->menu_confirm |= backend->is_pressed(layout, INPUT_ROLE_MENU_CONFIRM); + s->menu_back |= backend->is_pressed(layout, INPUT_ROLE_MENU_BACK); + + s->screenshot |= backend->is_pressed(layout, INPUT_ROLE_SCREENSHOT); + s->switch_resolution |= backend->is_pressed(layout, INPUT_ROLE_SWITCH_RESOLUTION); + s->switch_internal_screen_size |= backend->is_pressed(layout, INPUT_ROLE_SWITCH_INTERNAL_SCREEN_SIZE); + s->toggle_bilinear_filter |= backend->is_pressed(layout, INPUT_ROLE_TOGGLE_BILINEAR_FILTER); + s->toggle_perspective_filter |= backend->is_pressed(layout, INPUT_ROLE_TOGGLE_PERSPECTIVE_FILTER); + s->toggle_z_buffer |= backend->is_pressed(layout, INPUT_ROLE_TOGGLE_Z_BUFFER); + s->toggle_dither |= backend->is_pressed(layout, INPUT_ROLE_TOGGLE_DITHER); + s->toggle_fullscreen |= backend->is_pressed(layout, INPUT_ROLE_TOGGLE_FULLSCREEN); + s->toggle_rendering_mode |= backend->is_pressed(layout, INPUT_ROLE_TOGGLE_RENDERING_MODE); + // clang-format on + + backend->custom_update(s, layout); +} + +void Input_Update(void) { - bool result = S_Input_Update(); + g_Input.any = 0; + + M_UpdateFromBackend( + &g_Input, &g_Input_Keyboard, g_Config.input.keyboard_layout); + M_UpdateFromBackend( + &g_Input, &g_Input_Controller, g_Config.input.controller_layout); + + g_Input.option &= g_Camera.type != CAM_CINEMATIC; + g_Input.roll |= g_Input.forward && g_Input.back; + g_Input.menu_back |= g_Input.option; + if (g_Input.left && g_Input.right) { + g_Input.left = 0; + g_Input.right = 0; + } g_InputDB = M_GetDebounced(g_Input); - if (m_ListenMode) { + if (Input_IsInListenMode()) { g_Input = (INPUT_STATE) { 0 }; g_InputDB = (INPUT_STATE) { 0 }; - return result; + return; } - if (!g_IsFMVPlaying && g_InputDB.console) { + if (!g_IsFMVPlaying && g_InputDB.enter_console) { Console_Open(); g_Input = (INPUT_STATE) { 0 }; g_InputDB = (INPUT_STATE) { 0 }; } - return result; -} - -uint16_t Input_GetAssignedKey(const int32_t layout, const INPUT_ROLE role) -{ - return g_Layout[layout].key[role]; -} - -void Input_AssignKey( - const int32_t layout, const INPUT_ROLE role, const uint16_t key) -{ - g_Layout[layout].key[role] = key; -} - -const char *Input_GetLayoutName(const int32_t layout) -{ - // clang-format off - switch (layout) { - case 0: return g_GF_PCStrings[GF_S_PC_DEFAULT_KEYS]; - case 1: return g_GF_PCStrings[GF_S_PC_USER_KEYS]; - default: return ""; - } - // clang-format on + // TODO: remove me from here + Shell_ProcessEvents(); } const char *Input_GetRoleName(const INPUT_ROLE role) { // clang-format off switch (role) { - case INPUT_ROLE_UP: return g_GF_GameStrings[GF_S_GAME_KEYMAP_RUN]; - case INPUT_ROLE_DOWN: return g_GF_GameStrings[GF_S_GAME_KEYMAP_BACK]; - case INPUT_ROLE_LEFT: return g_GF_GameStrings[GF_S_GAME_KEYMAP_LEFT]; - case INPUT_ROLE_RIGHT: return g_GF_GameStrings[GF_S_GAME_KEYMAP_RIGHT]; - case INPUT_ROLE_STEP_LEFT: return g_GF_GameStrings[GF_S_GAME_KEYMAP_STEP_LEFT]; - case INPUT_ROLE_STEP_RIGHT: return g_GF_GameStrings[GF_S_GAME_KEYMAP_STEP_RIGHT]; - case INPUT_ROLE_SLOW: return g_GF_GameStrings[GF_S_GAME_KEYMAP_WALK]; - case INPUT_ROLE_JUMP: return g_GF_GameStrings[GF_S_GAME_KEYMAP_JUMP]; - case INPUT_ROLE_ACTION: return g_GF_GameStrings[GF_S_GAME_KEYMAP_ACTION]; - case INPUT_ROLE_DRAW_WEAPON: return g_GF_GameStrings[GF_S_GAME_KEYMAP_DRAW_WEAPON]; - case INPUT_ROLE_FLARE: return g_GF_GameStrings[GF_S_GAME_KEYMAP_FLARE]; - case INPUT_ROLE_LOOK: return g_GF_GameStrings[GF_S_GAME_KEYMAP_LOOK]; - case INPUT_ROLE_ROLL: return g_GF_GameStrings[GF_S_GAME_KEYMAP_ROLL]; - case INPUT_ROLE_OPTION: return g_GF_GameStrings[GF_S_GAME_KEYMAP_INVENTORY]; - case INPUT_ROLE_CONSOLE: return "Console"; - default: return ""; + case INPUT_ROLE_UP: return g_GF_GameStrings[GF_S_GAME_KEYMAP_RUN]; + case INPUT_ROLE_DOWN: return g_GF_GameStrings[GF_S_GAME_KEYMAP_BACK]; + case INPUT_ROLE_LEFT: return g_GF_GameStrings[GF_S_GAME_KEYMAP_LEFT]; + case INPUT_ROLE_RIGHT: return g_GF_GameStrings[GF_S_GAME_KEYMAP_RIGHT]; + case INPUT_ROLE_STEP_L: return g_GF_GameStrings[GF_S_GAME_KEYMAP_STEP_LEFT]; + case INPUT_ROLE_STEP_R: return g_GF_GameStrings[GF_S_GAME_KEYMAP_STEP_RIGHT]; + case INPUT_ROLE_SLOW: return g_GF_GameStrings[GF_S_GAME_KEYMAP_WALK]; + case INPUT_ROLE_JUMP: return g_GF_GameStrings[GF_S_GAME_KEYMAP_JUMP]; + case INPUT_ROLE_ACTION: return g_GF_GameStrings[GF_S_GAME_KEYMAP_ACTION]; + case INPUT_ROLE_DRAW: return g_GF_GameStrings[GF_S_GAME_KEYMAP_DRAW_WEAPON]; + case INPUT_ROLE_USE_FLARE: return g_GF_GameStrings[GF_S_GAME_KEYMAP_FLARE]; + case INPUT_ROLE_LOOK: return g_GF_GameStrings[GF_S_GAME_KEYMAP_LOOK]; + case INPUT_ROLE_ROLL: return g_GF_GameStrings[GF_S_GAME_KEYMAP_ROLL]; + case INPUT_ROLE_OPTION: return g_GF_GameStrings[GF_S_GAME_KEYMAP_INVENTORY]; + case INPUT_ROLE_ENTER_CONSOLE: return "Console"; + default: return ""; } // clang-format on } - -const char *Input_GetKeyName(const uint16_t key) -{ - return m_KeyNames[key]; -} - -void __cdecl Input_CheckConflictsWithDefaults(void) -{ - for (int32_t i = 0; i < INPUT_ROLE_NUMBER_OF; i++) { - g_ConflictLayout[i] = false; - for (int32_t j = 0; j < INPUT_ROLE_NUMBER_OF; j++) { - const uint16_t key1 = Input_GetAssignedKey(0, i); - const uint16_t key2 = Input_GetAssignedKey(1, j); - if (key1 == key2) { - g_ConflictLayout[i] = true; - break; - } - } - } -} - -void Input_EnterListenMode(void) -{ - m_ListenMode = true; -} - -void Input_ExitListenMode(void) -{ - m_ListenMode = false; - S_Input_Update(); - g_OldInputDB = g_Input; - g_InputDB = M_GetDebounced(g_Input); -} diff --git a/src/tr2/game/input.h b/src/tr2/game/input.h index 8732b04b54..e4e59f2544 100644 --- a/src/tr2/game/input.h +++ b/src/tr2/game/input.h @@ -1,85 +1,5 @@ #pragma once -#include "global/types.h" +#include -#define INPUT_MAX_LAYOUT 2 - -typedef enum { - // clang-format off - INPUT_ROLE_UP = 0, - INPUT_ROLE_FORWARD = INPUT_ROLE_UP, - INPUT_ROLE_DOWN = 1, - INPUT_ROLE_BACK = INPUT_ROLE_DOWN, - INPUT_ROLE_LEFT = 2, - INPUT_ROLE_RIGHT = 3, - INPUT_ROLE_STEP_LEFT = 4, - INPUT_ROLE_STEP_RIGHT = 5, - INPUT_ROLE_SLOW = 6, - INPUT_ROLE_JUMP = 7, - INPUT_ROLE_ACTION = 8, - INPUT_ROLE_DRAW_WEAPON = 9, - INPUT_ROLE_FLARE = 10, - INPUT_ROLE_LOOK = 11, - INPUT_ROLE_ROLL = 12, - INPUT_ROLE_OPTION = 13, - INPUT_ROLE_CONSOLE = 14, - INPUT_ROLE_NUMBER_OF = 15, - // clang-format on -} INPUT_ROLE; - -typedef union { - uint64_t any; - struct { - // clang-format off - uint64_t forward: 1; - uint64_t back: 1; - uint64_t left: 1; - uint64_t right: 1; - uint64_t jump: 1; - uint64_t draw: 1; - uint64_t action: 1; - uint64_t slow: 1; - uint64_t option: 1; - uint64_t look: 1; - uint64_t step_left: 1; - uint64_t step_right: 1; - uint64_t roll: 1; - uint64_t pause: 1; - uint64_t reserved1: 1; - uint64_t reserved2: 1; - uint64_t dozy_cheat: 1; - uint64_t stuff_cheat: 1; - uint64_t debug_info: 1; - uint64_t flare: 1; - uint64_t menu_confirm: 1; - uint64_t menu_back: 1; - uint64_t save: 1; - uint64_t load: 1; - uint64_t console: 1; - // clang-format on - }; -} INPUT_STATE; - -typedef struct { - uint16_t key[INPUT_ROLE_NUMBER_OF]; -} INPUT_LAYOUT; - -extern INPUT_STATE g_Input; -extern INPUT_STATE g_InputDB; -extern INPUT_STATE g_OldInputDB; -extern INPUT_LAYOUT g_Layout[2]; -extern bool g_ConflictLayout[INPUT_ROLE_NUMBER_OF]; - -bool Input_Update(void); - -void Input_EnterListenMode(void); -void Input_ExitListenMode(void); -bool Input_IsAnythingPressed(void); -void Input_AssignKey(int32_t layout, INPUT_ROLE role, uint16_t key); -uint16_t Input_GetAssignedKey(int32_t layout, INPUT_ROLE role); - -const char *Input_GetLayoutName(int32_t layout); const char *Input_GetRoleName(INPUT_ROLE role); -const char *Input_GetKeyName(uint16_t key); - -void __cdecl Input_CheckConflictsWithDefaults(void); diff --git a/src/tr2/game/inventory/common.c b/src/tr2/game/inventory/common.c index e94b523d2e..5f1e115e91 100644 --- a/src/tr2/game/inventory/common.c +++ b/src/tr2/game/inventory/common.c @@ -1,6 +1,7 @@ #include "game/inventory/common.h" #include "game/demo.h" +#include "game/game.h" #include "game/input.h" #include "game/inventory/backpack.h" #include "game/inventory/ring.h" @@ -14,6 +15,7 @@ #include "game/option/option.h" #include "game/output.h" #include "game/overlay.h" +#include "game/shell.h" #include "game/sound.h" #include "game/text.h" #include "global/const.h" @@ -249,6 +251,8 @@ int32_t __cdecl Inv_Display(int32_t inventory_mode) Inv_Ring_CalcAdders(&ring, 24); Input_Update(); + Shell_ProcessInput(); + Game_ProcessInput(); if (g_Inv_DemoMode) { if (g_InputDB.any) { diff --git a/src/tr2/game/option/option_controls.c b/src/tr2/game/option/option_controls.c index aad606c593..bc06fbe155 100644 --- a/src/tr2/game/option/option_controls.c +++ b/src/tr2/game/option/option_controls.c @@ -1,28 +1,79 @@ +#include "config.h" #include "game/option/option.h" #include "game/ui/widgets/controls_dialog.h" #include "global/vars.h" -static UI_WIDGET *m_ControlsDialog; -static UI_CONTROLS_CONTROLLER m_ControlsDialogController; +#include -void Option_Controls_Shutdown(void) +static UI_WIDGET *m_Dialog; +static UI_CONTROLS_CONTROLLER m_Controller; +static int32_t m_Listener1; +static int32_t m_Listener2; + +static void M_Init(void); +static void M_Shutdown(void); +static void M_HandleLayoutChange(const EVENT *event, void *user_data); +static void M_HandleKeyChange(const EVENT *event, void *user_data); + +static void M_Init(void) +{ + UI_ControlsController_Init(&m_Controller); + m_Controller.active_layout = g_Config.input.keyboard_layout; + + m_Dialog = UI_ControlsDialog_Create(&m_Controller); + m_Listener1 = EventManager_Subscribe( + m_Controller.events, "layout_change", NULL, M_HandleLayoutChange, NULL); + m_Listener2 = EventManager_Subscribe( + m_Controller.events, "key_change", NULL, M_HandleKeyChange, NULL); +} + +static void M_Shutdown(void) +{ + if (m_Dialog == NULL) { + return; + } + + m_Dialog->free(m_Dialog); + m_Dialog = NULL; + + UI_Events_Unsubscribe(m_Listener1); + UI_Events_Unsubscribe(m_Listener2); + + UI_ControlsController_Shutdown(&m_Controller); +} + +static void M_HandleLayoutChange(const EVENT *event, void *user_data) { - if (m_ControlsDialog != NULL) { - m_ControlsDialog->free(m_ControlsDialog); - m_ControlsDialog = NULL; + switch (m_Controller.backend) { + case INPUT_BACKEND_KEYBOARD: + g_Config.input.keyboard_layout = m_Controller.active_layout; + break; + case INPUT_BACKEND_CONTROLLER: + g_Config.input.controller_layout = m_Controller.active_layout; + break; } - Input_CheckConflictsWithDefaults(); + + Config_Write(); +} + +static void M_HandleKeyChange(const EVENT *event, void *user_data) +{ + Config_Write(); +} + +void Option_Controls_Shutdown(void) +{ + M_Shutdown(); } void __cdecl Option_Controls(INVENTORY_ITEM *const item) { - if (m_ControlsDialog == NULL) { - m_ControlsDialog = - UI_ControlsDialog_Create(&m_ControlsDialogController); + if (m_Dialog == NULL) { + M_Init(); } - m_ControlsDialog->control(m_ControlsDialog); - if (m_ControlsDialogController.state == UI_CONTROLS_STATE_EXIT) { + m_Dialog->control(m_Dialog); + if (m_Controller.state == UI_CONTROLS_STATE_EXIT) { Option_Controls_Shutdown(); } else { g_Input = (INPUT_STATE) { 0 }; diff --git a/src/tr2/game/shell.h b/src/tr2/game/shell.h index c5df56a710..003b6f91e5 100644 --- a/src/tr2/game/shell.h +++ b/src/tr2/game/shell.h @@ -1,8 +1,4 @@ #pragma once -#include "global/types.h" - -void __cdecl Shell_Main(void); -void __cdecl Shell_Shutdown(void); -void __cdecl Shell_ExitSystem(const char *message); -void __cdecl Shell_ExitSystemFmt(const char *fmt, ...); +#include "game/shell/common.h" +#include "game/shell/input.h" diff --git a/src/tr2/game/shell.c b/src/tr2/game/shell/common.c similarity index 94% rename from src/tr2/game/shell.c rename to src/tr2/game/shell/common.c index 44d1e562fd..ac8e800c06 100644 --- a/src/tr2/game/shell.c +++ b/src/tr2/game/shell/common.c @@ -1,5 +1,3 @@ -#include "game/shell.h" - #include "config.h" #include "decomp/decomp.h" #include "game/console/common.h" @@ -10,6 +8,7 @@ #include "game/gameflow/reader.h" #include "game/input.h" #include "game/music.h" +#include "game/shell.h" #include "game/sound.h" #include "game/text.h" #include "global/funcs.h" @@ -19,6 +18,7 @@ #include #include +#include #include #include @@ -38,7 +38,10 @@ void __cdecl Shell_Main(void) Text_Init(); UI_Init(); Console_Init(); + + Sound_Init(); Music_Init(); + Input_Init(); Config_Read(); if (!S_InitialiseSystem()) { @@ -64,7 +67,6 @@ void __cdecl Shell_Main(void) g_HiRes = 0; TempVideoAdjust(1, 1.0); - Input_Update(); g_IsVidModeLock = 1; S_DisplayPicture("data\\legal.pcx", 0); @@ -168,7 +170,6 @@ void __cdecl Shell_Shutdown(void) { GameString_Shutdown(); Console_Shutdown(); - WinInFinish(); RenderFinish(true); WinVidFinish(); WinVidHideGameWindow(); @@ -201,3 +202,15 @@ void __cdecl Shell_ExitSystemFmt(const char *fmt, ...) Memory_FreePointer(&message); } + +void Shell_ProcessEvents(void) +{ + SDL_Event e; + while ((SDL_PollEvent(&e)) != 0) { + if (e.type == SDL_QUIT) { + g_IsMessageLoopClosed = true; + g_IsGameWindowMinimized = true; + g_StopInventory = true; + } + } +} diff --git a/src/tr2/game/shell/common.h b/src/tr2/game/shell/common.h new file mode 100644 index 0000000000..94101a6e5d --- /dev/null +++ b/src/tr2/game/shell/common.h @@ -0,0 +1,10 @@ +#pragma once + +#include "global/types.h" + +void __cdecl Shell_Main(void); +void __cdecl Shell_Shutdown(void); +void __cdecl Shell_ExitSystem(const char *message); +void __cdecl Shell_ExitSystemFmt(const char *fmt, ...); + +void Shell_ProcessEvents(void); diff --git a/src/tr2/game/shell/input.c b/src/tr2/game/shell/input.c new file mode 100644 index 0000000000..963c426fd6 --- /dev/null +++ b/src/tr2/game/shell/input.c @@ -0,0 +1,305 @@ +#include "game/shell/input.h" + +#include "config.h" +#include "decomp/decomp.h" +#include "game/console/common.h" +#include "game/gameflow/gameflow_new.h" +#include "game/input.h" +#include "game/inventory/backpack.h" +#include "game/lara/control.h" +#include "global/const.h" +#include "global/funcs.h" +#include "global/vars.h" + +#include +#include + +static void M_ToggleBilinearFiltering(void); +static void M_TogglePerspectiveCorrection(void); +static void M_ToggleZBuffer(void); +static void M_ToggleTripleBuffering(void); +static void M_ToggleDither(void); +static void M_ToggleFullscreen(void); +static void M_ToggleRenderingMode(void); +static void M_DecreaseResolutionOrBPP(void); +static void M_IncreaseResolutionOrBPP(void); +static void M_DecreaseInternalScreenSize(void); +static void M_IncreaseInternalScreenSize(void); + +static void M_ToggleBilinearFiltering(void) +{ + APP_SETTINGS new_settings = g_SavedAppSettings; + new_settings.bilinear_filtering = !new_settings.bilinear_filtering; + GameApplySettings(&new_settings); +} + +static void M_TogglePerspectiveCorrection(void) +{ + APP_SETTINGS new_settings = g_SavedAppSettings; + new_settings.perspective_correct = !new_settings.perspective_correct; + g_PerspectiveDistance = g_SavedAppSettings.perspective_correct + ? SW_DETAIL_HIGH + : SW_DETAIL_MEDIUM; + GameApplySettings(&new_settings); +} + +static void M_ToggleZBuffer(void) +{ + APP_SETTINGS new_settings = g_SavedAppSettings; + new_settings.zbuffer = !new_settings.zbuffer; + GameApplySettings(&new_settings); +} + +static void M_ToggleTripleBuffering(void) +{ + if (g_SavedAppSettings.fullscreen) { + return; + } + + APP_SETTINGS new_settings = g_SavedAppSettings; + new_settings.triple_buffering = !new_settings.triple_buffering; + GameApplySettings(&new_settings); +} + +static void M_ToggleDither(void) +{ + APP_SETTINGS new_settings = g_SavedAppSettings; + new_settings.dither = !new_settings.dither; + GameApplySettings(&new_settings); +} + +static void M_ToggleFullscreen(void) +{ + if (g_IsVidModeLock) { + return; + } + + APP_SETTINGS new_settings = g_SavedAppSettings; + new_settings.fullscreen = !new_settings.fullscreen; + if (g_SavedAppSettings.fullscreen) { + const int32_t win_width = MAX(g_PhdWinWidth, 320); + const int32_t win_height = MAX(g_PhdWinHeight, 240); + new_settings.window_height = win_height; + new_settings.window_width = CalculateWindowWidth(win_width, win_height); + new_settings.triple_buffering = 0; + GameApplySettings(&new_settings); + + g_GameSizer = 1.0; + g_GameSizerCopy = 1.0; + setup_screen_size(); + } else { + const DISPLAY_MODE_LIST *const mode_list = + new_settings.render_mode == RM_HARDWARE + ? &g_CurrentDisplayAdapter.hw_disp_mode_list + : &g_CurrentDisplayAdapter.sw_disp_mode_list; + + if (mode_list->count > 0) { + const DISPLAY_MODE target_mode = { + .width = g_GameVid_Width, + .height = g_GameVid_Height, + .bpp = g_GameVid_BPP, + .vga = VGA_NO_VGA, + }; + + const DISPLAY_MODE_NODE *mode = NULL; + for (mode = mode_list->head; mode != NULL; mode = mode->next) { + if (!CompareVideoModes(&mode->body, &target_mode)) { + break; + } + } + + if (mode == NULL) { + mode = mode_list->tail; + } + + new_settings.video_mode = mode; + GameApplySettings(&new_settings); + } + } +} + +static void M_ToggleRenderingMode(void) +{ + if (g_IsVidModeLock || g_Inv_IsActive) { + return; + } + + APP_SETTINGS new_settings = g_SavedAppSettings; + new_settings.render_mode = + new_settings.render_mode == RM_HARDWARE ? RM_SOFTWARE : RM_HARDWARE; + + const DISPLAY_MODE_LIST *const mode_list = + new_settings.render_mode == RM_HARDWARE + ? &g_CurrentDisplayAdapter.hw_disp_mode_list + : &g_CurrentDisplayAdapter.sw_disp_mode_list; + + if (mode_list->count == 0) { + return; + } + + const DISPLAY_MODE target_mode = { + .width = g_GameVid_Width, + .height = g_GameVid_Height, + .bpp = new_settings.render_mode == RM_HARDWARE ? 16 : 8, + .vga = VGA_NO_VGA, + }; + + const DISPLAY_MODE_NODE *mode = NULL; + for (mode = mode_list->head; mode != NULL; mode = mode->next) { + if (!CompareVideoModes(&mode->body, &target_mode)) { + break; + } + } + + if (mode == NULL) { + mode = mode_list->tail; + } + + new_settings.video_mode = mode; + new_settings.fullscreen = 1; + GameApplySettings(&new_settings); +} + +static void M_DecreaseResolutionOrBPP(void) +{ + if (g_IsVidSizeLock || g_Camera.type == CAM_CINEMATIC + || g_GameFlow.screen_sizing_disabled + || !g_SavedAppSettings.fullscreen) { + return; + } + + APP_SETTINGS new_settings = g_SavedAppSettings; + const DISPLAY_MODE_NODE *const current_mode = new_settings.video_mode; + const DISPLAY_MODE_NODE *mode = current_mode; + if (mode != NULL) { + mode = mode->previous; + } + + if (new_settings.render_mode == RM_HARDWARE) { + for (; mode != NULL; mode = mode->previous) { + if (g_Input.slow) { + if (mode->body.width == current_mode->body.width + && mode->body.height == current_mode->body.height + && mode->body.vga == current_mode->body.vga + && mode->body.bpp < current_mode->body.bpp) { + break; + } + } else if ( + mode->body.vga == current_mode->body.vga + && mode->body.bpp == current_mode->body.bpp) { + break; + } + } + } + + if (mode != NULL) { + new_settings.video_mode = mode; + GameApplySettings(&new_settings); + } +} + +static void M_IncreaseResolutionOrBPP(void) +{ + if (g_IsVidSizeLock || g_Camera.type == CAM_CINEMATIC + || g_GameFlow.screen_sizing_disabled + || !g_SavedAppSettings.fullscreen) { + return; + } + + APP_SETTINGS new_settings = g_SavedAppSettings; + const DISPLAY_MODE_NODE *const current_mode = new_settings.video_mode; + const DISPLAY_MODE_NODE *mode = current_mode; + if (mode != NULL) { + mode = mode->next; + } + + if (new_settings.render_mode == RM_HARDWARE) { + for (; mode != NULL; mode = mode->next) { + if (g_Input.slow) { + if (mode->body.width == current_mode->body.width + && mode->body.height == current_mode->body.height + && mode->body.vga == current_mode->body.vga + && mode->body.bpp > current_mode->body.bpp) { + break; + } + } else if ( + mode->body.vga == current_mode->body.vga + && mode->body.bpp == current_mode->body.bpp) { + break; + } + } + } + if (mode != NULL) { + new_settings.video_mode = mode; + GameApplySettings(&new_settings); + } +} + +static void M_DecreaseInternalScreenSize(void) +{ + if (g_IsVidSizeLock || g_Camera.type == CAM_CINEMATIC + || g_GameFlow.screen_sizing_disabled + || !g_SavedAppSettings.fullscreen) { + return; + } + + DecreaseScreenSize(); +} + +static void M_IncreaseInternalScreenSize(void) +{ + if (g_IsVidSizeLock || g_Camera.type == CAM_CINEMATIC + || g_GameFlow.screen_sizing_disabled + || !g_SavedAppSettings.fullscreen) { + return; + } + + IncreaseScreenSize(); +} + +void Shell_ProcessInput(void) +{ + if (g_InputDB.screenshot) { + Screenshot_Make(g_Config.rendering.screenshot_format); + } + + if (g_InputDB.switch_resolution) { + if (g_Input.slow) { + M_DecreaseResolutionOrBPP(); + } else { + M_IncreaseResolutionOrBPP(); + } + } + + if (g_InputDB.switch_internal_screen_size) { + if (g_Input.slow) { + M_DecreaseInternalScreenSize(); + } else { + M_IncreaseInternalScreenSize(); + } + } + + if (g_InputDB.toggle_bilinear_filter) { + M_ToggleBilinearFiltering(); + } + + if (g_InputDB.toggle_perspective_filter) { + M_TogglePerspectiveCorrection(); + } + + if (g_InputDB.toggle_z_buffer) { + M_ToggleZBuffer(); + } + + if (g_InputDB.toggle_dither) { + M_ToggleDither(); + } + + if (g_InputDB.toggle_fullscreen) { + M_ToggleFullscreen(); + } + + if (g_InputDB.toggle_rendering_mode) { + M_ToggleRenderingMode(); + } +} diff --git a/src/tr2/game/shell/input.h b/src/tr2/game/shell/input.h new file mode 100644 index 0000000000..d246a7cd3f --- /dev/null +++ b/src/tr2/game/shell/input.h @@ -0,0 +1,3 @@ +#pragma once + +void Shell_ProcessInput(void); diff --git a/src/tr2/game/ui/controllers/controls.c b/src/tr2/game/ui/controllers/controls.c index db339db53d..d4e00eee4e 100644 --- a/src/tr2/game/ui/controllers/controls.c +++ b/src/tr2/game/ui/controllers/controls.c @@ -3,47 +3,58 @@ #include "game/input.h" #include "global/vars.h" +#include #include -#include +#include static const INPUT_ROLE m_LeftRoles[] = { - INPUT_ROLE_UP, INPUT_ROLE_DOWN, INPUT_ROLE_LEFT, - INPUT_ROLE_RIGHT, INPUT_ROLE_STEP_LEFT, INPUT_ROLE_STEP_RIGHT, - INPUT_ROLE_SLOW, (INPUT_ROLE)-1, + INPUT_ROLE_UP, INPUT_ROLE_DOWN, INPUT_ROLE_LEFT, INPUT_ROLE_RIGHT, + INPUT_ROLE_STEP_L, INPUT_ROLE_STEP_R, INPUT_ROLE_SLOW, (INPUT_ROLE)-1, }; static const INPUT_ROLE m_RightRoles[] = { - INPUT_ROLE_JUMP, INPUT_ROLE_ACTION, INPUT_ROLE_DRAW_WEAPON, - INPUT_ROLE_FLARE, INPUT_ROLE_LOOK, INPUT_ROLE_ROLL, - INPUT_ROLE_OPTION, INPUT_ROLE_CONSOLE, (INPUT_ROLE)-1, + INPUT_ROLE_JUMP, INPUT_ROLE_ACTION, INPUT_ROLE_DRAW, + INPUT_ROLE_USE_FLARE, INPUT_ROLE_LOOK, INPUT_ROLE_ROLL, + INPUT_ROLE_OPTION, INPUT_ROLE_ENTER_CONSOLE, (INPUT_ROLE)-1, }; static const INPUT_ROLE *M_GetInputRoles(int32_t col); +static void M_CycleLayout(UI_CONTROLS_CONTROLLER *controller, int32_t dir); static bool M_NavigateLayout(UI_CONTROLS_CONTROLLER *controller); static bool M_NavigateInputs(UI_CONTROLS_CONTROLLER *controller); -static bool M_ListenDebounce(UI_CONTROLS_CONTROLLER *controller); -static bool M_Listen(UI_CONTROLS_CONTROLLER *controller); static bool M_NavigateInputsDebounce(UI_CONTROLS_CONTROLLER *controller); +static bool M_Listen(UI_CONTROLS_CONTROLLER *controller); +static bool M_ListenDebounce(UI_CONTROLS_CONTROLLER *controller); static const INPUT_ROLE *M_GetInputRoles(const int32_t col) { return col == 0 ? m_LeftRoles : m_RightRoles; } +static void M_CycleLayout( + UI_CONTROLS_CONTROLLER *const controller, const int32_t dir) +{ + controller->active_layout += dir; + controller->active_layout += INPUT_LAYOUT_NUMBER_OF; + controller->active_layout %= INPUT_LAYOUT_NUMBER_OF; + + const EVENT event = { + .name = "layout_change", + .sender = NULL, + .data = NULL, + }; + EventManager_Fire(controller->events, &event); +} + static bool M_NavigateLayout(UI_CONTROLS_CONTROLLER *const controller) { if (g_InputDB.menu_confirm || g_InputDB.menu_back) { controller->state = UI_CONTROLS_STATE_EXIT; - } else if (g_InputDB.right) { - controller->active_layout++; - controller->active_layout %= INPUT_MAX_LAYOUT; } else if (g_InputDB.left) { - if (controller->active_layout == 0) { - controller->active_layout = INPUT_MAX_LAYOUT - 1; - } else { - controller->active_layout--; - } + M_CycleLayout(controller, -1); + } else if (g_InputDB.right) { + M_CycleLayout(controller, 1); } else if (g_InputDB.back && controller->active_layout != 0) { controller->state = UI_CONTROLS_STATE_NAVIGATE_INPUTS; controller->active_col = 0; @@ -93,7 +104,7 @@ static bool M_NavigateInputs(UI_CONTROLS_CONTROLLER *const controller) } } } else if (g_InputDB.menu_confirm) { - controller->state = UI_CONTROLS_STATE_LISTEN_DEBOUNCE; + controller->state = UI_CONTROLS_STATE_NAVIGATE_INPUTS_DEBOUNCE; } else { return false; } @@ -102,9 +113,10 @@ static bool M_NavigateInputs(UI_CONTROLS_CONTROLLER *const controller) return true; } -static bool M_ListenDebounce(UI_CONTROLS_CONTROLLER *const controller) +static bool M_NavigateInputsDebounce(UI_CONTROLS_CONTROLLER *const controller) { - if (Input_IsAnythingPressed()) { + Input_Update(); + if (g_Input.any) { return false; } Input_EnterListenMode(); @@ -114,66 +126,50 @@ static bool M_ListenDebounce(UI_CONTROLS_CONTROLLER *const controller) static bool M_Listen(UI_CONTROLS_CONTROLLER *const controller) { - int32_t pressed = 0; - - if (g_JoyKeys != 0) { - for (int32_t i = 0; i < 32; i++) { - if (g_JoyKeys & (1 << i)) { - pressed = i; - break; - } - } - if (!pressed) { - return false; - } - pressed += 0x100; - } else { - for (int32_t i = 0; i < 256; i++) { - if (g_DIKeys[i] & 0x80) { - pressed = i; - break; - } - } - if (!pressed) { - return false; - } - } - - if (!pressed - // clang-format off - || Input_GetKeyName(pressed) == NULL - || pressed == DIK_RETURN - || pressed == DIK_LEFT - || pressed == DIK_RIGHT - || pressed == DIK_UP - || pressed == DIK_DOWN - // clang-format on - ) { - g_Input = (INPUT_STATE) { 0 }; - g_InputDB = (INPUT_STATE) { 0 }; + if (!Input_ReadAndAssignRole( + controller->backend, controller->active_layout, + controller->active_role)) { return false; } - if (pressed != DIK_ESCAPE) { - Input_AssignKey( - controller->active_layout, controller->active_role, pressed); - } + Input_ExitListenMode(); + + const EVENT event = { + .name = "key_change", + .sender = NULL, + .data = NULL, + }; + EventManager_Fire(controller->events, &event); - controller->state = UI_CONTROLS_STATE_NAVIGATE_INPUTS_DEBOUNCE; + controller->state = UI_CONTROLS_STATE_LISTEN_DEBOUNCE; return true; } -static bool M_NavigateInputsDebounce(UI_CONTROLS_CONTROLLER *const controller) +static bool M_ListenDebounce(UI_CONTROLS_CONTROLLER *const controller) { - if (Input_IsAnythingPressed()) { + if (g_Input.any) { return false; } - Input_ExitListenMode(); controller->state = UI_CONTROLS_STATE_NAVIGATE_INPUTS; return true; } +void UI_ControlsController_Init(UI_CONTROLS_CONTROLLER *const controller) +{ + assert(controller->events == NULL); + controller->backend = INPUT_BACKEND_KEYBOARD; + controller->state = UI_CONTROLS_STATE_NAVIGATE_LAYOUT; + + controller->events = EventManager_Create(); +} + +void UI_ControlsController_Shutdown(UI_CONTROLS_CONTROLLER *const controller) +{ + EventManager_Free(controller->events); + controller->events = NULL; +} + bool UI_ControlsController_Control(UI_CONTROLS_CONTROLLER *const controller) { switch (controller->state) { @@ -181,12 +177,12 @@ bool UI_ControlsController_Control(UI_CONTROLS_CONTROLLER *const controller) return M_NavigateLayout(controller); case UI_CONTROLS_STATE_NAVIGATE_INPUTS: return M_NavigateInputs(controller); - case UI_CONTROLS_STATE_LISTEN_DEBOUNCE: - return M_ListenDebounce(controller); - case UI_CONTROLS_STATE_LISTEN: - return M_Listen(controller); case UI_CONTROLS_STATE_NAVIGATE_INPUTS_DEBOUNCE: return M_NavigateInputsDebounce(controller); + case UI_CONTROLS_STATE_LISTEN: + return M_Listen(controller); + case UI_CONTROLS_STATE_LISTEN_DEBOUNCE: + return M_ListenDebounce(controller); default: return false; } diff --git a/src/tr2/game/ui/controllers/controls.h b/src/tr2/game/ui/controllers/controls.h index c0dfe293c2..ea222bdb5f 100644 --- a/src/tr2/game/ui/controllers/controls.h +++ b/src/tr2/game/ui/controllers/controls.h @@ -2,23 +2,30 @@ #include "game/input.h" +#include + typedef enum { UI_CONTROLS_STATE_NAVIGATE_LAYOUT, UI_CONTROLS_STATE_NAVIGATE_INPUTS, - UI_CONTROLS_STATE_LISTEN_DEBOUNCE, - UI_CONTROLS_STATE_LISTEN, UI_CONTROLS_STATE_NAVIGATE_INPUTS_DEBOUNCE, + UI_CONTROLS_STATE_LISTEN, + UI_CONTROLS_STATE_LISTEN_DEBOUNCE, UI_CONTROLS_STATE_EXIT, } UI_CONTROLS_STATE; typedef struct { + INPUT_BACKEND backend; + UI_CONTROLS_STATE state; int32_t active_layout; + INPUT_ROLE active_role; int32_t active_col; int32_t active_row; - INPUT_ROLE active_role; - UI_CONTROLS_STATE state; + + EVENT_MANAGER *events; } UI_CONTROLS_CONTROLLER; +void UI_ControlsController_Init(UI_CONTROLS_CONTROLLER *controller); +void UI_ControlsController_Shutdown(UI_CONTROLS_CONTROLLER *controller); bool UI_ControlsController_Control(UI_CONTROLS_CONTROLLER *controller); INPUT_ROLE UI_ControlsController_GetInputRole(int32_t col, int32_t row); diff --git a/src/tr2/game/ui/widgets/controls_dialog.c b/src/tr2/game/ui/widgets/controls_dialog.c index 5aa5223afa..4ad0d6f9e5 100644 --- a/src/tr2/game/ui/widgets/controls_dialog.c +++ b/src/tr2/game/ui/widgets/controls_dialog.c @@ -93,7 +93,6 @@ UI_WIDGET *UI_ControlsDialog_Create(UI_CONTROLS_CONTROLLER *const controller) }; self->controller = controller; - self->controller->state = UI_CONTROLS_STATE_NAVIGATE_LAYOUT; self->layout_selector = UI_ControlsLayoutSelector_Create(self->controller); self->left_column = UI_ControlsColumn_Create(0, self->controller); diff --git a/src/tr2/game/ui/widgets/controls_input_selector.c b/src/tr2/game/ui/widgets/controls_input_selector.c index a08356c371..097253c144 100644 --- a/src/tr2/game/ui/widgets/controls_input_selector.c +++ b/src/tr2/game/ui/widgets/controls_input_selector.c @@ -24,12 +24,13 @@ static void M_Free(UI_CONTROLS_INPUT_SELECTOR *self); static void M_UpdateText(UI_CONTROLS_INPUT_SELECTOR *const self) { - const uint16_t key = - Input_GetAssignedKey(self->controller->active_layout, self->input_role); - if (Input_GetKeyName(key) == NULL) { + const char *const key_name = Input_GetKeyName( + self->controller->backend, self->controller->active_layout, + self->input_role); + if (key_name == NULL) { UI_Label_ChangeText(self->choice, "BAD"); } else { - UI_Label_ChangeText(self->choice, Input_GetKeyName(key)); + UI_Label_ChangeText(self->choice, key_name); } UI_Label_ChangeText(self->label, Input_GetRoleName(self->input_role)); } @@ -67,9 +68,7 @@ static void M_Control(UI_CONTROLS_INPUT_SELECTOR *const self) || self->controller->state == UI_CONTROLS_STATE_NAVIGATE_INPUTS_DEBOUNCE) { UI_Label_AddFrame(self->label); - } else if ( - self->controller->state == UI_CONTROLS_STATE_LISTEN - || self->controller->state == UI_CONTROLS_STATE_LISTEN_DEBOUNCE) { + } else if (self->controller->state == UI_CONTROLS_STATE_LISTEN) { UI_Label_AddFrame(self->choice); } } @@ -78,14 +77,10 @@ static void M_Control(UI_CONTROLS_INPUT_SELECTOR *const self) // Flash conflicts UI_Label_Flash(self->choice, false, 0); - const uint16_t key1 = - Input_GetAssignedKey(self->controller->active_layout, self->input_role); - for (INPUT_ROLE role = 0; role < INPUT_ROLE_NUMBER_OF; role++) { - const uint16_t key2 = - Input_GetAssignedKey(self->controller->active_layout, role); - if (role != self->input_role && key1 == key2) { - UI_Label_Flash(self->choice, true, 20); - } + if (Input_IsKeyConflicted( + self->controller->backend, self->controller->active_layout, + self->input_role)) { + UI_Label_Flash(self->choice, true, 20); } } diff --git a/src/tr2/global/funcs.h b/src/tr2/global/funcs.h index 65c8efb78b..e8e5e04174 100644 --- a/src/tr2/global/funcs.h +++ b/src/tr2/global/funcs.h @@ -182,17 +182,6 @@ #define DartEffectControl ((void __cdecl (*)(int16_t fx_num))0x00442AE0) #define GiantYeti_Control ((void __cdecl (*)(int16_t item_num))0x00443050) #define Yeti_Control ((void __cdecl (*)(int16_t item_num))0x00443350) -#define WinInReadJoystick ((DWORD __cdecl (*)(int32_t *x, int32_t *y))0x004472A0) -#define WinInputInit ((bool __cdecl (*)(void))0x004473B0) -#define DInputEnumDevices ((bool __cdecl (*)(JOYSTICK_LIST *joystickList))0x00447430) -#define DInputEnumDevicesCallback ((BOOL __stdcall (*)(LPCDIDEVICEINSTANCE lpddi, LPVOID pvRef))0x00447460) -#define GetJoystick ((JOYSTICK_NODE *__cdecl (*)(GUID *lpGuid))0x00447570) -#define DInputKeyboardCreate ((void __cdecl (*)(void))0x004475C0) -#define DInputKeyboardRelease ((void __cdecl (*)(void))0x00447690) -#define DInputJoystickCreate ((bool __cdecl (*)(void))0x004476C0) -#define WinInStart ((void __cdecl (*)(void))0x004477B0) -#define WinInFinish ((void __cdecl (*)(void))0x004477E0) -#define WinInRunControlPanel ((void __cdecl (*)(HWND hWnd))0x004477F0) #define IncreaseScreenSize ((void __cdecl (*)(void))0x00447810) #define DecreaseScreenSize ((void __cdecl (*)(void))0x00447880) #define setup_screen_size ((void __cdecl (*)(void))0x004478F0) diff --git a/src/tr2/global/vars_decomp.h b/src/tr2/global/vars_decomp.h index cb2b98f926..371540da6e 100644 --- a/src/tr2/global/vars_decomp.h +++ b/src/tr2/global/vars_decomp.h @@ -298,7 +298,6 @@ #define g_MinWindowHeight (*(int32_t*)0x004D838C) #define g_IsGameWindowActive (*(bool*)0x004D8390) #define g_MessageLoopCounter (*(int32_t*)0x004D8394) -#define g_DInput (*(LPDIRECTINPUT*)0x004D855C) #define IDID_SysKeyboard (*(LPDIRECTINPUTDEVICE*)0x004D8560) #define g_ScreenSizer (*(int32_t*)0x004D8568) #define g_IsVidSizeLock (*(int32_t*)0x004D856C) diff --git a/src/tr2/inject_exec.c b/src/tr2/inject_exec.c index 5ba10275a1..90549aa207 100644 --- a/src/tr2/inject_exec.c +++ b/src/tr2/inject_exec.c @@ -86,7 +86,6 @@ #include "inject_util.h" #include "specific/s_audio_sample.h" #include "specific/s_flagged_string.h" -#include "specific/s_input.h" static void M_DecompGeneral(const bool enable); static void M_DecompFMV(const bool enable); @@ -133,7 +132,6 @@ static void M_Lot(bool enable); static void M_Objects(bool enable); static void M_S_Audio_Sample(bool enable); -static void M_S_Input(bool enable); static void M_S_FlaggedString(bool enable); static void M_DecompGeneral(const bool enable) @@ -1110,11 +1108,6 @@ static void M_S_Audio_Sample(const bool enable) INJECT(enable, 0x004553C0, S_Audio_Sample_OutIsTrackPlaying); } -static void M_S_Input(const bool enable) -{ - INJECT(enable, 0x0044D8F0, S_Input_Key); -} - static void M_S_FlaggedString(const bool enable) { INJECT(enable, 0x00445F00, S_FlaggedString_Delete); @@ -1174,6 +1167,5 @@ void Inject_Exec(void) M_Objects(true); M_S_Audio_Sample(true); - M_S_Input(true); M_S_FlaggedString(true); } diff --git a/src/tr2/meson.build b/src/tr2/meson.build index a952a7b81d..6a4c86938a 100644 --- a/src/tr2/meson.build +++ b/src/tr2/meson.build @@ -195,7 +195,8 @@ dll_sources = [ 'game/room.c', 'game/room_draw.c', 'game/savegame/common.c', - 'game/shell.c', + 'game/shell/common.c', + 'game/shell/input.c', 'game/sound.c', 'game/text.c', 'game/ui/common.c', @@ -215,7 +216,6 @@ dll_sources = [ 'main_dll.c', 'specific/s_audio_sample.c', 'specific/s_flagged_string.c', - 'specific/s_input.c', dll_resources, ] diff --git a/src/tr2/specific/s_input.h b/src/tr2/specific/s_input.h deleted file mode 100644 index 14d316d807..0000000000 --- a/src/tr2/specific/s_input.h +++ /dev/null @@ -1,6 +0,0 @@ -#pragma once - -#include "game/input.h" - -bool __cdecl S_Input_Key(INPUT_ROLE role); -bool __cdecl S_Input_Update(void);