Quake-style drop-down debug console for LBA2. The console is always compiled and works everywhere: in-game, menu, inventory, credits, and during video playback. DEBUG_TOOLS remains a separate optional layer for additional legacy hotkeys/features.
The console is part of normal builds (no dedicated CMake flag required).
cmake -B build
cmake --build buildThe console is supported with the SDL backend (default in this project).
- F12 by default: open/close the console.
- Optional override in
lba2.cfg: setConsoleToggleKey=<SDL scancode int>(for example41forK_CARREon AZERTY layouts). - When the console is open, all keyboard input is consumed by the console (no game/menu input).
- Type a line and press Enter to run a command or cheat.
- Backspace: delete last character.
- Up/Down: scroll console output; the input line stays fixed at the bottom. When you are not at the newest lines, the last visible scrollback line shows
....
- help – list all commands with short descriptions. With an argument, help <name> prints usage and context for that command or cvar (e.g.
help cube,help fps,help status). - cmdlist – list command names only.
- varlist – list cvars (variables) with descriptions.
- buildinfo – print build timestamp and CMake options (SOUND_BACKEND, MVIDEO_BACKEND, ENABLE_ASM). The same string is written to the log at startup.
Unknown commands print a hint to use cmdlist. Commands that need an in-game scene (give, savebug) print a short reason if used while a video is playing, before a scene exists, or in the phantom-cube state.
These mirror the classic key-sequence cheats; you can type their name directly at the prompt and press Enter:
- life – max life
- magic – max magic
- full – full points
- gold – add gold/kashes
- speed – toggle frame rate display
- clover – clover
- box – clover box
- pingouin – MecaPingouin
| Command | Description |
|---|---|
| cube <n> | Request change to cube number <n> (applied next frame in game; cube changes no longer trigger autosave). |
| load | Load save by player name as printed by listsaves, or by file name (with optional .lba). |
| loadbug | Load bug save by name or file (optional .lba), default bug. |
| listsaves | List save games (player names from .lba files). |
| listbugs | List bug saves in the bugs directory (same path as savebug). |
| savebug [name] | Save current game to bugs directory; optional name (default bug). |
| timer [ms] | Advance in-game timer by N ms (default 200). |
| status | Print island, cube, chapter, object/zone counts, FPS, timer, position. |
| screenshot | Save the next frame as PNG in the shoot directory without the console visible (uses SavePNG). |
| give <n> | Play “found object” sequence for inventory entry <n>; some items (e.g. weapons, protopack) also update gameplay state. Mostly for visual/debug use. |
| playvideo <name> | Play ACF video by name. |
| listvideos | List available ACF video names. |
| playjingle <1-26> | Play jingle by number. |
| playmusic <num> [loop 0|1] | Play music track by number (optional loop flag, default 1). |
| playsample <num> [freq] [decal] [repeat] [volume] [pan] | Play sample by index with optional params: pitchbend (freq, default 0x1000), random pitch range (decal), repeat count (repeat, 0=loop, default 1), volume (0–127, default 127), pan (0–127, default 64). |
| audio ... | Audio commands: audio sample play/stop_all, audio music play/stop, audio global pause/resume/stop_all/reset/reverse_stereo/log. Calls HQ/AIL functions directly (see AUDIO.md). |
| video ... | Video commands: `video log <0 |
| exit | Exit the game immediately (clean shutdown). |
Get/set with varname (print value) or varname value (set).
| Cvar | Type | Description |
|---|---|---|
| fps | bool | Frame rate display. |
| horizon | bool | Draw horizon / cubes around. |
| zv | bool | Draw ZV boxes. |
- Console is a panel at the top of the screen.
- Scrollback shows recent lines; the last line is the input with a
]> ... _prompt. When scrolled up, an ellipsis...appears on the last visible scrollback line to indicate older messages above. - Output from commands and cheats appears in the scrollback.
- Independent of game buffer: The console uses its own 8-bit overlay buffer. It is drawn via
AffStringToBuffer(LIB386/SVGA) and composited in the video layer’s pre-present callback (Console_PrePresent), so it never touches the game’sLogor dirty-box pipeline. - Event-driven input: Keys are fed from the event loop via
Console_FeedEvent(registered withSetEventFilter). When the console is open, key events are queued and processed each frame byConsole_Update()(no arguments). The configured toggle key is reserved from gameplay input to avoid double-handling. - Hooks:
SetEventFilter(Console_FeedEvent)andSetPrePresentCallback(Console_PrePresent)are registered inmain()afterInitAdeline().MyGetInput()reserves the configured toggle key, and when the console is open callsConsole_Update()and returns. - Module:
SOURCES/CONSOLE/–CONSOLE.H,CONSOLE.CPP(core),CONSOLE_CMD.CPP(commands/cvars). Core links only LIB386 (AFFSTR for text) and SDL for events; no dependency on gameLogor dirty-box. - Gameplay integration: Commands call existing engine functions (
LoadGameNumCube,PlayAcf,DoFoundObj, etc.) rather than introducing console-only code paths. Cube changes no longer trigger autosave to keep debug teleports tidy; other save behavior is unchanged. - External call sites (outside
SOURCES/CONSOLE/):INPUT.CPP(input path when open),PLAYACF.CPP(stall ACF while open),PERSO.CPP(event filter, pre-present, screenshot handoff),GAMEMENU.CPP(slide-show gate). Cheat names live inCHEATCOD.CPP. Build wiring:SOURCES/CMakeLists.txt,SOURCES/CONSOLE/CMakeLists.txt,tests/console/. A one-line map also lives inCONSOLE.Habove the public API.
- Commands: Add new handlers in
SOURCES/CONSOLE/CONSOLE_CMD.CPPand register them viaConsole_RegisterCommandEx("name", handler, "short description", "usage line", "context line")(orConsole_RegisterCommandif usage/context are omitted) insideConsole_RegisterAll(). - CVars: Register new tunables via
Console_RegisterCvarinCONSOLE_CMD.CPP, wiring them to existing globals rather than duplicating state. - Cheats: To add a cheat that works both from key sequences and the console, extend
CheatNames[]andApplyCheatinSOURCES/CHEATCOD.CPP; the console will automatically route matching command names throughTryExecuteCheatByName. - Safety: Prefer read-only inspection commands or one-shot state changes that leave the game in a consistent, save/load-safe state. If a command is inherently risky (e.g. heavy state mutation), call it out explicitly in its help text.