Custom hotkey remapping for unit/building production keys in Options#2589
Custom hotkey remapping for unit/building production keys in Options#2589wahidkurdo wants to merge 6 commits intoTheSuperHackers:mainfrom
Conversation
…n keys - Add per-faction (USA/China/GLA) hotkey categories to KeyboardOptionsMenu - Override-Map in HotKeyManager for persistent key rebinding - Manual overlay layout management (no Shell push/pop conflicts) - ComboBox category selector, ListBox command list, TextEntry key input - Assign/ResetAll buttons with full MetaMap + CommandButton support - Includes .wnd UI layout files under Patch/Window/Menus/
|
| Filename | Overview |
|---|---|
| GeneralsMD/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/Menus/KeyboardOptionsMenu.cpp | Major addition: faction category support (USA/China/GLA/Other) in the hotkey list, new overlay open/close helpers, and null-safety guards throughout; detectFaction uses broad substring matches that may misclassify some buttons (P2). |
| GeneralsMD/Code/GameEngine/Source/GameClient/MessageStream/HotKey.cpp | Adds setOverride, removeOverride, getOverride, clearAllOverrides, loadOverrides, and saveOverrides; logic is correct but saveOverrides has a misleading comment (P2). |
| GeneralsMD/Code/GameEngine/Include/GameClient/HotKey.h | Declares the six new override methods and adds m_hotKeyOverrides (OverrideMap) to HotKeyManager; changes are straightforward and correct. |
| GeneralsMD/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/Menus/OptionsMenu.cpp | Replaces TheShell->push(...) with OpenKeyboardOptionsMenu() and adds explanatory comments; contains a dead #if defined(ENABLE_VOICE_CHAT) preprocessor block (P2). |
| GeneralsMD/Code/GameEngine/Include/GameClient/GUICallbacks.h | Adds OpenKeyboardOptionsMenu and CloseKeyboardOptionsMenu extern declarations; clean, minimal change. |
| GeneralsMD/Code/GameEngine/Source/Common/System/FunctionLexicon.cpp | Registers KeyboardOptionsMenuUpdate in the window-layout update table; trivial, correct change. |
| Patch/README.md | New installation guide explaining how to copy .wnd patch files; well-written and accurate. |
Sequence Diagram
sequenceDiagram
participant User
participant OptionsMenu
participant KeyboardOptionsMenu
participant HotKeyManager
participant HotKeyOverrides.ini
User->>OptionsMenu: Click "Keyboard Options"
OptionsMenu->>KeyboardOptionsMenu: OpenKeyboardOptionsMenu()
KeyboardOptionsMenu->>OptionsMenu: Hide OptionsMenu overlay
KeyboardOptionsMenu->>KeyboardOptionsMenu: winCreateLayout + runInit
User->>KeyboardOptionsMenu: Select faction category
KeyboardOptionsMenu->>HotKeyManager: getOverride(cmdButtonName)
HotKeyManager-->>KeyboardOptionsMenu: override key (or empty)
KeyboardOptionsMenu->>KeyboardOptionsMenu: fillCommandListBoxForFaction()
User->>KeyboardOptionsMenu: Select command, type new key, click Assign
KeyboardOptionsMenu->>KeyboardOptionsMenu: Conflict check against faction list
KeyboardOptionsMenu->>HotKeyManager: setOverride(name, newKey)
HotKeyManager->>HotKeyOverrides.ini: saveOverrides()
User->>KeyboardOptionsMenu: Click "Reset All"
KeyboardOptionsMenu->>HotKeyManager: clearAllOverrides()
HotKeyManager->>HotKeyOverrides.ini: saveOverrides() (empty)
User->>KeyboardOptionsMenu: Click "Back"
KeyboardOptionsMenu->>KeyboardOptionsMenu: CloseKeyboardOptionsMenu()
KeyboardOptionsMenu->>OptionsMenu: Show OptionsMenu overlay again
Prompt To Fix All With AI
Fix the following 3 code review issues. Work through them one at a time, proposing concise fixes.
---
### Issue 1 of 3
GeneralsMD/Code/GameEngine/Source/GameClient/MessageStream/HotKey.cpp:271-272
**Misleading "overwrite completely" comment**
The comment on the `prefs.load()` call says "don't bother loading existing file; we overwrite completely", but the code immediately loads the existing file and then surgically removes only `HotKey_`-prefixed entries, preserving any other keys. The real intent (preserve non-hotkey entries) is the right approach, but the comment states the opposite and will confuse future readers.
```suggestion
// Load existing file so non-hotkey entries are preserved; we only overwrite HotKey_ entries.
prefs.load(HOTKEY_OVERRIDES_FILENAME);
```
### Issue 2 of 3
GeneralsMD/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/Menus/KeyboardOptionsMenu.cpp:146-161
**`detectFaction` substring matching causes false-positive GLA assignments**
`strstr(l, "gla")` matches any command button whose lowercase name contains `"gla"` as a substring — for example a hypothetical `"GlareEffect"` button would be binned under GLA. Similarly `"usa"` would catch any name with those three letters in sequence. Given that ZH CommandButton names follow patterns like `"Command_GLA_..."`, a prefix check (e.g. `strncmp` against `"gla_"` / `"china_"` / `"usa_"`) or an explicit allow-list of known prefixes would avoid misclassification.
### Issue 3 of 3
GeneralsMD/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/Menus/OptionsMenu.cpp:74-77
**Dead `#if defined(ENABLE_VOICE_CHAT)` block wraps a commented-out include**
The preprocessor block will never be active because its only content is a comment (the `#include` is already commented out). It adds noise without benefit and could mislead someone into thinking voice-chat code is conditionally compiled here. The entire `#if … #endif` block can be removed.
Reviews (6): Last reviewed commit: "fix: address code review feedback" | Re-trigger Greptile
375b7c7 to
66fca53
Compare
- Show conflict warning in description text when duplicate hotkey detected - Replace NULL with nullptr in runInit call - Include HotKey.h and HotKey.cpp with override methods
- Show conflict warning in description text when duplicate hotkey detected - Replace NULL with nullptr in runInit call - Include HotKey.h and HotKey.cpp with override methods
There was a problem hiding this comment.
We do not add game data files to this repository. You will need to document the data changes that are required to use the new code.
There was a problem hiding this comment.
The Hotkey option was already in the game but hidden during EA never finished. The code consists of AI prompts; no one is going to write hundreds of lines of code without help from Claude.
i already pushed the README.md for how to use it. The Only Problem is that you need the Window-Menus files in game Folder
There was a problem hiding this comment.
The code consists of AI prompts; no one is going to write hundreds of lines of code without help from Claude.
Do you think that EA had AI when they wrote hunderds of thousands of line of code for the generals and zero hour games?
There was a problem hiding this comment.
The code consists of AI prompts; no one is going to write hundreds of lines of code without help from Claude.
Do you think that EA had AI when they wrote hunderds of thousands of line of code for the generals and zero hour games?
They got paid for it and we dont
| } | ||
| else if (controlID == buttonAccept ) | ||
| { | ||
| // VoiceOptionsUI::Save() removed — /voice slash commands persist directly. |
There was a problem hiding this comment.
This comment doesn't make sense
i sent a pull request before for generalsOnline voice chat this was for it
| GameWindow *control = (GameWindow *)mData1; | ||
| Int controlID = control->winGetWindowId(); | ||
|
|
||
| // VoiceOptionsUI event routing removed — /voice-only configuration. |
| //------------------------------------------------------------------------------------------------- | ||
| void OptionsMenuShutdown( WindowLayout *layout, void *userData ) | ||
| { | ||
| // VoiceOptionsUI::Teardown() removed with /voice-only configuration. |
| } | ||
|
|
||
|
|
||
| // Voice-chat options panel disabled — use /voice slash commands instead. |
| #include "GameNetwork/GameSpy/PeerDefs.h" | ||
| #include "GameLogic/GameLogic.h" | ||
| #include "GameLogic/ScriptEngine.h" | ||
| #if defined(ENABLE_VOICE_CHAT) |
There was a problem hiding this comment.
Unused code and out of scope for this PR.
| UnicodeString str; | ||
| GadgetComboBoxReset(comboBoxCategoryList); | ||
|
|
||
| // Built-in MetaMap categories (global hotkeys) |
There was a problem hiding this comment.
The code consists of AI prompts; no one is going to write hundreds of lines of code without help from Claude.
Do you think that EA had AI when they wrote hunderds of thousands of line of code for the generals and zero hour games?
|
Hey @wahidkurdo , are you still working on this? |
- Show conflict warning in description text when duplicate hotkey detected - Add null check on EntryData in faction assign path - Replace NULL with nullptr in runInit and MessageBoxA calls - Add strncmp prefix validation in loadOverrides - Include HotKey.h and HotKey.cpp with override methods
- Show conflict warning in description text when duplicate hotkey detected - Add null check on EntryData in faction assign path - Replace NULL with nullptr in runInit and MessageBoxA calls - Add strncmp prefix validation in loadOverrides - Include HotKey.h and HotKey.cpp with override methods
You can now set Custom Hotkeys in game Options
Test Done its working without crashes