From dcdca6f2b2ec39568256feab4f298eb9d71824fd Mon Sep 17 00:00:00 2001 From: seelenkuchen <10817856+seelenkuchen@users.noreply.github.com> Date: Sun, 8 Nov 2026 13:33:18 +0100 Subject: [PATCH 1/3] [Docs] Describe the DX9 input devices and the control scheme files Adds the DirectInput8 and XInput device details and a section on the .kfg control scheme files (controls.configFile, controls.mouse, controls.controller, the 37-action format, default-scheme differences and the HUD menu key). Docs only. --- Docs/Architecture/Control-And-Input.md | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/Docs/Architecture/Control-And-Input.md b/Docs/Architecture/Control-And-Input.md index 816195dbb..ec99cc13e 100644 --- a/Docs/Architecture/Control-And-Input.md +++ b/Docs/Architecture/Control-And-Input.md @@ -19,7 +19,7 @@ Primary source files: ## Architectural Split -The engine does not let gameplay code talk to DirectInput or raw key codes directly. +The engine does not let gameplay code talk to the platform input API or raw key codes directly. Instead it uses: @@ -82,6 +82,10 @@ The two backends follow the same architecture: - per-frame reads update raw key/button/axis arrays - helper functions expose normalized axis and key state to `sithControl` +The DX9 backend uses DirectInput8 for the keyboard, mouse, and joysticks, and XInput for gamepads. DirectInput devices are enumerated at startup. XInput pads are scanned at startup and rescanned every two seconds while the game runs; a connected pad is appended to the joystick list after the DirectInput joysticks. A pad registers six axes: X and Y on the left stick, RX and RY on the right stick, and Z and RZ on the left and right triggers. Its A/B/X/Y, left/right shoulder, Back, Start, and stick-click buttons map to joystick buttons 0 through 9, and the d-pad drives POV 0. Trigger values below 30 (out of 255) read as zero. + +The device readers copy the raw state into shared arrays. Keyboard state is the DirectInput key array. Joysticks are polled and their `DIJOYSTATE` axes (X, Y, Z, RX, RY, RZ), buttons, and POV hats are copied into the axis and key state. Mouse X, Y, and Z are deltas since the previous read; Z is the wheel delta in DirectInput units (a wheel notch is 120), and Y is positive down. With mouse sensitivity enabled, the accumulated mouse deltas are clamped to the registered axis range. The DX6 backend has the same shape but uses the older DirectInput interfaces and has no XInput path. + Important entry points in the DX9 path are: - [`stdControl_Startup()`](../../Libs/std/Win95/DX9/stdControlDX9.c#L209) @@ -212,3 +216,15 @@ That separation is one of the cleaner parts of the engine architecture. Even tho - hardware details do not leak into player movement code - gameplay code does not need to know which device produced an action - camera idling and control policies can sit above the raw device layer without contaminating it + +## Control Scheme Files + +The hardcoded defaults above are not the only source of bindings. The game also supports the original `.kfg` control schemes, implemented in [`jonesConfig.c`](../../Jones3D/Display/jonesConfig.c). + +The active scheme is named by the `controls.configFile` key in `Jones.cfg`. [`jonesConfig_Startup()`](../../Jones3D/Display/jonesConfig.c#L1177) sets up the key-set path, loads the active scheme through [`jonesConfig_LoadActiveControlScheme()`](../../Jones3D/Display/jonesConfig.c#L2049), and applies it with [`jonesConfig_BindControls()`](../../Jones3D/Display/jonesConfig.c#L2582). Scheme files live in the key-sets directory: `\` when `installPath` is set, otherwise `..\` relative to the working directory. The `` name comes from the `SITHSTRING_KEYSETS` string. + +A scheme file starts with a localized heading, the enabled marker `1`, and the `Actions`/`Keys` column header, then one quoted action line for each of the 37 actions followed by its quoted bindings. The columns are padded and the file uses CRLF line endings. [`jonesConfig_LoadControlScheme()`](../../Jones3D/Display/jonesConfig.c#L2140) reads it and rejects a truncated or malformed file. The format can name keyboard keys, joystick buttons, POV directions, and the X, Y, Z, and RZ joystick axes. It cannot name mouse buttons or the right-stick RX/RY axes. Mouse bindings come from the hardcoded [`sithControl_RegisterMouseBindings()`](../../Libs/sith/Devices/sithControl.c#L842) defaults and the `controls.mouse` option instead. + +The default scheme differs from the engine defaults in three ways: activate moves off the grave key, `I` opens the HUD menu, and joystick bindings are dropped while `controls.controller` is false. Mouse bindings are similarly gated by `controls.mouse` through [`jonesConfig_EnableMouseControl()`](../../Jones3D/Display/jonesConfig.c#L4888). + +The scheme's interface action is also the HUD menu key. [`JonesMain_ProcessMenu()`](../../Jones3D/Main/JonesMain.c#L1324) checks the keys bound from that action and Escape, ignores them while Ctrl is held, and toggles the HUD menu or hides the console. From cfed0fe8f567e906c6668133c8c44b8061ac0ff0 Mon Sep 17 00:00:00 2001 From: seelenkuchen <10817856+seelenkuchen@users.noreply.github.com> Date: Sun, 8 Nov 2026 13:55:50 +0100 Subject: [PATCH 2/3] [Docs] Correct the default control scheme description The default schemes are full tables, not three changes to the engine defaults; the joystick and mouse gating applies to every scheme. --- Docs/Architecture/Control-And-Input.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Docs/Architecture/Control-And-Input.md b/Docs/Architecture/Control-And-Input.md index ec99cc13e..36199056e 100644 --- a/Docs/Architecture/Control-And-Input.md +++ b/Docs/Architecture/Control-And-Input.md @@ -225,6 +225,6 @@ The active scheme is named by the `controls.configFile` key in `Jones.cfg`. [`jo A scheme file starts with a localized heading, the enabled marker `1`, and the `Actions`/`Keys` column header, then one quoted action line for each of the 37 actions followed by its quoted bindings. The columns are padded and the file uses CRLF line endings. [`jonesConfig_LoadControlScheme()`](../../Jones3D/Display/jonesConfig.c#L2140) reads it and rejects a truncated or malformed file. The format can name keyboard keys, joystick buttons, POV directions, and the X, Y, Z, and RZ joystick axes. It cannot name mouse buttons or the right-stick RX/RY axes. Mouse bindings come from the hardcoded [`sithControl_RegisterMouseBindings()`](../../Libs/sith/Devices/sithControl.c#L842) defaults and the `controls.mouse` option instead. -The default scheme differs from the engine defaults in three ways: activate moves off the grave key, `I` opens the HUD menu, and joystick bindings are dropped while `controls.controller` is false. Mouse bindings are similarly gated by `controls.mouse` through [`jonesConfig_EnableMouseControl()`](../../Jones3D/Display/jonesConfig.c#L4888). +The default schemes are complete tables in `jonesConfig.c`, built by `jonesConfig_SetDefaultControlScheme()`. When a scheme is bound, its bindings replace the engine's for each action it covers: for example, activate uses Ctrl and the first joystick button instead of the grave key, and `I` toggles the HUD menu. For every scheme, `jonesConfig_BindControls()` skips joystick bindings while `controls.controller` is false, and applies `controls.mouse` through [`jonesConfig_EnableMouseControl()`](../../Jones3D/Display/jonesConfig.c#L4888). The scheme's interface action is also the HUD menu key. [`JonesMain_ProcessMenu()`](../../Jones3D/Main/JonesMain.c#L1324) checks the keys bound from that action and Escape, ignores them while Ctrl is held, and toggles the HUD menu or hides the console. From 5b792cc223d08349feb110b4e3aef090099923b6 Mon Sep 17 00:00:00 2001 From: seelenkuchen <10817856+seelenkuchen@users.noreply.github.com> Date: Sun, 8 Nov 2026 13:57:04 +0100 Subject: [PATCH 3/3] [Docs] Describe the mouse delta averaging --- Docs/Architecture/Control-And-Input.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Docs/Architecture/Control-And-Input.md b/Docs/Architecture/Control-And-Input.md index 36199056e..1ba1cd24b 100644 --- a/Docs/Architecture/Control-And-Input.md +++ b/Docs/Architecture/Control-And-Input.md @@ -84,7 +84,7 @@ The two backends follow the same architecture: The DX9 backend uses DirectInput8 for the keyboard, mouse, and joysticks, and XInput for gamepads. DirectInput devices are enumerated at startup. XInput pads are scanned at startup and rescanned every two seconds while the game runs; a connected pad is appended to the joystick list after the DirectInput joysticks. A pad registers six axes: X and Y on the left stick, RX and RY on the right stick, and Z and RZ on the left and right triggers. Its A/B/X/Y, left/right shoulder, Back, Start, and stick-click buttons map to joystick buttons 0 through 9, and the d-pad drives POV 0. Trigger values below 30 (out of 255) read as zero. -The device readers copy the raw state into shared arrays. Keyboard state is the DirectInput key array. Joysticks are polled and their `DIJOYSTATE` axes (X, Y, Z, RX, RY, RZ), buttons, and POV hats are copied into the axis and key state. Mouse X, Y, and Z are deltas since the previous read; Z is the wheel delta in DirectInput units (a wheel notch is 120), and Y is positive down. With mouse sensitivity enabled, the accumulated mouse deltas are clamped to the registered axis range. The DX6 backend has the same shape but uses the older DirectInput interfaces and has no XInput path. +The device readers copy the raw state into shared arrays. Keyboard state is the DirectInput key array. Joysticks are polled and their `DIJOYSTATE` axes (X, Y, Z, RX, RY, RZ), buttons, and POV hats are copied into the axis and key state. Mouse X, Y, and Z are deltas since the previous read; Z is the wheel delta in DirectInput units (a wheel notch is 120), and Y is positive down. When two reads are less than 25 ms apart, X and Y are averaged with the previous delta. With mouse sensitivity enabled, the deltas are instead accumulated and clamped to the registered axis range. The DX6 backend has the same shape but uses the older DirectInput interfaces and has no XInput path. Important entry points in the DX9 path are: