Files
sacred_k/docs/options.md
T
khallaandClaude Opus 5.5 70673dc301 Rename project to sacredK
sacred_re.dll/.exe/.ini/.log/_crash files are now sacredK.*; inventory saves
with the old "sacred_re.inventory" format id still load.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-19 22:07:14 +02:00

112 lines
6.6 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Options window: tabs and key bindings
Request (2026-10-18): the settings screen gets three tabs: *Allgemein*,
*Beute* (loot filter; first iteration: the game's loot options moved there
from the common page) and *Tastenbelegung* (key bindings, so far only
settable in `sacredK.ini`). Code: `src/mods/options.cpp`; bindings in
`src/mods/input.cpp`.
## The window (cUI_Options)
- vtable `0x89505c`, constructor `0x716570` (name, rect, parent, flags;
`ret 0x18`), destructor `0x7165f0`; controls built by `0x7184e0`.
- vf44 `0x716640` (renderer, ?, ?; `ret 0xc`): window render (`0x727040`),
then drives the sliders while the mouse is held. vf10 `0x716b30`: events.
- `0x717ea0` loads the settings into the controls when the window is shown;
`0x717460` (thiscall, plain `ret`) writes them back — called for OK.
- Controls: vector at `+0x90` (begin) / `+0x94` (end); the 16 background tiles
are in the window's own list `+0x78`. Buttons: `+0x158` Cancel, `+0x15c` OK.
Pickup: radio buttons `+0x16c/+0x170/+0x174` (`PICKUPAUTO` 0/1/2),
checkbox `+0x178` (`PICKUPANIM`).
- Layout (1024x768): frames at x `0x40` / `0x220`, y `0x40` / `0x120` /
`0x200`, borders `0x14` outside, labels above (y `0x20` / `0x100` /
`0x1e0`). Left: graphics, auto-pickup (*AUTOCOLLECT*), general; right: sound
volume, 3D sound, internet. OK / Cancel at y `0x284`.
- cUI_Frame (vtable `0x8955ac`): its render `0x73a540` does not test the
visible flag, only `+0xdc` (set to 1 by its constructors).
## How the mod works
- After the constructor: every control in `+0x90` is put on a page by its
position — left column middle row → *Beute*, everything else → *Allgemein*,
OK / Cancel on all pages. The auto-pickup group moves up one row (to the top
of its page), the general group below it moves up into its place.
- A cUI_TabSheet (`game/ui/tabs.h`) at the top frames' border; its headers
(default row layout) sit above the frame labels.
- Each frame (vf44) the controls not on the active page are hidden (visible
flag, frames also `+0xdc`); controls hidden by the mod are shown again on
their page. The game re-shows controls when the window opens, so this runs
every frame.
- *Tastenbelegung* is drawn by the mod: rows per binding, grouped
(Kampfkünste, Waffensets, Bewegung, Aktionen), a key box per row. A click on
a box captures the next key press (`input::SetKeyCapture`, swallowed before
the game sees it): Esc cancels, Backspace unbinds, a bindable key is taken
(and removed from any other action). The page works on a copy loaded when
the window opens; OK (`0x717460`) saves it to `[keys]` in `sacredK.ini`,
Cancel drops it.
- Movement keys (W/A/S/D) are bindings now (`MoveUp/Left/Down/Right`);
`mods/wasd.cpp` polls the bound keys.
## Follow-ups (2026-10-18)
- Pages moved down 24 px (`kContentShift`) for room below the tab headers.
- *Alle zurücksetzen* (left of OK / Cancel) sets every binding back to its
default; saved with OK like any other change.
- Potion bindings *Trank 1–5* and *Trank 1 für Gefährten* (default: no key).
They call `cEngine::UseActionSlot` (`0x613040`, thiscall (kind, on ally),
`ret 8`) on the engine tick. The game's own potion hotkeys are off: its
engine hotkey switch (`cEngine::ReceiveEvent`, index bytes `0x619adc` per
upper-case character − 0x20, targets `0x619ac0`) had Space → kind 1 (Shift:
5), B → kind 1 on the weakest ally, Q 2, W 3, E 4, R 5; those six entries
now point at index 6 (no hotkey). `ActionSlot3` (W's action on G) is gone.
- The window is drawn like the save game / export screens: black beside the
1024 frame (`hud::RenderFramed`).
- Key bindings page: a backdrop (`0x724ed0`) and a frame (`0x739f90`) per
column, created with the window's controls and shown only on that page.
(Drawing the window's existing ones at other rects did not fit: a frame's
border pieces keep the place they were made at.)
- Pages move down 24 px under the tab headers. A slider (cUI_Scrollbar,
vtable `0x895664`) moves with its parts: minus, plus, track and knob are
embedded controls (+0x94 / +0x110 / +0x18c / +0x208) with rects in window
coordinates, and the knob is placed from +0x78 / +0x7c each frame.
- Key page layout (2026-10-19): the two frames span the other pages' frame
area (top row's top to the bottom of *Internet-Optionen*); the hints sit
in the bottom row next to *Alle zurücksetzen*, since they hold for the
whole page.
- Potion kinds are named by the bottom bar's tooltip texts:
`PotionTooltipText` `0x43fa90` (kind) → text id by key, e.g.
`<color=FFFFFF80>Heiltrank <colorw=FFFFFFFF>[SPC]` (kinds 1–5: Heiltrank,
Sog der Hölle, Trank des Mentors, Antidot der Viper, Trank der
Konzentration / Teleportationstrank; read in `scripts/de/SRglbl.res`).
Shown, the tags are colour codes (backslash, letter, 8 hex digits:
`\dFFFFFF80Heiltrank \wFFFFFFFF[SPC]`); `game::PotionKindName` strips them and the key; the tooltips get the bound key
in the brackets, or none (`game::SetTextOverride`, mods/potioncounts.cpp).
- No posted game keys any more: *Spiel speichern* calls what the UI manager's
S case (`0x757775`) does: save window built (manager slot `0x2b`),
`CanOpenWindow` `0x75a690`, engine event (vtable `0x88eb38`, 0x13, 5, 1),
then window command *show* (0x11) for `UI_WND_SAVEGAME`
(`game/ui/windows.h`, shared with escape.cpp's *hide* 0x12).
## Karte, Minikarte, Beschriftungen (2026-10-19)
Request: M (map), Tab (minimap) and Alt (text overlay) bindable too.
- M: the UI manager's letter switch (`cUI_Manager::ReceiveEvent` 0x757120,
upper-case character − 'C', index bytes 0x75868c, targets 0x758660) shows
`UI_WND_MEGAMAP` (slot 0x25) unless a blocking window is open; while the map
is open its own branch (cmp 'M' at 0x757f86) hides it. Switched off (M →
index 10, the compare → -1); the *Karte* binding does the same checks and
sends the window command.
- Tab: the in-game window procedure 0x8110d0 shows `UI_WND_OVERVIEWMAP` on
key down (switch on vk − 9: index bytes 0x812124, case 0x81146d) and hides
it on key up (0x812270, case 0x8117f8). Switched off (Tab → the "other key"
indices 4 / 3); *Minikarte (halten)* shows / hides it on the bound key's
down / up.
- Alt: no message, the game polls `GetAsyncKeyState(VK_MENU)` for its name
overlay in seven places (DrawObjectLabels 0x627260, PickObjectAt 0x626d30,
cEngine 0x60f1d0 / 0x611f10 / 0x617360, cCreature 0x599880, the map's debug
teleport 0x6c7ec0). Their `call [GetAsyncKeyState]` read our pointer
instead: `LabelsKeyState` returns the bound key's state.
- Alt and F10 come as WM_SYSKEYDOWN: the key capture takes those too.
- Key page: 20 lines per column (line 25 px) to fit the three rows.