53c4eac3fdb874b20478bdf0a4c0b7fea6f5e975
9
Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
ce1b0ab9c3 |
Sounds fade, dull and doppler with distance again
The OpenAL port kept the whole authored audio model and then threw most of
its output away. Every frame the engine computed a distance-attenuation
curve, a high-frequency rolloff, doppler cents, a reverb level and a
front/rear placement, and every one of those consumers had been commented
out when the two AWE32 cards were replaced. What reached the speakers was
OpenAL's own defaults instead: a straight-line fade to silence, no
filtering, doppler at the wrong constants with an inverted velocity, no
reverb, and every cockpit sound dead centre.
Restored, per AUDIO.INI, which is byte-identical to the file that shipped
in August 1995:
- the authored knee/rolloff distance curve, replacing AL_LINEAR_DISTANCE.
This also un-blinds the transient cull, the voice-steal weighting and
the mix ducking, which all key off it and were treating far sources as
full presence
- the CC7 squared volume law; writing the scale linearly ran everything
about 6 dB hot at mid-scale
- brightness and distance muffling, and the wet-exterior/dry-cockpit
reverb split, both through a new OpenAL EFX bridge
- doppler on the moving-source path only, as the original had it
- front/rear placement from the authored position enum
The larger find is that AL_PITCH was never called anywhere in the tree, so
the entire pitch chain was inert - not only doppler but pitch_mix_offset,
which our own sequences author 97 times. Doppler alone would have changed
nothing audible.
Note pitch is applied for parity with the BT engine but is identity here:
our content predates NoteAudioControlID, so every source runs at note 60.
Builds clean on VS2022 Release|Win32. Smoke-tested against vRIO on COM1 -
reaches gameplay and holds a steady frame loop. ALC_EXT_EFX is present on
the build machine with all nine entry points, so the filter and reverb work
is live rather than inert. Not yet listened to on the pod, which is the
real test: the volume law changes the level of everything.
docs/SOUND.md documents the original two-card quadraphonic design, where
the surviving original assets are, and what remains.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
|
||
|
|
91420b5cb2 |
Flight sticks, HOTAS and pedals, with a setup wizard
Ported from BT411, which needed the same thing for its glass cockpit. PadRIO reads XInput, which covers Xbox-class pads and nothing else. A flight stick, a HOTAS throttle, a twist grip, rudder pedals or a wheel arrive through DirectInput instead, and until now the game could not see any of them - the only generic-joystick path left was the 1995 single- device DIJoystick behind L4CONTROLS=DIJOYSTICK, which is untouched here. L4JOY is the reader: up to four devices as normalized state blocks, hot- plug re-enumeration on the same ~3 s cadence PadRIO uses to look for a pad, and a device lost mid-race zeroed rather than left holding whatever was pressed when it went. XInput-class devices are excluded by VID/PID against the RawInput paths carrying the "IG_" marker - without that an Xbox pad arrives through both APIs and every button counts twice. bindings.txt gains four rows in the grammar it already had, using its own vocabulary (deadzone/rate) rather than BT411's: joydev <slot> [product-name substring] joyaxis <src> axis <axis> [invert] [deadzone <d>] [rate <n>] joybutton <n> button <addr> [toggle] joyhat <n> <up|down|left|right> button <addr> Slots resolve to a live device every poll, by name substring or ordinal, so unplugging and replugging does not rewrite anyone's file. Two things the pod's shape forced that BT411 solved differently: Pedals - a signed composite axis that decomposes into the pod's two pedals, positive right and negative left. The pod has a pedal each side; a twist grip or rudder bar is one signed control, and pressing one or the other but never both is exactly what it wants to say. It is a channel name like any other, so a pad stick can drive the turn too. A joyaxis on Throttle with no rate is a real lever and OWNS the channel - full travel maps onto the 0..1 the pod runs on, instead of nudging the accumulator that a spring-centred pad stick has to use. RP412JOYCONFIG=1 (joyconfig.bat) runs the capture wizard before the console screen: it asks the player to move each control, and derives the sign convention from the DIRECTION of the move. That is the point of it - a stick that reads positive pushed right and one that reads negative are equally common, and no amount of documentation gets a player to work out which they own. It writes only its own section, between marker lines, so hand-edited keyboard and pad rows survive re-running it. The wizard also prints every axis at rest before it starts. A driver that refuses the +-32767 range we ask for reports its own, and an axis then sits hard over instead of near zero; seeing "X +1.00" on an untouched stick is the difference between a five-minute fix and a bug report that says it configured itself. Each capture reports the move it saw for the same reason. Verified on the Logitech Extreme 3D on this machine. Enumeration finds it and excludes the Xbox pad, which still arrives separately through XInput. Every row shape parses - 7 axes, 2 buttons, 4 hat directions - and three deliberately malformed rows (a bad axis name, button 99, a "sideways" hat) are each rejected by line number rather than silently dropped. The wizard lists the device with its axes at rest reading X +0.00 Y -0.01 RZ -0.04 SL0 +1.00, waits on the first prompt without self-triggering, and with a hand on the stick captures X to steering, Y to pitch, RZ to the pedals and SL0 to the throttle, inverting the ones that read backwards. Running the captures through to a written file needs a hand on the stick, so that part is the machine's to confirm, not this build's. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> |
||
|
|
0ca6b5b01f |
RGB keyboard lamp mirror: vRIO Dynamic Lighting port, live in-game
The polish-backlog item, implemented from vRIO KeyboardLampMirror: game-commanded RIO lamp states paint per-key RGB keyboards through Windows Dynamic Lighting (WinRT LampArray). Keys bound to lamp addresses in the active bindings profile glow with the panel palette (red banks, yellow Secondary/Screen columns), flash modes use the exact L4MFDVIEW formula so keyboard and on-screen buttons blink in step, unbound keys are blacked out so the board reads as the button field, and zone-lit keyboards fall back to a board-wide mirror of the strongest lamp. Advantage over vRIO: Dynamic Lighting grants LEDs to the FOREGROUND app - which is the game - so no Windows settings dance. Isolation: L4KEYLIGHT.cpp compiles /std:c++17 + DEFAULT packing + conformance (per-file vcxproj settings; the engine /Zp1 would break the WinRT ABI) with a scalars-only interface, and all WinRT work runs on a private worker thread (watcher, claiming, 100ms paint loop). On by default with a bindings map present; RP412KEYLIGHT=0 opts out; missing Dynamic Lighting logs once and stays dormant. Verified live on the dev laptop: claimed its 24-zone keyboard (board-wide mirror) during a race; race cycling with per-race start/stop of the mirror thread stays green. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> |
||
|
|
b0def79de2 |
Rebindable input: vRIO bindings profile ported, full board coverage
PadRIO now loads bindings.txt (vRIO profile grammar: key/pad/padaxis lines with toggle, deflect/rate, invert/deadzone options) written self-documenting with the full default layout on first run. The default is vRIO board-complete map - number and letter rows are the MFD banks as printed on the panel, F-keys the secondary/screen columns, numpad the pilot keypad (0x50-0x5F delivered as arcade RIO KeyEvents, a new PadRIO capability), Space/arrows the joystick column - with the desktop driving keys carved out: WASD stick, Q/E pedals, PgUp/PgDn throttle, B reverse (vRIO gap key; R returns to its bank). Pad bindings unchanged in spirit, plus Panic on LB and config on Start/Back; axis signs are encoded in the profile now, so L4PADFLIP flips on top of it. Default profile parses with zero rejected lines (68 key buttons, 8 key axes, 12 pad buttons, 5 pad axes); single-player cycle and the key-bomb tests stay green. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> |
||
|
|
ff6ec8c56a |
SteamNetTransport: the Steam wire is implemented and live
Steamworks SDK 1.64 vendored at extern/steamworks_sdk_164 (headers + win32 redistributables only; .gitignore trims the rest). Both projects build with RP412_STEAM; activation stays behind the RP412STEAM=1 environment switch, so plain desktop runs never touch Steam. L4STEAMTRANSPORT.cpp implements NetTransport on ISteamNetworkingSockets with FakeIP: SteamNetTransport_Install brings up SteamAPI, relay network access, and a two-port FakeIP identity (fake port 0 = console channel, 1 = game mesh), then swaps the process wire; any failure logs the reason and the game carries on over TCP. Addressing keeps the engine untouched: all pods share the -net port convention, eggs carry fakeip:engineport, and the transport alone translates engine ports to Steam fake ports via the lobby-fed peer table (RegisterPeer). Connect mirrors the TCP retry-while-refused loop; Receive normalizes message lanes back into the stream semantics CheckBuffers expects. Runtime verified on this box: RP412STEAM=1 under AppID 480 came up as 169.254.59.52 (fake ports 32256/32257); without Steam credentials it falls back to TCP cleanly; default boot logs no Steam lines at all. steam_api.dll ships in the dist. Next: the lobby layer (ISteamMatchmaking member data -> RegisterPeer + egg build + RPL4CONSOLE marshal), which needs a second account to test. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> |
||
|
|
22421fb418 |
NetTransport seam: the wire moves behind an interface
The Steam-multiplayer prerequisite from the design doc: L4NET keeps hosts, message queues, and the deterministic mesh ordering, while connect/listen/accept/close, send/receive, startup/cleanup, the local interface list, and ip[:port] parsing move behind NetTransport (L4NETTRANSPORT.h). WinsockNetTransport carries the existing TCP behavior over verbatim - including the connect retry-while-refused loop the egg-ACK ordering relies on - and is the process default; NetTransport_Set installs a replacement before the network manager comes up. L4STEAMTRANSPORT.h documents the ISteamNetworkingSockets mapping per method (FakeIP keeps [pilots] entries as IPv4 strings) behind RP412_STEAM until the Steamworks SDK lands. Also fixed in passing: the ExclusiveBroadcast path sent sizeof(network_packet) - four bytes of pointer - instead of the message size, which would have sheared the stream framing had it ever fired. Verified: single-player race cycle (menu, race, results, menu, race) green; -net 8000 boots, listens for a console through the transport, and idles stable. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> |
||
|
|
214a8e079c |
Un-pack the 7-display cockpit in-engine (L4MFDSPLIT=1)
The pod drove five monochrome MFDs from the color channels of two video outputs - SVGA16 packs bit-slices of the shared gauge canvas into R/G/B of gauge window 3 (upper MFDs) and R/G of window 4 (lower MFDs), with the map palettized on the secondary and physically mounted portrait. The desktop reconstruction previously required an external BitBlt-mirror wrapper. With L4MFDSPLIT=1, SVGA16 renders each display into its own window (MFDSplitView, plain GDI) straight from the canvas + port bit-masks: five green-screen MFD windows and the 90CW-rotated Map, tiled in the pod grid to the right of the main view (L4MFDSCALE percent, default 50). The packed D3D windows stay hidden but keep presenting off-screen, leaving the original path untouched. Handles spanning mode (2-window setups). Also: the plasma glass now opens directly below the main view (clamped to the work area; L4PLASMAPOS=x,y overrides) per playtest feedback. Verified: window grid comes up as main + 5 MFDs + Map + plasma with the packed windows hidden; screenshots confirm a green MFD score readout and the portrait tactical map rendering correctly. dist packer and BUILD.md updated; the launcher wrapper is obsolete for split-mode use. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> |
||
|
|
de5a97d37d |
Workstream A prototype: play without the cockpit
Splits the control surface the game consumes from the RIO board into RIOBase (8 virtuals + the five analog scalars); the serial RIO is now one implementation of it. Adds two new ones: - PadRIO (L4CONTROLS=PAD): in-process RIO speaking the full surface from an XInput controller + PC keyboard using vRIO's default profile (left stick/WASD = stick, triggers/Q,E = pedals, right stick Y/PgUp,PgDn = rate throttle that holds position, A/Space = trigger, B/R = reverse, dpad/arrows = hat, Start,Back/F1,F2 = config). Samples in GetNextEvent so button latency does not depend on the 15 s menu-time analog cadence; hot-plugs pads; L4PADFLIP=XY inverts stick axes; lamp commands land in lampState[] for the planned on-screen cockpit panel. The stock VTVRIOMapper/lamp/button path runs unchanged. - PlasmaScreen (L4PLASMA=SCREEN): the 128x32 plasma glass as a desktop window in plasma orange (L4PLASMASCALE, default x4), rendering the same Video8BitBuffered surface the gauge system always drew; no COM port. Verified in the sandbox with vRIO off and no serial devices: boots to a running mission, controller hot-detected, plasma window drawing live game content (score readout). BUILD.md 4 documents the desktop environ.ini and bindings; roadmap updated. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> |
||
|
|
12b31187f9 |
Move the build to VS2022 (v143) with runtime parity against VC9
Hand-converted the four .vcproj projects to .vcxproj (Win32, v143, Windows 11 SDK + DXSDK June 2010 for d3dx9/dxerr only). WinTesla.sln now builds the v143 projects; the legacy solution is kept as WinTesla_vc9.sln. Kept: /Zp1 in Munga_L4+RP_L4, Unicode, x86, /DYNAMICBASE:NO, /FORCE:MULTIPLE (header-defined globals still duplicated across TUs). Changed: CRT unified to /MD(d); import libs linked by the exes instead of merged into Munga_L4.lib; WINDOWS_IGNORE_PACKING_MISMATCH and _SILENCE_STDEXT_HASH_DEPRECATION_WARNINGS defined; legacy_stdio_definitions.lib for the June-2010 dxerr.lib. Source fixes, all behavior-preserving: Time gains standard (non-volatile) copy-ctor/assignment overloads (rvalues cannot bind to volatile& in standard C++); operator==(SOCKADDR_IN&,...) made inline; L4DINPUT's Enum*Callback pair renamed DIEnum* (collided with L4CTRL's under LTCG); std::ios.in -> std::ios::in in CAMMGR.cpp. Verified: VC9 baseline rebuilt from this tree first, then the v143 build compared against it in a sandboxed game working copy - identical logs and behavior through RIO init (against vRIO) and mission load, including the same pre-existing AV in d3d_OBJECT::LoadTexture (L4D3D.cpp:262) that both toolchains hit; documented in BUILD.md 4 as the next debugging target. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> |