diff --git a/source/common/gamecontrol.cpp b/source/common/gamecontrol.cpp index daeadf7c5..987cd933a 100644 --- a/source/common/gamecontrol.cpp +++ b/source/common/gamecontrol.cpp @@ -10,6 +10,9 @@ #include "gamecvars.h" #include "build.h" +InputState inputState; + + struct GameFuncNameDesc { int index; diff --git a/source/common/gamecontrol.h b/source/common/gamecontrol.h index c17b07bac..efe529b3f 100644 --- a/source/common/gamecontrol.h +++ b/source/common/gamecontrol.h @@ -5,100 +5,10 @@ #include "_control.h" #include "c_cvars.h" #include "zstring.h" +#include "inputstate.h" extern FString currentGame; -// Order is that of EDuke32 by necessity because it exposes the key binds to scripting by index instead of by name. -enum GameFunction_t -{ - gamefunc_Move_Forward, - gamefunc_Move_Backward, - gamefunc_Turn_Left, - gamefunc_Turn_Right, - gamefunc_Strafe, - gamefunc_Fire, - gamefunc_Open, - gamefunc_Run, - gamefunc_Alt_Fire, - gamefunc_Jump, - gamefunc_Crouch, - gamefunc_Look_Up, - gamefunc_Look_Down, - gamefunc_Look_Left, - gamefunc_Look_Right, - gamefunc_Strafe_Left, - gamefunc_Strafe_Right, - gamefunc_Aim_Up, - gamefunc_Aim_Down, - gamefunc_Weapon_1, - gamefunc_Weapon_2, - gamefunc_Weapon_3, - gamefunc_Weapon_4, - gamefunc_Weapon_5, - gamefunc_Weapon_6, - gamefunc_Weapon_7, - gamefunc_Weapon_8, - gamefunc_Weapon_9, - gamefunc_Weapon_10, - gamefunc_Inventory, - gamefunc_Inventory_Use = gamefunc_Inventory, - gamefunc_Inventory_Left, - gamefunc_Inventory_Right, - gamefunc_Holo_Duke, - gamefunc_Jetpack, - gamefunc_NightVision, - gamefunc_Night_Vision = gamefunc_NightVision, - gamefunc_MedKit, - gamefunc_Med_Kit = gamefunc_MedKit, - gamefunc_TurnAround, - gamefunc_SendMessage, - gamefunc_Map, - gamefunc_Map_Toggle = gamefunc_Map, - gamefunc_Shrink_Screen, - gamefunc_Enlarge_Screen, - gamefunc_Center_View, - gamefunc_Holster_Weapon, - gamefunc_Show_Opponents_Weapon, - gamefunc_Map_Follow_Mode, - gamefunc_See_Coop_View, - gamefunc_See_Co_Op_View = gamefunc_See_Coop_View, - gamefunc_Mouse_Aiming, - gamefunc_Toggle_Crosshair, - gamefunc_Steroids, - gamefunc_Quick_Kick, - gamefunc_Next_Weapon, - gamefunc_Previous_Weapon, - gamefunc_Show_Console, - gamefunc_Show_DukeMatch_Scores, - gamefunc_Dpad_Select, - gamefunc_Dpad_Aiming, - gamefunc_AutoRun, - gamefunc_Last_Weapon, - gamefunc_Quick_Save, - gamefunc_Quick_Load, - gamefunc_Alt_Weapon, - gamefunc_Third_Person_View, - gamefunc_Toggle_Crouch, - gamefunc_See_Chase_View, // this was added by Blood - gamefunc_Turn_Around, - gamefunc_Weapon_Fire, - gamefunc_Weapon_Special_Fire, - gamefunc_Aim_Center, - gamefunc_Tilt_Left, - gamefunc_Tilt_Right, - gamefunc_Send_Message, - gamefunc_BeastVision, - gamefunc_CrystalBall, - gamefunc_JumpBoots, - gamefunc_ProximityBombs, - gamefunc_RemoteBombs, - gamefunc_Smoke_Bomb, // and these by ShadowWarrior (todo: There's quite a bit of potential for consolidation here - is it worth it?) - gamefunc_Gas_Bomb, - gamefunc_Flash_Bomb, - gamefunc_Caltrops, - - NUMGAMEFUNCTIONS -}; extern uint8_t KeyboardKeys[NUMGAMEFUNCTIONS][2]; diff --git a/source/common/inputstate.h b/source/common/inputstate.h new file mode 100644 index 000000000..8a310520b --- /dev/null +++ b/source/common/inputstate.h @@ -0,0 +1,177 @@ +#pragma once + +// This encapsulates the entire game-readable input state which previously was spread out across several files. + +// Order is that of EDuke32 by necessity because it exposes the key binds to scripting by index instead of by name. +enum GameFunction_t +{ + gamefunc_Move_Forward, + gamefunc_Move_Backward, + gamefunc_Turn_Left, + gamefunc_Turn_Right, + gamefunc_Strafe, + gamefunc_Fire, + gamefunc_Open, + gamefunc_Run, + gamefunc_Alt_Fire, + gamefunc_Jump, + gamefunc_Crouch, + gamefunc_Look_Up, + gamefunc_Look_Down, + gamefunc_Look_Left, + gamefunc_Look_Right, + gamefunc_Strafe_Left, + gamefunc_Strafe_Right, + gamefunc_Aim_Up, + gamefunc_Aim_Down, + gamefunc_Weapon_1, + gamefunc_Weapon_2, + gamefunc_Weapon_3, + gamefunc_Weapon_4, + gamefunc_Weapon_5, + gamefunc_Weapon_6, + gamefunc_Weapon_7, + gamefunc_Weapon_8, + gamefunc_Weapon_9, + gamefunc_Weapon_10, + gamefunc_Inventory, + gamefunc_Inventory_Use = gamefunc_Inventory, + gamefunc_Inventory_Left, + gamefunc_Inventory_Right, + gamefunc_Holo_Duke, + gamefunc_Jetpack, + gamefunc_NightVision, + gamefunc_Night_Vision = gamefunc_NightVision, + gamefunc_MedKit, + gamefunc_Med_Kit = gamefunc_MedKit, + gamefunc_TurnAround, + gamefunc_SendMessage, + gamefunc_Map, + gamefunc_Map_Toggle = gamefunc_Map, + gamefunc_Shrink_Screen, + gamefunc_Enlarge_Screen, + gamefunc_Center_View, + gamefunc_Holster_Weapon, + gamefunc_Show_Opponents_Weapon, + gamefunc_Map_Follow_Mode, + gamefunc_See_Coop_View, + gamefunc_See_Co_Op_View = gamefunc_See_Coop_View, + gamefunc_Mouse_Aiming, + gamefunc_Toggle_Crosshair, + gamefunc_Steroids, + gamefunc_Quick_Kick, + gamefunc_Next_Weapon, + gamefunc_Previous_Weapon, + gamefunc_Show_Console, + gamefunc_Show_DukeMatch_Scores, + gamefunc_Dpad_Select, + gamefunc_Dpad_Aiming, + gamefunc_AutoRun, + gamefunc_Last_Weapon, + gamefunc_Quick_Save, + gamefunc_Quick_Load, + gamefunc_Alt_Weapon, + gamefunc_Third_Person_View, + gamefunc_Toggle_Crouch, + gamefunc_See_Chase_View, // this was added by Blood + gamefunc_Turn_Around, + gamefunc_Weapon_Fire, + gamefunc_Weapon_Special_Fire, + gamefunc_Aim_Center, + gamefunc_Tilt_Left, + gamefunc_Tilt_Right, + gamefunc_Send_Message, + gamefunc_BeastVision, + gamefunc_CrystalBall, + gamefunc_JumpBoots, + gamefunc_ProximityBombs, + gamefunc_RemoteBombs, + gamefunc_Smoke_Bomb, // and these by ShadowWarrior (todo: There's quite a bit of potential for consolidation here - is it worth it?) + gamefunc_Gas_Bomb, + gamefunc_Flash_Bomb, + gamefunc_Caltrops, + + NUMGAMEFUNCTIONS +}; + + +class InputState +{ + + FixedBitArray ButtonState, ButtonHeldState; +public: + + bool BUTTON(int x) + { + return ButtonState[x]; + } + + bool BUTTONHELD(int x) + { + return ButtonHeldState[x]; + } + + void SetButton(int x, bool set = true) + { + if (set) ButtonState.Set(x); + else ButtonState.Clear(x); + } + + void SetButtonHeld(int x, bool set = true) + { + if (set) ButtonHeldState.Set(x); + else ButtonHeldState.Clear(x); + } + + void ClearButton(int x) + { + ButtonState.Clear(x); + } + + void ClearButtonHeld(int x) + { + ButtonHeldState.Clear(x); + } + + void ClearButtonState() + { + ButtonState.Zero(); + ButtonHeldState.Zero(); + } + + void PrepareState() + { + ButtonHeldState = ButtonState; + ButtonState.Zero(); + } + + +}; + + +extern InputState inputState; + +inline bool BUTTON(int x) +{ + return inputState.BUTTON(x); +} + +inline bool BUTTONHELD(int x) +{ + return inputState.BUTTONHELD(x); +} + +inline bool BUTTONJUSTPRESSED(int x) +{ + return (BUTTON(x) && !BUTTONHELD(x)); +} + +inline bool BUTTONRELEASED(int x) +{ + return (!BUTTON(x) && BUTTONHELD(x)); +} + +inline bool BUTTONSTATECHANGED(int x) +{ + return (BUTTON(x) != BUTTONHELD(x)); +} diff --git a/source/common/utility/tarray.h b/source/common/utility/tarray.h index 5b39dbceb..486e120e0 100644 --- a/source/common/utility/tarray.h +++ b/source/common/utility/tarray.h @@ -1457,6 +1457,40 @@ public: }; +template +class FixedBitArray +{ + uint8_t bytes[(size + 7) / 8]; + +public: + + bool operator[](size_t index) const + { + return !!(bytes[index >> 3] & (1 << (index & 7))); + } + + void Set(size_t index, bool set = true) + { + if (!set) Clear(index); + else bytes[index >> 3] |= (1 << (index & 7)); + } + + void Clear(size_t index) + { + bytes[index >> 3] &= ~(1 << (index & 7)); + } + + constexpr unsigned Size() const + { + return size; + } + + void Zero() + { + memset(&bytes[0], 0, sizeof(bytes)); + } +}; + // A wrapper to externally stored data. // I would have expected something for this in the stl, but std::span is only in C++20. template diff --git a/source/mact/include/control.h b/source/mact/include/control.h index 09ea7e8f3..51377881a 100644 --- a/source/mact/include/control.h +++ b/source/mact/include/control.h @@ -37,6 +37,7 @@ Modifications for JonoF's port by Jonathon Fowler (jf@jonof.id.au) #define control_public_h_ #include "tarray.h" +#include "inputstate.h" //*************************************************************************** // @@ -44,37 +45,6 @@ Modifications for JonoF's port by Jonathon Fowler (jf@jonof.id.au) // //*************************************************************************** -#define MAXGAMEBUTTONS 80 - -extern BitArray CONTROL_ButtonState, CONTROL_ButtonHeldState; - -inline bool BUTTON(int x) -{ - return CONTROL_ButtonState[x]; -} - -inline bool BUTTONHELD(int x) -{ - return CONTROL_ButtonHeldState[x]; -} - -inline bool BUTTONJUSTPRESSED(int x) -{ - return (BUTTON(x) && !BUTTONHELD(x)); -} - -inline bool BUTTONRELEASED(int x) -{ - return (!BUTTON(x) && BUTTONHELD(x)); -} - -inline bool BUTTONSTATECHANGED(int x) -{ - return (BUTTON(x) != BUTTONHELD(x)); -} - - - //*************************************************************************** // // TYPEDEFS diff --git a/source/mact/src/control.cpp b/source/mact/src/control.cpp index c93386ba8..322ec553c 100644 --- a/source/mact/src/control.cpp +++ b/source/mact/src/control.cpp @@ -22,9 +22,6 @@ bool CONTROL_MousePresent = false; bool CONTROL_JoyPresent = false; bool CONTROL_JoystickEnabled = false; -BitArray CONTROL_ButtonState(MAXGAMEBUTTONS); -BitArray CONTROL_ButtonHeldState(MAXGAMEBUTTONS); - LastSeenInput CONTROL_LastSeenInput; float CONTROL_MouseSensitivity = DEFAULTMOUSESENSITIVITY; @@ -614,10 +611,6 @@ static void CONTROL_PollDevices(ControlInfo *info) { memset(info, 0, sizeof(ControlInfo)); -#ifdef __ANDROID__ - CONTROL_Android_PollDevices(info); -#endif - if (CONTROL_MouseEnabled) CONTROL_GetMouseDelta(info); @@ -743,14 +736,13 @@ void CONTROL_ClearButton(int whichbutton) CONTROL_Android_ClearButton(whichbutton); #endif - CONTROL_ButtonState.Clear(whichbutton); + inputState.ClearButton(whichbutton); CONTROL_Flags[whichbutton].cleared = TRUE; } void CONTROL_ClearAllButtons(void) { - CONTROL_ButtonHeldState.Zero(); - CONTROL_ButtonState.Zero(); + inputState.ClearButtonState(); for (auto & c : CONTROL_Flags) c.cleared = TRUE; @@ -816,8 +808,7 @@ static void CONTROL_GetFunctionInput(void) CONTROL_ButtonFunctionState(CONTROL_ButtonFlags); CONTROL_AxisFunctionState(CONTROL_ButtonFlags); - std::swap(CONTROL_ButtonHeldState, CONTROL_ButtonState); - CONTROL_ButtonState.Zero(); + inputState.PrepareState(); int i = CONTROL_NUM_FLAGS-1; @@ -825,7 +816,7 @@ static void CONTROL_GetFunctionInput(void) { CONTROL_SetFlag(i, /*CONTROL_KeyboardFunctionPressed(i) | */CONTROL_ButtonFlags[i]); - if (CONTROL_Flags[i].cleared == FALSE) CONTROL_ButtonState.Set(i, CONTROL_Flags[i].active); + if (CONTROL_Flags[i].cleared == FALSE) inputState.SetButton(i, CONTROL_Flags[i].active); else if (CONTROL_Flags[i].active == FALSE) CONTROL_Flags[i].cleared = 0; } while (i--); @@ -835,9 +826,6 @@ static void CONTROL_GetFunctionInput(void) void CONTROL_GetInput(ControlInfo *info) { -#ifdef __ANDROID__ - CONTROL_Android_PollDevices(info); -#endif CONTROL_PollDevices(info); CONTROL_GetFunctionInput(); inputchecked = 1; @@ -881,16 +869,7 @@ bool CONTROL_Startup(controltype which, int32_t(*TimeFunction)(void), int32_t ti CONTROL_ResetJoystickValues(); -#ifdef GEKKO - if (CONTROL_MousePresent) - initprintf("CONTROL_Startup: Mouse Present\n"); - - if (CONTROL_JoyPresent) - initprintf("CONTROL_Startup: Joystick Present\n"); -#endif - - CONTROL_ButtonState.Zero(); - CONTROL_ButtonHeldState.Zero(); + inputState.ClearButtonState(); for (auto & CONTROL_Flag : CONTROL_Flags) CONTROL_Flag.used = FALSE;