Domain correction from playtest: hand-fed eggs are a developer shortcut
- a mission only ends on a console command, so the clock hits 00:00 and
counts up forever. Even single-player games need a console marshal.
RPL4CONSOLE is that console. Like the real one it lives on its own
thread: it owns the mission clock and raises the stop request at the
selected length; the app-manager per-frame hook (new gPerFrameHook seam
in APPMGR, called while the application global is live - the loop
condition NULLs it on exit, which ate the first attempt) executes the
engine-safe part, dispatching the same StopMissionMessage TeslaConsole
sent. Final scores flow in through a new RP-layer sink
(gConsoleScoreSink in RPCNSL): RPPlayer feeds it the same score it
sends a real console at mission end.
It also inherits the launcher role: the application tears down after a
stop (arcade pods were relaunched per mission by TeslaLauncher), so
WinMain respawns the process when the console ended the mission,
landing back on the race-setup screen. L4NetworkManager grows
FeedLocalEgg (the single-user egg-inject path, callable mid-session)
for the future in-process loop.
Verified end to end: menu -> 3:00 race -> stop dispatched exactly on
time -> final score collected (host 1 = 4113) -> process respawned with
the front end up. -egg runs stay unmarshaled (the dev shortcut).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Starting without -egg, -net, or -mr now boots a race-setup screen
(RP_L4/RPL4FE.cpp) instead of aborting: track / vehicle / color / badge
/ time-of-day / weather / race length plus pilot name, populated from
TeslaConsole''s RPConfig.xml catalog (Death Race scenario). LAUNCH
builds the egg exactly as the console did - the RPMission.ToEggString
port, including the pilot name pre-rendered to 1bpp plasma bitmaps
(128x32 + 64x16) via GDI with the console''s auto-shrink font logic and
the verbatim ordinal graphics - writes frontend.egg, and injects it
into the standard egg-load path (new L4Application::
SetEggNotationFileName).
The menu is a GDI child of the main window (pod green-on-black, double
buffered, mouse driven, EDIT control for the name) running a modal loop
before engine init; closing the window exits cleanly. Found and fixed
along the way: the empty egg CString holds a NULL representation
(operator! is the safe emptiness test), and the modal loop needed a
queue nudge for launch clicks delivered via SendMessage.
Verified end to end: boot -> menu -> LAUNCH -> generated egg (7.5KB) ->
racing in the 1080p cockpit with score and mission clock running.
start-windowed.bat now boots into the front end.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Findings from TeslaConsole.RedPlanet and L4NET: the pod lifecycle
(egg chunks/ACK, RunMission, telemetry, results), the egg as the entire
mission definition (NotationFile text incl. pre-rendered plasma name
bitmaps), the RPConfig.xml catalog, and the key topology finding -
every pod gets the same egg and builds a deterministic full TCP mesh
from the ordered pilots list (connect to earlier entries, listen for
later). Maps 1:1 onto Steam: lobby owner = console, SteamIDs = pilot
addresses, ISteamNetworkingSockets P2P = the mesh, with a NetTransport
seam at L4NET mirroring the RIOBase pattern. Implementation options and
open decisions listed for signoff.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The 4-8px black padding framing every MFD and the map read as a jarring
border over the 3D. Glass and button strips now run to the pane edges
(last button in each strip/column absorbs the rounding remainder);
only the thin separations between buttons within a strip remain.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
SS_BLACKRECT paints the system window-frame color - gray on modern
Windows - so the viewscreen child is now a plain STATIC subclassed to
erase true black. The MFD/map panes flickered because Paint() cleared
the on-screen surface before redrawing at the fill cadence; the pane
now composes off screen and lands in a single BitBlt.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Playtest: the half-height red buttons did not read well; back to
display_height/8 (18..40px). The contiguous amber map columns stay.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Playtest direction on the canvas layout: all five MFDs at the compact
320x240 glass size - upper pair pushed to the top corners, score glass
top-center, lower pair in the bottom corners, map bottom-center - and
the viewscreen now fills the entire 1920x1080 canvas. Launched with
-res 1920 1080 the 3D renders native 1:1 (the 2007 D3D9 path takes the
1080p backbuffer and 16:9 aspect without complaint). start-windowed.bat
updated accordingly.
Verified live: full-screen native 3D with the cockpit floating over its
edges, mission running, preset lamp lit on the map column.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The cockpit is now a fixed 1920x1080 canvas (uniformly scaled down on
smaller monitors, min 25%):
[ MFD UL 640 ][ MFD UC 640 ][ MFD UR 640 ] <- native glass, 1920 wide
[ viewscreen 800x600 centered ]
[ MFD LL ] [ Map ] [ MFD LR ] <- bottom edge
Playtest direction: the original pods MFDs partially occluded the main
display, and that is used here on purpose - the panes overlap the
viewscreen and render over it (viewscreen pinned to the bottom of the
sibling z-order, WS_CLIPSIBLINGS everywhere, so the 3D present clips
around every pane). Top-row glasses are gauge-canvas native 640x480 -
three across is exactly 1920. Red MFD buttons at half height; the amber
map columns stack contiguous like the pod strips. The auto-fit
scale/L4MFDSCALE machinery is gone - the canvas is the design space.
Verified live at 100% scale: contiguous native top row over the
centered viewscreen, bottom cluster overlapping its lower edge, map and
gauges updating (BOOST values moving, presets lit).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Remove-Item raced a live playtest session and gutted the folder around
the locked files. Detect a running rpl4opt.exe under dist and abort
before deleting anything.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The game loop pumps ONE message per frame (APPMGR.cpp PeekMessage), and
WM_PAINT is synthesized only when the queue is otherwise empty - so the
child panes queued invalidations that never delivered: the map stayed
black and button lamps froze at their first-paint state on the live
screen. (PrintWindow-based captures forced paints and the synthetic
SendMessage click bypassed the queue, which is why every automated
verification looked fine while the live window was frozen.)
MFDSplitView::Repaint and PlasmaScreen::Update now paint synchronously
via RedrawWindow(RDW_INVALIDATE|RDW_UPDATENOW) at fill time, and the
button press/release feedback goes through the same path. Verified with
a true screen capture (CopyFromScreen): map drawing live, timer
counting, the active preset lamp bright on the map right column.
Lamp anchor sanity-check against the game code: mode switch NOV/STD/
VET/EXP = ButtonAuxUpperRight5-8 = 0x33..0x30 = the upper-right MFD
bottom strip left-to-right; presets = Secondary7-12 = 0x18-0x1D = the
map right column - both match the placed buttons.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The assembled shell could exceed the work area (1291px tall at default
scale) - on a 1080p monitor the whole lower row, map included, hung off
the bottom of the screen, which read as the map not rendering, and the
lamp-reactive preset buttons were unreachable down there. (The render
and click paths themselves were verified fine: a synthetic press on a
map preset button lights it through the game lamp command.)
The layout now measures SPI_GETWORKAREA and fits: the pane scale steps
down (to 20% minimum) and the viewscreen takes the leftover height at
the 3D aspect, shrinking below native when needed - Present stretches,
so the scene scales cleanly. Rows and viewscreen center in the shell,
which is sized to the work area. Verified: at 70% panes in a 1392-high
work area the viewscreen reduced to 609x457 with everything on screen.
The plasma glass sits out of the cockpit for the moment
(PlasmaScreen::Hide) per playtest direction.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The main game window becomes the cockpit shell (enlarged, clipping
children); every display folds in as a chrome-less child pane in the
pod interior arrangement:
[ MFD UL ] [ MFD UC ] [ MFD UR ]
[ plasma (reduced) ][ viewscreen (centered) ]
[ MFD LL ] [ Map ] [ MFD LR ]
The 3D scene presents into a black STATIC viewscreen child via
Present's hDestWindowOverride (new gMainPresentWindow global) - no
swap-chain changes, and STATIC's transparent hit-testing keeps mouse
input over the 3D view flowing to the game window. MFDSplitView gains a
parent/child mode; PlasmaScreen::Position reparents the glass into the
shell. Main window class background goes black for the cockpit gaps.
Verified by screenshot: live green gauges (LIFT CUT / BOOST / CHUTE /
trigger-program screens) with their red button strips, the 3D canyon in
the centered viewscreen, plasma score glass at its left, map with lit
amber preset lamps - one window, 976x1132 client at 50% scale.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
[ MFD UL ] [ MFD UC ] [ MFD UR ]
[ plasma (reduced) ][ main screen (centered) ]
[ MFD LL ] [ Map ] [ MFD LR ]
SVGA16 moves the main game window into the middle band (centered under
the MFD columns) and shrinks the plasma glass to fill the space at its
left via a new PlasmaScreen::Position hook (the glass paint stretches to
the client area, so resizing rescales it). Lower row sits below the
main screen band.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The pod stacks its displays vertically - upper MFDs above the
viewscreen, weapon MFDs + secondary below. Default grid now places the
lower row (MFD LL / Map / MFD LR) at the main screen's bottom edge
instead of directly under the upper row, so the main screen reads as
the middle band, with the plasma glass at its lower-left.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The side-button columns widened the map window, drifting the glass right
of center; shift the default position left by one column width.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The arcade startup hid the cursor unconditionally in release builds -
correct for a pod, but desktop windowed play needs the mouse for the
on-screen cockpit buttons and the cursor vanished over every display
window. Hide (and restore) it only when running fullscreen.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Each MFDSplitView window now carries its display's physical button bank,
placed as in the pod (addresses per vRIO CockpitLayout): a 4x2 red
cluster around each MFD glass (anchors 0x2F/0x27/0x37 upper, 0x0F/0x07
lower, addresses descending row-major) and 6 amber buttons down each
side of the map - Secondary 0x10-0x15 left, Screen 0x18-0x1D right; the
remaining column addresses are Tesla relays, per the pod wiring, so they
get no buttons.
Buttons light from the lamp state the game commands: PadRIO grows a
static active-instance hook (SetScreenButton/GetLampState); mouse
press/release feeds PadRIO's desired-state sampling alongside pad and
keyboard, and paint decodes the lamp byte (state1/state2 brightness,
solid/slow/med/fast flash animated by tick). With real serial hardware
(no PadRIO) the buttons draw dark and inert.
Verified: map flank buttons light per the game's preset lamps, aligned
with the labels the glass draws at its edges; MFD clusters render 4+4.
Roadmap: queued the vRIO Dynamic Lighting RGB-keyboard lamp mirror as a
polish-pass item. dist repacked.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
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>
Playtest feedback: X and Y from the Xbox controller were both inverted.
Negate both by default (pad and WASD go through the same assignment, so
they stay consistent); L4PADFLIP now flips back toward raw XInput
orientation per axis.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Collects the Release exe (+pdb), the AUDIO/GAUGE/VIDEO data and INIs from
assets\RP411 (leaving the arcade launch scripts and old 4.10 exe behind),
libsndfile + the system OpenAL runtime (oalinst.exe as fallback), a
desktop environ.ini (PAD;KEYBOARD + on-screen plasma), start-windowed.bat
and a controls README. -Zip additionally produces a handoff zip. dist\ is
gitignored; verified by running the game from the packaged folder.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
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>
startrp-800x600.bat/.ps1 rode into the previous commit unintentionally;
remove them from tracking (local copies untouched) and gitignore them so
a bulk add cannot sweep them back in.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
d3d_OBJECT::LoadTexture never checked D3DXCreateTextureFromFileA, cached
the NULL texture, and unconditionally AddRef()ed it - an access violation
on any missing/unreadable texture, hit by every bare working copy because
the pod skins (VIDEO\player1-8) come from the presets/replacement-material
path, not the depot. Failures now log the filename+hr and the draw op
renders untextured, matching the existing no-texture-filename path. Also
guard the unchecked gReplacementData->find() in LoadObject (same latent
UB one branch earlier).
Verified in the sandbox working copy: the game now boots to a running
RPL4 window with -windowed -egg TEST.EGG (RIO served by vRIO), logging
the eight missing pod skins instead of dying in MakeEntityRenderables.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
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>
Consumer port of Red Planet: sellable on Steam, internet multiplayer,
playable without cockpit hardware. Adds the project README and
docs/RP412-ROADMAP.md covering the three workstreams (vRIO-derived
input/display, TeslaConsole-derived session UI, Steamworks networking)
and the Steam logistics assessment.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Verified full build with VC++ 2008 Express SP1 + Windows SDK v6.0A + DirectX
SDK (June 2010): 4 Projects succeeded, 0 failed (Release|Win32). Outputs:
Release\rpl4opt.exe, Release\RPL4TOOL.exe, lib\Munga_L4.lib, lib\DivLoader.lib.
Two projects referenced DirectX but were never repointed at $(DXSDK_DIR)
(they had no hardcoded path to replace earlier):
- DivLoader.vcproj: add "$(DXSDK_DIR)Include" to both compiler configs
(was failing on D3DX9.h).
- RPL4TOOL.vcproj / RPL4TOOL VS2008.vcproj: add "$(DXSDK_DIR)Lib\x86" to the
linker search path (was failing with LNK1181 on dinput8.lib).
.gitignore: ignore the build-output static libs that land in lib/
(Munga_L4.lib, DivLoader.lib); the dependency libs OpenAL32.lib and
libsndfile-1.lib stay tracked.
BUILD.md / docs/BUILD-NOTES.md: record the verified build, the CLI recipe,
and the DXSDK_DIR stale-environment gotcha.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The Express editions of Visual C++ ship without ATL. The only ATL usage was
in MUNGA_L4/L4APP.cpp (atlbase.h/atlconv.h + USES_CONVERSION/W2A macros, all
in that one file) for wide-to-ANSI conversion of command-line arguments.
- Replace the ATL includes with a self-contained L4WideToAnsi helper (a
WideCharToMultiByte wrapper) and local USES_CONVERSION/W2A macros that
reproduce ATL's W2A semantics. All call sites consume the result immediately
(stricmp / CString assignment / atoi / atol), so behaviour is unchanged.
- Set UseOfATL="0" in Munga_L4.vcproj, RP_L4.vcproj and their VS2008 variants.
- Document the Express build path and the confirmed June 2010 DirectX SDK in
BUILD.md (new section 6) and docs/BUILD-NOTES.md.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Imports the current Win32 source for the pod-racing game 'Red Planet',
built on the MUNGA engine and its L4 (Win32/DirectX) platform layer:
- MUNGA / MUNGA_L4: cross-platform engine core and Win32 backend
- RP / RP_L4: Red Planet game logic and Win32 application
- DivLoader, Setup1: asset loader and installer project
- lib, MUNGA_L4/openal, MUNGA_L4/sos: third-party audio dependencies
Removed stale Subversion metadata and added .gitignore/.gitattributes.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>