Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
f1164f3
feat(frontend): restore optional smooth menu fonts
raistlen007 Nov 2, 2026
2fb881f
TrackIR support
raistlen007 Nov 3, 2026
fb55b12
Merge branch 'main' into feature/smooth-menu-fonts
raistlen007 Nov 3, 2026
686d77a
Merge branch 'main' into feature/smooth-menu-fonts
raistlen007 Nov 7, 2026
6de1958
Tidy the smooth menu fonts change
raistlen007 Nov 7, 2026
7e04b2d
Merge branch 'main' into feature/TrackIR-udp-support
raistlen007 Nov 7, 2026
fbae643
Tidy the head tracking change
raistlen007 Nov 7, 2026
808e066
Name the head tracking layer for both sources
raistlen007 Nov 7, 2026
6edeede
Merge branch 'main' into feature/smooth-menu-fonts
raistlen007 Nov 10, 2026
263ad77
Merge remote-tracking branch 'origin/main' into feature/TrackIR-udp-s…
raistlen007 Nov 10, 2026
9660292
Merge branch 'main' into feature/smooth-menu-fonts
raistlen007 Nov 10, 2026
cf4f10d
Merge branch 'main' into feature/TrackIR-udp-support
raistlen007 Nov 11, 2026
21d9c9b
feat(input): support two controllers and expanded 64-button mappings
raistlen007 Oct 10, 2026
f0652e3
feat(input): add gated Hyperdrive lever and robust controller binding…
raistlen007 Oct 10, 2026
a1b2d98
chore(config): isolate private dual-controller user YAML settings
raistlen007 Oct 10, 2026
a35f8fd
Merge remote-tracking branch 'origin/feature/smooth-menu-fonts' into …
raistlen007 Nov 11, 2026
2d919d5
fix(input): don't crash when quitting with an in-flight menu open
raistlen007 Nov 11, 2026
07478af
fix(head-tracking): keep head tracking during hyperspace
raistlen007 Nov 11, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -210,6 +210,7 @@ set(XWA_RUNTIME_SOURCES
src/xwa_runtime/camera/camera_motion.c
src/xwa_runtime/camera/exterior_hud.c
src/xwa_runtime/config/modern_controller_options_screen.c
src/xwa_runtime/config/modern_head_tracking_screen.c
src/xwa_runtime/config/modern_input_options_screen.c
src/xwa_runtime/config/modern_options_menu.c
src/xwa_runtime/config/modern_pilot_profiles_screen.c
Expand Down Expand Up @@ -288,6 +289,9 @@ set(XWA_RUNTIME_SOURCES
src/xwa_runtime/models/craft_sounds.c
src/xwa_runtime/models/opt_synth.c
src/xwa_runtime/models/mission_art.c
src/xwa_runtime/input/head_tracking.c
src/xwa_runtime/input/opentrack_udp.c
src/xwa_runtime/input/trackir.c
src/xwa_runtime/runtime/flight_pause_task.c
src/xwa_runtime/runtime/flight_task.c
src/xwa_runtime/runtime/frontend_task.c
Expand Down Expand Up @@ -323,6 +327,11 @@ target_include_directories(xwa_input_options PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/
target_link_libraries(xwa_input_options PUBLIC aeron)

add_library(xwa_core ${XWA_RECOVERED_SOURCES} ${XWA_RUNTIME_SOURCES})
if(WIN32)
# Head tracking: advapi32 finds the installed TrackIR NPClient, which is
# loaded at runtime (no TrackIR SDK is bundled); ws2_32 receives OpenTrack UDP.
target_link_libraries(xwa_core PRIVATE advapi32 ws2_32)
endif()

# The recovered sources reproduce MSVC 5.0-era code, which reinterprets one
# struct pointer type as another (iMUSE passes ImStreamZone*/ImTrack* lists
Expand Down Expand Up @@ -762,6 +771,7 @@ set(XWA_FORMAT_HEADERS
src/xwa_runtime/config/modern_camera_shake_options.h
src/xwa_runtime/config/modern_input_options.h
src/xwa_runtime/config/modern_controller_options_screen.h
src/xwa_runtime/config/modern_head_tracking_screen.h
src/xwa_runtime/config/modern_input_options_screen.h
src/xwa_runtime/config/modern_options_menu.h
src/xwa_runtime/config/modern_pilot_profiles_screen.h
Expand Down Expand Up @@ -873,6 +883,9 @@ set(XWA_FORMAT_HEADERS
src/xwa_runtime/input/winmm_joystick_provider.h
src/xwa_runtime/input/controller_mapping.h
src/xwa_runtime/input/mouse_flight.h
src/xwa_runtime/input/head_tracking.h
src/xwa_runtime/input/opentrack_udp.h
src/xwa_runtime/input/trackir.h
src/xwa_runtime/timing/modern_flight_timing.h
src/xwa_runtime/runtime/movie_task.h
src/xwa_runtime/hooks/orientation_hook.h
Expand Down
15 changes: 15 additions & 0 deletions resources/remaster/config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,19 @@ input:
mouse_mode: 'position'
mouse_sensitivity: 5
mouse_invert_y: true
# Native TrackIR is Windows-only; OpenTrack UDP works on all platforms.
# Configure OpenTrack output to UDP over network -> 127.0.0.1:4242.
# Inversion is relative to OpenXWA's standard head-motion directions.
head_tracking:
enabled: false
source: 'trackir'
invert:
yaw: false
pitch: false
roll: false
x: false
y: false
z: false
controller:
device:
# Empty GUID selects the first connected controller.
Expand All @@ -21,6 +34,7 @@ input:
pitch: { source: 'lefty', invert: true, deadzone: 0.08 }
throttle: { source: 'righttrigger', invert: false, deadzone: 0.0 }
roll: { source: 'rightx', invert: false, deadzone: 0.08 }
hyperdrive: { source: 'none', invert: false, deadzone: 0.0 }
buttons:
'1': 'south'
'2': 'east'
Expand Down Expand Up @@ -67,6 +81,7 @@ input:
pitch: { source: 1, invert: true, deadzone: 0.08 }
throttle: { source: 2, invert: false, deadzone: 0.08 }
roll: { source: 3, invert: false, deadzone: 0.08 }
hyperdrive: { source: 'none', invert: false, deadzone: 0.0 }
buttons:
'1': 0
'2': 1
Expand Down
24 changes: 22 additions & 2 deletions src/xwa/config/game_config.c
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@

#ifdef XWA_MODERN
#include "xwa_runtime/config/modern_controller_options_screen.h"
#include "xwa_runtime/config/modern_head_tracking_screen.h"
#include "xwa_runtime/config/modern_input_options.h"
#include "xwa_runtime/config/modern_input_options_screen.h"
#include "xwa_runtime/config/modern_mods.h"
Expand Down Expand Up @@ -952,9 +953,19 @@ int Config_ControllerOptionsScreen(void) {
g_menuCursorRow = 4;
break;
case 2:
XwaModernControllerOptionsScreen_SelectSlot(0);
g_pendingMenuScreen = 20;
g_menuCursorRow = 0;
break;
case 4:
XwaModernControllerOptionsScreen_SelectSlot(1);
g_pendingMenuScreen = 20;
g_menuCursorRow = 0;
break;
case 3:
g_pendingMenuScreen = 24;
g_menuCursorRow = 0;
break;
default:
break;
}
Expand Down Expand Up @@ -2625,6 +2636,13 @@ int Config_OptionsDatapadUpdate(int frameState) {
}
done = 0;
break;
case 24:
if (XwaModernHeadTrackingScreen_Update(g_configMenuCenterX, &g_menuCursorRow)) {
g_pendingMenuScreen = 4;
g_menuCursorRow = 5;
}
done = 0;
break;
#endif
default:
done = 0;
Expand Down Expand Up @@ -5364,12 +5382,14 @@ void Config_ApplyModernInputOptions(const XwaModernInputOptions* options) {
strcmp(previousDevice.guid, options->controller.device.guid) != 0 ||
strcmp(previousDevice.path, options->controller.device.path) != 0 ||
previousDevice.ordinal != options->controller.device.ordinal);
g_gameConfig.rudderEnabled = (uint8_t)options->controller.roll_enabled;
g_gameConfig.rudderEnabled = (uint8_t)((options->controller.enabled && options->controller.roll_enabled) ||
(options->controller2.enabled && options->controller2.roll_enabled));
/* The axes are inverted where the Aeron input becomes WinMM joystick
values, so the game's own flip settings stay off. */
g_gameConfig.flipRudder = 0;
g_gameConfig.flipY = 0;
g_gameConfig.ffEnabled = (uint8_t)options->controller.rumble_enabled;
g_gameConfig.ffEnabled = (uint8_t)((options->controller.enabled && options->controller.rumble_enabled) ||
(options->controller2.enabled && options->controller2.rumble_enabled));
g_gameConfig.ffStrength = (uint8_t)options->controller.rumble_strength;
g_gameConfig.ffCenter = 0;
XwaControllerMapping_CopySelectedActions(g_gameConfig.joyButtons);
Expand Down
29 changes: 29 additions & 0 deletions src/xwa/flight/flight.c
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,9 @@
#include "xwa_runtime/models/craft_hyperspace.h"
#include "xwa_runtime/models/model_roles.h"
#ifdef XWA_MODERN
#include "xwa_runtime/input/controller_mapping.h"
#endif
#ifdef XWA_MODERN
#include "xwa_runtime/input/mouse_flight.h"
#include "xwa_runtime/models/articulation.h"
#include "xwa_runtime/models/craft_sounds.h"
Expand Down Expand Up @@ -2643,6 +2646,32 @@ uint16_t FlightInput_Read(int playerIdxOrSentinel) {
}
g_controlMask = filteredMask;
keyMods = keyModAlt2 + 2 * keyModAlt3;
#ifdef XWA_MODERN
/* Two independent physical devices, including their expanded button
* bindings, feed the same source-agnostic flight key stream. */
XwaControllerMapping_ReadActions(&key, &keyMods);

/* The lever is a Space alternative exclusively for hyperspace
* confirmation action 10; action 2 enters a hangar and must not
* respond. Consume early strokes so they cannot trigger later. */
{
const int lever_pushed = XwaControllerMapping_ConsumeHyperdriveEngage();
if (lever_pushed && g_joystickEnabled && key == 0 && !g_filmPlaybackMode &&
!g_inHangarReady && g_localPlayer >= 0 && g_localPlayer < 8 &&
g_players[g_localPlayer].pendingActionId == 10 &&
g_players[g_localPlayer].msgTypeId == 0 &&
!g_players[g_localPlayer].mapCameraState &&
!g_players[g_localPlayer].hasCheckpointFlag &&
g_players[g_localPlayer].hyperspacePhase == PLAYER_HYPERSPACE_PHASE_NONE &&
(uint16_t)g_players[g_localPlayer].objectIndex != 0xffffu) {
const MobileObject* ship =
g_objectTable[(uint16_t)g_players[g_localPlayer].objectIndex].mobj;
if (ship && ship->pCraft && (ship->pCraft->systemFlags & 0x80u)) {
key = KEY_SPACE;
}
}
}
#endif
}

if (key == 0) {
Expand Down
Loading
Loading