Skip to content

Custom hotkey remapping for unit/building production keys in Options#2589

Open
wahidkurdo wants to merge 6 commits intoTheSuperHackers:mainfrom
wahidkurdo:feat/custom-hotkey-remapping
Open

Custom hotkey remapping for unit/building production keys in Options#2589
wahidkurdo wants to merge 6 commits intoTheSuperHackers:mainfrom
wahidkurdo:feat/custom-hotkey-remapping

Conversation

@wahidkurdo
Copy link
Copy Markdown

You can now set Custom Hotkeys in game Options

Test Done its working without crashes

…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/
@greptile-apps
Copy link
Copy Markdown

greptile-apps Bot commented Apr 12, 2026

Greptile Summary

This PR adds in-game custom hotkey remapping for unit/building production keys, extending the existing KeyboardOptionsMenu with faction categories (USA, China, GLA, Other) and persisting user overrides to HotKeyOverrides.ini via a new HotKeyManager override API. The overlay navigation model was reworked to open the keyboard options menu as a manual overlay rather than a Shell push/pop pair. All previously flagged P1 issues (missing HotKeyManager override methods, silent conflict, missing null check on EntryData, and Reset All not clearing overrides) have been addressed.

Confidence Score: 5/5

Safe to merge; all previously reported P1 issues are resolved and only P2 style/heuristic concerns remain.

All P1 issues from previous rounds (missing HotKeyManager API, silent conflict, EntryData null-crash, Reset All not clearing data) are correctly addressed. Remaining findings are P2: a misleading comment in saveOverrides, a broad substring match in detectFaction, and a dead preprocessor block in OptionsMenu.cpp. None affect runtime correctness.

KeyboardOptionsMenu.cpp — detectFaction heuristic may misclassify edge-case button names.

Important Files Changed

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
Loading
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

@wahidkurdo wahidkurdo force-pushed the feat/custom-hotkey-remapping branch from 375b7c7 to 66fca53 Compare April 12, 2026 13:59
- 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
Copy link
Copy Markdown

@xezon xezon left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this AI generated code?

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This comment doesn't make sense

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This comment doesn't make sense

//-------------------------------------------------------------------------------------------------
void OptionsMenuShutdown( WindowLayout *layout, void *userData )
{
// VoiceOptionsUI::Teardown() removed with /voice-only configuration.
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This comment doesn't make sense

}


// Voice-chat options panel disabled — use /voice slash commands instead.
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This comment doesn't make sense

#include "GameNetwork/GameSpy/PeerDefs.h"
#include "GameLogic/GameLogic.h"
#include "GameLogic/ScriptEngine.h"
#if defined(ENABLE_VOICE_CHAT)
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unused code and out of scope for this PR.

UnicodeString str;
GadgetComboBoxReset(comboBoxCategoryList);

// Built-in MetaMap categories (global hotkeys)
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

comment not needed

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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?

@DevGeniusCode
Copy link
Copy Markdown

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
@wahidkurdo wahidkurdo requested review from Skyaero42 and xezon April 30, 2026 16:23
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants