From 8dacdf295181c6f9e52a07293aa61c471c43d370 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sat, 11 Apr 2020 18:09:51 +0200 Subject: [PATCH] - use an array to store the buttons. This puts a lot less knowledge about the game's features into the low level code. --- src/am_map.cpp | 31 +++-- src/common/utility/findfile.cpp | 2 - src/console/c_bind.cpp | 81 ++++++++--- src/console/c_buttons.cpp | 237 ++++++++++++++++---------------- src/console/c_buttons.h | 88 ++++++++---- src/console/c_dispatch.cpp | 30 +--- src/ct_chat.cpp | 3 +- src/d_buttons.h | 39 ++++++ src/d_main.cpp | 58 +++++++- src/g_game.cpp | 91 ++++++------ src/g_level.cpp | 2 +- src/menu/menu.cpp | 2 +- src/win32/i_input.cpp | 2 +- 13 files changed, 410 insertions(+), 256 deletions(-) create mode 100644 src/d_buttons.h diff --git a/src/am_map.cpp b/src/am_map.cpp index 2aea59656..77cf0d5ad 100644 --- a/src/am_map.cpp +++ b/src/am_map.cpp @@ -66,6 +66,7 @@ #include "actorinlines.h" #include "earcut.hpp" #include "c_buttons.h" +#include "d_buttons.h" //============================================================================= @@ -1430,7 +1431,7 @@ bool DAutomap::Responder (event_t *ev, bool last) { // check for am_pan* and ignore in follow mode const char *defbind = AutomapBindings.GetBind(ev->data1); - if (!strnicmp(defbind, "+am_pan", 7)) return false; + if (defbind && !strnicmp(defbind, "+am_pan", 7)) return false; } bool res = C_DoKey(ev, &AutomapBindings, nullptr); @@ -1439,7 +1440,7 @@ bool DAutomap::Responder (event_t *ev, bool last) // If this is a release event we also need to check if it released a button in the main Bindings // so that that button does not get stuck. const char *defbind = Bindings.GetBind(ev->data1); - return (defbind[0] != '+'); // Let G_Responder handle button releases + return (!defbind || defbind[0] != '+'); // Let G_Responder handle button releases } return res; } @@ -1465,11 +1466,11 @@ void DAutomap::changeWindowScale () { mtof_zoommul = M_ZOOMOUT / -am_zoomdir; } - else if (Button_AM_ZoomIn.bDown) + else if (buttonMap.ButtonDown(Button_AM_ZoomIn)) { mtof_zoommul = M_ZOOMIN; } - else if (Button_AM_ZoomOut.bDown) + else if (buttonMap.ButtonDown(Button_AM_ZoomOut)) { mtof_zoommul = M_ZOOMOUT; } @@ -1546,14 +1547,14 @@ void DAutomap::Ticker () else { m_paninc.x = m_paninc.y = 0; - if (Button_AM_PanLeft.bDown) m_paninc.x -= FTOM(F_PANINC); - if (Button_AM_PanRight.bDown) m_paninc.x += FTOM(F_PANINC); - if (Button_AM_PanUp.bDown) m_paninc.y += FTOM(F_PANINC); - if (Button_AM_PanDown.bDown) m_paninc.y -= FTOM(F_PANINC); + if (buttonMap.ButtonDown(Button_AM_PanLeft)) m_paninc.x -= FTOM(F_PANINC); + if (buttonMap.ButtonDown(Button_AM_PanRight)) m_paninc.x += FTOM(F_PANINC); + if (buttonMap.ButtonDown(Button_AM_PanUp)) m_paninc.y += FTOM(F_PANINC); + if (buttonMap.ButtonDown(Button_AM_PanDown)) m_paninc.y -= FTOM(F_PANINC); } // Change the zoom if necessary - if (Button_AM_ZoomIn.bDown || Button_AM_ZoomOut.bDown || am_zoomdir != 0) + if (buttonMap.ButtonDown(Button_AM_ZoomIn) || buttonMap.ButtonDown(Button_AM_ZoomOut) || am_zoomdir != 0) changeWindowScale(); // Change x,y location @@ -3338,12 +3339,12 @@ void AM_ToggleMap() if (!automapactive) { // Reset AM buttons - Button_AM_PanLeft.Reset(); - Button_AM_PanRight.Reset(); - Button_AM_PanUp.Reset(); - Button_AM_PanDown.Reset(); - Button_AM_ZoomIn.Reset(); - Button_AM_ZoomOut.Reset(); + buttonMap.ClearButton(Button_AM_PanLeft); + buttonMap.ClearButton(Button_AM_PanRight); + buttonMap.ClearButton(Button_AM_PanUp); + buttonMap.ClearButton(Button_AM_PanDown); + buttonMap.ClearButton(Button_AM_ZoomIn); + buttonMap.ClearButton(Button_AM_ZoomOut); primaryLevel->automap->startDisplay(); automapactive = true; diff --git a/src/common/utility/findfile.cpp b/src/common/utility/findfile.cpp index 1017adc8c..332f0db88 100644 --- a/src/common/utility/findfile.cpp +++ b/src/common/utility/findfile.cpp @@ -191,7 +191,6 @@ const char *I_FindName(findstate_t *fileinfo) #endif - //========================================================================== // // D_AddFile @@ -361,7 +360,6 @@ void D_AddDirectory(TArray& wadfiles, const char* dir, const char *file } } - //========================================================================== // // BaseFileSearch diff --git a/src/console/c_bind.cpp b/src/console/c_bind.cpp index 4d13708e9..a18d766a3 100644 --- a/src/console/c_bind.cpp +++ b/src/console/c_bind.cpp @@ -32,21 +32,24 @@ ** */ -#include "doomtype.h" -#include "doomdef.h" -#include "c_dispatch.h" +#include + +#include "cmdlib.h" +#include "keydef.h" +#include "c_commandline.h" #include "c_bind.h" -#include "g_level.h" -#include "hu_stuff.h" +#include "c_dispatch.h" #include "configfile.h" -#include "d_event.h" #include "filesystem.h" #include "templates.h" -#include "dobject.h" -#include "vm.h" #include "i_time.h" -#include "menu/menu.h" -#include "v_text.h" +#include "printf.h" +#include "sc_man.h" +#include "c_cvars.h" + +#include "d_event.h" + +#include "hu_stuff.h" // for chatmodeon const char *KeyNames[NUM_KEYS] = { @@ -705,9 +708,17 @@ void ReadBindings(int lump, bool override) // //============================================================================= -void C_BindDefaults () +void C_SetDefaultKeys(const char* baseconfig) { - int lump, lastlump = 0; + auto lump = fileSystem.CheckNumForFullName("engine/commonbinds.txt"); + if (lump >= 0) ReadBindings(lump, true); + int lastlump = 0; + + while ((lump = fileSystem.FindLumpFullName(baseconfig, &lastlump)) != -1) + { + if (fileSystem.GetFileContainer(lump) > 0) break; + ReadBindings(lump, true); + } while ((lump = fileSystem.FindLump("DEFBINDS", &lastlump)) != -1) { @@ -715,15 +726,41 @@ void C_BindDefaults () } } -CCMD(binddefaults) +//============================================================================= +// +// +// +//============================================================================= +CVAR(Int, cl_defaultconfiguration, 2, CVAR_ARCHIVE | CVAR_GLOBALCONFIG) + + +void C_BindDefaults() { - C_BindDefaults (); + C_SetDefaultKeys(cl_defaultconfiguration == 1 ? "engine/origbinds.txt" : cl_defaultconfiguration == 2 ? "engine/leftbinds.txt" : "engine/defbinds.txt"); } -void C_SetDefaultBindings () +CCMD(controlpreset) { - C_UnbindAll (); - C_BindDefaults (); + if (argv.argc() < 2) + { + Printf("Usage: Controlpreset {0,1,2}\n"); + return; + } + int v = atoi(argv[1]); + if (v < 0 || v > 2) return; + cl_defaultconfiguration = v; + C_BindDefaults(); +} + +CCMD(binddefaults) +{ + C_BindDefaults(); +} + +void C_SetDefaultBindings() +{ + C_UnbindAll(); + C_BindDefaults(); } //============================================================================= @@ -781,13 +818,13 @@ bool C_DoKey (event_t *ev, FKeyBindings *binds, FKeyBindings *doublebinds) dclick = false; } + if (ev->type == EV_KeyUp && binding[0] != '+') + { + return false; + } + if (!binding.IsEmpty() && (chatmodeon == 0 || ev->data1 < 256)) { - if (ev->type == EV_KeyUp && binding[0] != '+') - { - return false; - } - char *copy = binding.LockBuffer(); if (ev->type == EV_KeyUp) diff --git a/src/console/c_buttons.cpp b/src/console/c_buttons.cpp index ea158c99d..b82f84549 100644 --- a/src/console/c_buttons.cpp +++ b/src/console/c_buttons.cpp @@ -4,6 +4,7 @@ ** **--------------------------------------------------------------------------- ** Copyright 1998-2007 Randy Heit +** Copyright 2019 Christoph Oelckers ** All rights reserved. ** ** Redistribution and use in source and binary forms, with or without @@ -39,76 +40,118 @@ #include "cmdlib.h" #include "c_console.h" - -FButtonStatus Button_Mlook, Button_Klook, Button_Use, Button_AltAttack, - Button_Attack, Button_Speed, Button_MoveRight, Button_MoveLeft, - Button_Strafe, Button_LookDown, Button_LookUp, Button_Back, - Button_Forward, Button_Right, Button_Left, Button_MoveDown, - Button_MoveUp, Button_Jump, Button_ShowScores, Button_Crouch, - Button_Zoom, Button_Reload, - Button_User1, Button_User2, Button_User3, Button_User4, - Button_AM_PanLeft, Button_AM_PanRight, Button_AM_PanDown, Button_AM_PanUp, - Button_AM_ZoomIn, Button_AM_ZoomOut; +ButtonMap buttonMap; -// To add new actions, go to the console and type "key ". -// This will give you the key value to use in the first column. Then -// insert your new action into this list so that the keys remain sorted -// in ascending order. No two keys can be identical. If yours matches -// an existing key, change the name of your action. -FActionMap ActionMaps[] = + +//============================================================================= +// +// +// +//============================================================================= + +void ButtonMap::SetButtons(const char** names, int count) { - { &Button_AM_PanLeft, 0x0d52d67b, "am_panleft"}, - { &Button_User2, 0x125f5226, "user2" }, - { &Button_Jump, 0x1eefa611, "jump" }, - { &Button_Right, 0x201f1c55, "right" }, - { &Button_Zoom, 0x20ccc4d5, "zoom" }, - { &Button_Back, 0x23a99cd7, "back" }, - { &Button_AM_ZoomIn, 0x41df90c2, "am_zoomin"}, - { &Button_Reload, 0x426b69e7, "reload" }, - { &Button_LookDown, 0x4463f43a, "lookdown" }, - { &Button_AM_ZoomOut, 0x51f7a334, "am_zoomout"}, - { &Button_User4, 0x534c30ee, "user4" }, - { &Button_Attack, 0x5622bf42, "attack" }, - { &Button_User1, 0x577712d0, "user1" }, - { &Button_Klook, 0x57c25cb2, "klook" }, - { &Button_Forward, 0x59f3e907, "forward" }, - { &Button_MoveDown, 0x6167ce99, "movedown" }, - { &Button_AltAttack, 0x676885b8, "altattack" }, - { &Button_MoveLeft, 0x6fa41b84, "moveleft" }, - { &Button_MoveRight, 0x818f08e6, "moveright" }, - { &Button_AM_PanRight, 0x8197097b, "am_panright"}, - { &Button_AM_PanUp, 0x8d89955e, "am_panup"} , - { &Button_Mlook, 0xa2b62d8b, "mlook" }, - { &Button_Crouch, 0xab2c3e71, "crouch" }, - { &Button_Left, 0xb000b483, "left" }, - { &Button_LookUp, 0xb62b1e49, "lookup" }, - { &Button_User3, 0xb6f8fe92, "user3" }, - { &Button_Strafe, 0xb7e6a54b, "strafe" }, - { &Button_AM_PanDown, 0xce301c81, "am_pandown"}, - { &Button_ShowScores, 0xd5897c73, "showscores" }, - { &Button_Speed, 0xe0ccb317, "speed" }, - { &Button_Use, 0xe0cfc260, "use" }, - { &Button_MoveUp, 0xfdd701c7, "moveup" }, -}; -#define NUM_ACTIONS countof(ActionMaps) - - -// FindButton scans through the actionbits[] array -// for a matching key and returns an index or -1 if -// the key could not be found. This uses binary search, -// so actionbits[] must be sorted in ascending order. - -FButtonStatus *FindButton (unsigned int key) -{ - const FActionMap *bit; - - bit = BinarySearch - (ActionMaps, NUM_ACTIONS, &FActionMap::Key, key); - return bit ? bit->Button : NULL; + Buttons.Resize(count); + NumToName.Resize(count); + NameToNum.Clear(); + for(int i = 0; i < count; i++) + { + Buttons[i] = {}; + NameToNum.Insert(names[i], i); + NumToName[i] = names[i]; + } } +//============================================================================= +// +// +// +//============================================================================= + +int ButtonMap::ListActionCommands (const char *pattern) +{ + char matcher[32]; + int count = 0; + + for (auto& btn : NumToName) + { + if (pattern == NULL || CheckWildcards (pattern, + (mysnprintf (matcher, countof(matcher), "+%s", btn.GetChars()), matcher))) + { + Printf ("+%s\n", btn.GetChars()); + count++; + } + if (pattern == NULL || CheckWildcards (pattern, + (mysnprintf (matcher, countof(matcher), "-%s", btn.GetChars()), matcher))) + { + Printf ("-%s\n", btn.GetChars()); + count++; + } + } + return count; +} + + +//============================================================================= +// +// +// +//============================================================================= + +int ButtonMap::FindButtonIndex (const char *key, int funclen) const +{ + if (!key) return -1; + + FName name = funclen == -1? FName(key, true) : FName(key, funclen, true); + if (name == NAME_None) return -1; + + auto res = NameToNum.CheckKey(name); + if (!res) return -1; + + return *res; +} + + +//============================================================================= +// +// +// +//============================================================================= + +void ButtonMap::ResetButtonTriggers () +{ + for (auto &button : Buttons) + { + button.ResetTriggers (); + } +} + +//============================================================================= +// +// +// +//============================================================================= + +void ButtonMap::ResetButtonStates () +{ + for (auto &btn : Buttons) + { + if (!btn.bReleaseLock) + { + btn.ReleaseKey (0); + } + btn.ResetTriggers (); + } +} + +//============================================================================= +// +// +// +//============================================================================= + bool FButtonStatus::PressKey (int keynum) { int i, open; @@ -149,6 +192,12 @@ bool FButtonStatus::PressKey (int keynum) return !wasdown; } +//============================================================================= +// +// +// +//============================================================================= + bool FButtonStatus::ReleaseKey (int keynum) { int i, numdown, match; @@ -193,64 +242,22 @@ bool FButtonStatus::ReleaseKey (int keynum) return wasdown && !bDown; } -void ResetButtonTriggers () -{ - for (int i = NUM_ACTIONS-1; i >= 0; --i) - { - ActionMaps[i].Button->ResetTriggers (); - } -} +//============================================================================= +// +// +// +//============================================================================= -void ResetButtonStates () -{ - for (int i = NUM_ACTIONS-1; i >= 0; --i) - { - FButtonStatus *button = ActionMaps[i].Button; - - if (button != &Button_Mlook && button != &Button_Klook) - { - button->ReleaseKey (0); - } - button->ResetTriggers (); - } -} - - - -int ListActionCommands (const char *pattern) -{ - char matcher[16]; - unsigned int i; - int count = 0; - - for (i = 0; i < NUM_ACTIONS; ++i) - { - if (pattern == NULL || CheckWildcards (pattern, - (mysnprintf (matcher, countof(matcher), "+%s", ActionMaps[i].Name), matcher))) - { - Printf ("+%s\n", ActionMaps[i].Name); - count++; - } - if (pattern == NULL || CheckWildcards (pattern, - (mysnprintf (matcher, countof(matcher), "-%s", ActionMaps[i].Name), matcher))) - { - Printf ("-%s\n", ActionMaps[i].Name); - count++; - } - } - return count; -} - -void AddButtonTabCommands() +void ButtonMap::AddButtonTabCommands() { // Add all the action commands for tab completion - for (int i = 0; i < NUM_ACTIONS; i++) + for (auto& btn : NumToName) { char tname[16]; - strcpy (&tname[1], ActionMaps[i].Name); + strcpy (&tname[1], btn.GetChars()); tname[0] = '+'; C_AddTabCommand (tname); tname[0] = '-'; C_AddTabCommand (tname); } -} \ No newline at end of file +} diff --git a/src/console/c_buttons.h b/src/console/c_buttons.h index 7f753359b..3567a8548 100644 --- a/src/console/c_buttons.h +++ b/src/console/c_buttons.h @@ -1,15 +1,21 @@ #pragma once +#include +#include "tarray.h" +#include "name.h" + // Actions struct FButtonStatus { enum { MAX_KEYS = 6 }; // Maximum number of keys that can press this button uint16_t Keys[MAX_KEYS]; - uint8_t bDown; // Button is down right now - uint8_t bWentDown; // Button went down this tic - uint8_t bWentUp; // Button went up this tic - uint8_t padTo16Bytes; + bool bDown; // Button is down right now + bool bWentDown; // Button went down this tic + bool bWentUp; // Button went up this tic + bool bReleaseLock; // Lock ReleaseKey call in ResetButtonStates + void (*PressHandler)(); // for optional game-side customization + void (*ReleaseHandler)(); bool PressKey (int keynum); // Returns true if this key caused the button to be pressed. bool ReleaseKey (int keynum); // Returns true if this key is no longer pressed. @@ -17,27 +23,59 @@ struct FButtonStatus void Reset () { bDown = bWentDown = bWentUp = false; } }; -struct FActionMap +class ButtonMap { - FButtonStatus* Button; - unsigned int Key; // value from passing Name to MakeKey() - char Name[12]; + + TArray Buttons; + TArray NumToName; // The internal name of the button + TMap NameToNum; + +public: + void SetButtons(const char** names, int count); + + int NumButtons() const + { + return Buttons.Size(); + } + + int FindButtonIndex(const char* func, int funclen = -1) const; + + FButtonStatus* FindButton(const char* func, int funclen = -1) + { + int index = FindButtonIndex(func, funclen); + return index > -1 ? &Buttons[index] : nullptr; + } + + FButtonStatus* GetButton(int index) + { + return &Buttons[index]; + } + + void ResetButtonTriggers(); // Call ResetTriggers for all buttons + void ResetButtonStates(); // Same as above, but also clear bDown + int ListActionCommands(const char* pattern); + void AddButtonTabCommands(); + + + bool ButtonDown(int x) const + { + return Buttons[x].bDown; + } + + bool ButtonPressed(int x) const + { + return Buttons[x].bWentDown; + } + + bool ButtonReleased(int x) const + { + return Buttons[x].bWentUp; + } + + void ClearButton(int x) + { + Buttons[x].Reset(); + } }; - -extern FButtonStatus Button_Mlook, Button_Klook, Button_Use, Button_AltAttack, - Button_Attack, Button_Speed, Button_MoveRight, Button_MoveLeft, - Button_Strafe, Button_LookDown, Button_LookUp, Button_Back, - Button_Forward, Button_Right, Button_Left, Button_MoveDown, - Button_MoveUp, Button_Jump, Button_ShowScores, Button_Crouch, - Button_Zoom, Button_Reload, - Button_User1, Button_User2, Button_User3, Button_User4, - Button_AM_PanLeft, Button_AM_PanRight, Button_AM_PanDown, Button_AM_PanUp, - Button_AM_ZoomIn, Button_AM_ZoomOut; -extern bool ParsingKeyConf, UnsafeExecutionContext; - -void ResetButtonTriggers (); // Call ResetTriggers for all buttons -void ResetButtonStates (); // Same as above, but also clear bDown -FButtonStatus *FindButton (unsigned int key); -void AddButtonTabCommands(); -extern FActionMap ActionMaps[]; +extern ButtonMap buttonMap; diff --git a/src/console/c_dispatch.cpp b/src/console/c_dispatch.cpp index 01ccbc3f0..db1d6e25b 100644 --- a/src/console/c_dispatch.cpp +++ b/src/console/c_dispatch.cpp @@ -51,11 +51,6 @@ #include "c_buttons.h" #include "findfile.h" -// Todo: Get rid of -#include "d_net.h" -#include "d_main.h" - - // MACROS ------------------------------------------------------------------ // TYPES ------------------------------------------------------------------- @@ -176,7 +171,6 @@ FString StoredWarp; FConsoleCommand* Commands[FConsoleCommand::HASH_SIZE]; -CVAR (Bool, lookspring, true, CVAR_ARCHIVE); // Generate centerview when -mlook encountered? // PRIVATE DATA DEFINITIONS ------------------------------------------------ @@ -242,22 +236,18 @@ void C_DoCommand (const char *cmd, int keynum) // Check if this is an action if (*beg == '+' || *beg == '-') { - FButtonStatus *button; - - button = FindButton (MakeKey (beg + 1, end - beg - 1)); - if (button != NULL) + auto button = buttonMap.FindButton(beg + 1, int(end - beg - 1)); + if (button != nullptr) { if (*beg == '+') { button->PressKey (keynum); + if (button->PressHandler) button->PressHandler(); } else { button->ReleaseKey (keynum); - if (button == &Button_Mlook && lookspring) - { - Net_WriteByte (DEM_CENTERVIEW); - } + if (button->ReleaseHandler) button->ReleaseHandler(); } return; } @@ -468,14 +458,6 @@ FConsoleCommand* FConsoleCommand::FindByName (const char* name) FConsoleCommand::FConsoleCommand (const char *name, CCmdRun runFunc) : m_RunFunc (runFunc) { - static bool firstTime = true; - - if (firstTime) - { - firstTime = false; - AddButtonTabCommands(); - } - int ag = strcmp (name, "kill"); if (ag == 0) ag=0; @@ -848,14 +830,12 @@ CCMD (alias) } } -int ListActionCommands(const char* pattern); - CCMD (cmdlist) { int count; const char *filter = (argv.argc() == 1 ? NULL : argv[1]); - count = ListActionCommands (filter); + count = buttonMap.ListActionCommands (filter); count += DumpHash (Commands, false, filter); Printf ("%d commands\n", count); } diff --git a/src/ct_chat.cpp b/src/ct_chat.cpp index b807d56dc..1e72ebbdc 100644 --- a/src/ct_chat.cpp +++ b/src/ct_chat.cpp @@ -43,6 +43,7 @@ #include "gstrings.h" #include "vm.h" #include "c_buttons.h" +#include "d_buttons.h" enum { @@ -237,7 +238,7 @@ void CT_Drawer (void) FFont *displayfont = NewConsoleFont; if (players[consoleplayer].camera != NULL && - (Button_ShowScores.bDown || + (buttonMap.ButtonDown(Button_ShowScores) || players[consoleplayer].camera->health <= 0 || SB_ForceActive) && // Don't draw during intermission, since it has its own scoreboard in wi_stuff.cpp. diff --git a/src/d_buttons.h b/src/d_buttons.h new file mode 100644 index 000000000..341ead790 --- /dev/null +++ b/src/d_buttons.h @@ -0,0 +1,39 @@ +#pragma once + +enum +{ + Button_AM_PanLeft, + Button_User2, + Button_Jump, + Button_Right, + Button_Zoom, + Button_Back, + Button_AM_ZoomIn, + Button_Reload, + Button_LookDown, + Button_AM_ZoomOut, + Button_User4, + Button_Attack, + Button_User1, + Button_Klook, + Button_Forward, + Button_MoveDown, + Button_AltAttack, + Button_MoveLeft, + Button_MoveRight, + Button_AM_PanRight, + Button_AM_PanUp, + Button_Mlook, + Button_Crouch, + Button_Left, + Button_LookUp, + Button_User3, + Button_Strafe, + Button_AM_PanDown, + Button_ShowScores, + Button_Speed, + Button_Use, + Button_MoveUp, + NUM_ACTIONS +}; + diff --git a/src/d_main.cpp b/src/d_main.cpp index d6d49cdc0..e28bd3f38 100644 --- a/src/d_main.cpp +++ b/src/d_main.cpp @@ -105,6 +105,7 @@ #include "findfile.h" #include "md5.h" #include "c_buttons.h" +#include "d_buttons.h" EXTERN_CVAR(Bool, hud_althud) EXTERN_CVAR(Int, vr_mode) @@ -423,7 +424,7 @@ void D_PostEvent (const event_t *ev) events[eventhead] = *ev; if (ev->type == EV_Mouse && menuactive == MENU_Off && ConsoleState != c_down && ConsoleState != c_falling && !primaryLevel->localEventManager->Responder(ev) && !paused) { - if (Button_Mlook.bDown || freelook) + if (buttonMap.ButtonDown(Button_Mlook) || freelook) { int look = int(ev->y * m_pitch * mouse_sensitivity * 16.0); if (invertmouse) @@ -431,7 +432,7 @@ void D_PostEvent (const event_t *ev) G_AddViewPitch (look, true); events[eventhead].y = 0; } - if (!Button_Strafe.bDown && !lookstrafe) + if (!buttonMap.ButtonDown(Button_Strafe) && !lookstrafe) { G_AddViewAngle (int(ev->x * m_yaw * mouse_sensitivity * 8.0), true); events[eventhead].x = 0; @@ -2502,6 +2503,50 @@ static void FindStrifeTeaserVoices(FileSystem& fileSystem) } +static const char *DoomButtons[] = +{ + "am_panleft", + "user2" , + "jump" , + "right" , + "zoom" , + "back" , + "am_zoomin", + "reload" , + "lookdown" , + "am_zoomout", + "user4" , + "attack" , + "user1" , + "klook" , + "forward" , + "movedown" , + "altattack" , + "moveleft" , + "moveright" , + "am_panright", + "am_panup" , + "mlook" , + "crouch" , + "left" , + "lookup" , + "user3" , + "strafe" , + "am_pandown", + "showscores" , + "speed" , + "use" , + "moveup" }; + +CVAR(Bool, lookspring, true, CVAR_ARCHIVE); // Generate centerview when -mlook encountered? + +void Mlook_ReleaseHandler() +{ + if (lookspring) + { + Net_WriteByte(DEM_CENTERVIEW); + } +} //========================================================================== // @@ -2518,6 +2563,14 @@ static int D_DoomMain_Internal (void) FString *args; int argcount; FIWadManager *iwad_man; + + // Set up the button list. Mlook and Klook need a bit of extra treatment. + buttonMap.SetButtons(DoomButtons, countof(DoomButtons)); + buttonMap.GetButton(Button_Mlook)->ReleaseHandler = Mlook_ReleaseHandler; + buttonMap.GetButton(Button_Mlook)->bReleaseLock = true; + buttonMap.GetButton(Button_Klook)->bReleaseLock = true; + + // button != &Button_Mlook && button != &Button_Klook) std::set_new_handler(NewFailure); const char *batchout = Args->CheckValue("-errorlog"); @@ -3067,7 +3120,6 @@ int D_DoomMain() } // Unless something really bad happened, the game should only exit through this single point in the code. // No more 'exit', please. - // Todo: Move all engine cleanup here instead of using exit handlers and replace the scattered 'exit' calls with a special exception. D_Cleanup(); CloseNetwork(); GC::FinalGC = true; diff --git a/src/g_game.cpp b/src/g_game.cpp index 06fb928e8..78780fafb 100644 --- a/src/g_game.cpp +++ b/src/g_game.cpp @@ -80,6 +80,7 @@ #include "g_levellocals.h" #include "events.h" #include "c_buttons.h" +#include "d_buttons.h" static FRandom pr_dmspawn ("DMSpawn"); @@ -578,15 +579,15 @@ void G_BuildTiccmd (ticcmd_t *cmd) cmd->consistancy = consistancy[consoleplayer][(maketic/ticdup)%BACKUPTICS]; - strafe = Button_Strafe.bDown; - speed = Button_Speed.bDown ^ (int)cl_run; + strafe = buttonMap.ButtonDown(Button_Strafe); + speed = buttonMap.ButtonDown(Button_Speed) ^ (int)cl_run; forward = side = fly = 0; // [RH] only use two stage accelerative turning on the keyboard // and not the joystick, since we treat the joystick as // the analog device it is. - if (Button_Left.bDown || Button_Right.bDown) + if (buttonMap.ButtonDown(Button_Left) || buttonMap.ButtonDown(Button_Right)) turnheld += ticdup; else turnheld = 0; @@ -594,9 +595,9 @@ void G_BuildTiccmd (ticcmd_t *cmd) // let movement keys cancel each other out if (strafe) { - if (Button_Right.bDown) + if (buttonMap.ButtonDown(Button_Right)) side += sidemove[speed]; - if (Button_Left.bDown) + if (buttonMap.ButtonDown(Button_Left)) side -= sidemove[speed]; } else @@ -606,77 +607,77 @@ void G_BuildTiccmd (ticcmd_t *cmd) if (turnheld < SLOWTURNTICS) tspeed += 2; // slow turn - if (Button_Right.bDown) + if (buttonMap.ButtonDown(Button_Right)) { G_AddViewAngle (*angleturn[tspeed]); } - if (Button_Left.bDown) + if (buttonMap.ButtonDown(Button_Left)) { G_AddViewAngle (-*angleturn[tspeed]); } } - if (Button_LookUp.bDown) + if (buttonMap.ButtonDown(Button_LookUp)) { G_AddViewPitch (lookspeed[speed]); } - if (Button_LookDown.bDown) + if (buttonMap.ButtonDown(Button_LookDown)) { G_AddViewPitch (-lookspeed[speed]); } - if (Button_MoveUp.bDown) + if (buttonMap.ButtonDown(Button_MoveUp)) fly += flyspeed[speed]; - if (Button_MoveDown.bDown) + if (buttonMap.ButtonDown(Button_MoveDown)) fly -= flyspeed[speed]; - if (Button_Klook.bDown) + if (buttonMap.ButtonDown(Button_Klook)) { - if (Button_Forward.bDown) + if (buttonMap.ButtonDown(Button_Forward)) G_AddViewPitch (lookspeed[speed]); - if (Button_Back.bDown) + if (buttonMap.ButtonDown(Button_Back)) G_AddViewPitch (-lookspeed[speed]); } else { - if (Button_Forward.bDown) + if (buttonMap.ButtonDown(Button_Forward)) forward += forwardmove[speed]; - if (Button_Back.bDown) + if (buttonMap.ButtonDown(Button_Back)) forward -= forwardmove[speed]; } - if (Button_MoveRight.bDown) + if (buttonMap.ButtonDown(Button_MoveRight)) side += sidemove[speed]; - if (Button_MoveLeft.bDown) + if (buttonMap.ButtonDown(Button_MoveLeft)) side -= sidemove[speed]; // buttons - if (Button_Attack.bDown) cmd->ucmd.buttons |= BT_ATTACK; - if (Button_AltAttack.bDown) cmd->ucmd.buttons |= BT_ALTATTACK; - if (Button_Use.bDown) cmd->ucmd.buttons |= BT_USE; - if (Button_Jump.bDown) cmd->ucmd.buttons |= BT_JUMP; - if (Button_Crouch.bDown) cmd->ucmd.buttons |= BT_CROUCH; - if (Button_Zoom.bDown) cmd->ucmd.buttons |= BT_ZOOM; - if (Button_Reload.bDown) cmd->ucmd.buttons |= BT_RELOAD; + if (buttonMap.ButtonDown(Button_Attack)) cmd->ucmd.buttons |= BT_ATTACK; + if (buttonMap.ButtonDown(Button_AltAttack)) cmd->ucmd.buttons |= BT_ALTATTACK; + if (buttonMap.ButtonDown(Button_Use)) cmd->ucmd.buttons |= BT_USE; + if (buttonMap.ButtonDown(Button_Jump)) cmd->ucmd.buttons |= BT_JUMP; + if (buttonMap.ButtonDown(Button_Crouch)) cmd->ucmd.buttons |= BT_CROUCH; + if (buttonMap.ButtonDown(Button_Zoom)) cmd->ucmd.buttons |= BT_ZOOM; + if (buttonMap.ButtonDown(Button_Reload)) cmd->ucmd.buttons |= BT_RELOAD; - if (Button_User1.bDown) cmd->ucmd.buttons |= BT_USER1; - if (Button_User2.bDown) cmd->ucmd.buttons |= BT_USER2; - if (Button_User3.bDown) cmd->ucmd.buttons |= BT_USER3; - if (Button_User4.bDown) cmd->ucmd.buttons |= BT_USER4; + if (buttonMap.ButtonDown(Button_User1)) cmd->ucmd.buttons |= BT_USER1; + if (buttonMap.ButtonDown(Button_User2)) cmd->ucmd.buttons |= BT_USER2; + if (buttonMap.ButtonDown(Button_User3)) cmd->ucmd.buttons |= BT_USER3; + if (buttonMap.ButtonDown(Button_User4)) cmd->ucmd.buttons |= BT_USER4; - if (Button_Speed.bDown) cmd->ucmd.buttons |= BT_SPEED; - if (Button_Strafe.bDown) cmd->ucmd.buttons |= BT_STRAFE; - if (Button_MoveRight.bDown) cmd->ucmd.buttons |= BT_MOVERIGHT; - if (Button_MoveLeft.bDown) cmd->ucmd.buttons |= BT_MOVELEFT; - if (Button_LookDown.bDown) cmd->ucmd.buttons |= BT_LOOKDOWN; - if (Button_LookUp.bDown) cmd->ucmd.buttons |= BT_LOOKUP; - if (Button_Back.bDown) cmd->ucmd.buttons |= BT_BACK; - if (Button_Forward.bDown) cmd->ucmd.buttons |= BT_FORWARD; - if (Button_Right.bDown) cmd->ucmd.buttons |= BT_RIGHT; - if (Button_Left.bDown) cmd->ucmd.buttons |= BT_LEFT; - if (Button_MoveDown.bDown) cmd->ucmd.buttons |= BT_MOVEDOWN; - if (Button_MoveUp.bDown) cmd->ucmd.buttons |= BT_MOVEUP; - if (Button_ShowScores.bDown) cmd->ucmd.buttons |= BT_SHOWSCORES; + if (buttonMap.ButtonDown(Button_Speed)) cmd->ucmd.buttons |= BT_SPEED; + if (buttonMap.ButtonDown(Button_Strafe)) cmd->ucmd.buttons |= BT_STRAFE; + if (buttonMap.ButtonDown(Button_MoveRight)) cmd->ucmd.buttons |= BT_MOVERIGHT; + if (buttonMap.ButtonDown(Button_MoveLeft)) cmd->ucmd.buttons |= BT_MOVELEFT; + if (buttonMap.ButtonDown(Button_LookDown)) cmd->ucmd.buttons |= BT_LOOKDOWN; + if (buttonMap.ButtonDown(Button_LookUp)) cmd->ucmd.buttons |= BT_LOOKUP; + if (buttonMap.ButtonDown(Button_Back)) cmd->ucmd.buttons |= BT_BACK; + if (buttonMap.ButtonDown(Button_Forward)) cmd->ucmd.buttons |= BT_FORWARD; + if (buttonMap.ButtonDown(Button_Right)) cmd->ucmd.buttons |= BT_RIGHT; + if (buttonMap.ButtonDown(Button_Left)) cmd->ucmd.buttons |= BT_LEFT; + if (buttonMap.ButtonDown(Button_MoveDown)) cmd->ucmd.buttons |= BT_MOVEDOWN; + if (buttonMap.ButtonDown(Button_MoveUp)) cmd->ucmd.buttons |= BT_MOVEUP; + if (buttonMap.ButtonDown(Button_ShowScores)) cmd->ucmd.buttons |= BT_SHOWSCORES; // Handle joysticks/game controllers. float joyaxes[NUM_JOYAXIS]; @@ -684,12 +685,12 @@ void G_BuildTiccmd (ticcmd_t *cmd) I_GetAxes(joyaxes); // Remap some axes depending on button state. - if (Button_Strafe.bDown || (Button_Mlook.bDown && lookstrafe)) + if (buttonMap.ButtonDown(Button_Strafe) || (buttonMap.ButtonDown(Button_Mlook) && lookstrafe)) { joyaxes[JOYAXIS_Side] = joyaxes[JOYAXIS_Yaw]; joyaxes[JOYAXIS_Yaw] = 0; } - if (Button_Mlook.bDown) + if (buttonMap.ButtonDown(Button_Mlook)) { joyaxes[JOYAXIS_Pitch] = joyaxes[JOYAXIS_Forward]; joyaxes[JOYAXIS_Forward] = 0; @@ -709,7 +710,7 @@ void G_BuildTiccmd (ticcmd_t *cmd) fly += joyint(joyaxes[JOYAXIS_Up] * 2048); // Handle mice. - if (!Button_Mlook.bDown && !freelook) + if (!buttonMap.ButtonDown(Button_Mlook) && !freelook) { forward += (int)((float)mousey * m_forward); } diff --git a/src/g_level.cpp b/src/g_level.cpp index 3b7e88267..b1ba92501 100644 --- a/src/g_level.cpp +++ b/src/g_level.cpp @@ -1053,7 +1053,7 @@ void G_DoLoadLevel(const FString &nextmapname, int position, bool autosave, bool gameaction = ga_nothing; // clear cmd building stuff - ResetButtonStates(); + buttonMap.ResetButtonStates(); SendItemUse = nullptr; SendItemDrop = nullptr; diff --git a/src/menu/menu.cpp b/src/menu/menu.cpp index 2a9d606f0..81f737637 100644 --- a/src/menu/menu.cpp +++ b/src/menu/menu.cpp @@ -360,7 +360,7 @@ void M_StartControlPanel (bool makeSound, bool scaleoverride) if (CurrentMenu != nullptr) return; - ResetButtonStates (); + buttonMap.ResetButtonStates (); for (int i = 0; i < NUM_MKEYS; ++i) { MenuButtons[i].ReleaseKey(0); diff --git a/src/win32/i_input.cpp b/src/win32/i_input.cpp index fb4fd3ae5..ce6b76a0d 100644 --- a/src/win32/i_input.cpp +++ b/src/win32/i_input.cpp @@ -782,7 +782,7 @@ void I_GetEvent () void I_StartTic () { BlockMouseMove--; - ResetButtonTriggers (); + buttonMap.ResetButtonTriggers (); I_CheckGUICapture (); EventHandlerResultForNativeMouse = primaryLevel->localEventManager->CheckRequireMouse(); I_CheckNativeMouse (false, EventHandlerResultForNativeMouse);