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>
11 KiB
Building Red Planet 4.12 (Win32)
This is the Win32 source for the pod-racing game Red Planet, built on the in-house MUNGA engine and its L4 (Win32 / DirectX 9) platform layer. As of RP 4.12 the build targets Visual Studio 2022 (v143); the legacy VS 2005/2008 projects are retained for reference (see §5).
✅ Verified build (2026-07-12): all 4 projects build clean (
Release|Win32) with VS2022 Build Tools 17.14 (MSVC 14.44, v143) + Windows 11 SDK (10.0.26100) + DirectX SDK (June 2010). Outputs:Release\rpl4opt.exe(the game),Release\RPL4TOOL.exe,lib\Munga_l4.lib,lib\DivLoader.lib. Runtime-verified against the VC9 baseline built from the same tree: identical log output and behavior at every checkpoint, including RIO init against vRIO and mission load (see §4 for the pre-existing crash both builds share).
1. Requirements
| Component | Version | Notes |
|---|---|---|
| VS2022 Build Tools (or any VS2022 with C++ workload) | 17.x, MSVC v143 | Installed at C:\Program Files (x86)\Microsoft Visual Studio\2022\BuildTools. Install via winget install Microsoft.VisualStudio.2022.BuildTools --override "--quiet --wait --add Microsoft.VisualStudio.Workload.VCTools --includeRecommended". |
| Windows 10/11 SDK | any recent (26100 verified) | Comes with the VCTools workload. |
| DirectX SDK (June 2010) | — | Still needed for d3dx9 and dxerr only; everything else now comes from the Windows SDK. The projects reference it via $(DXSDK_DIR), which the SDK installer sets machine-wide. The DXSDK include/lib paths are appended after the Windows SDK paths (see the IncludePath/LibraryPath properties in the projects) so modern headers win — do not move them to AdditionalIncludeDirectories. |
Bundled third-party libraries (already in the repo)
Committed under lib/, no install needed: OpenAL32.lib, libsndfile-1.lib
(import libs). At run time the game needs OpenAL32.dll (system-wide install —
assets/RP411/oalinst.exe — or beside the exe) and libsndfile-1.dll (beside the
exe; a copy ships in assets/RP411/).
2. Building
& "C:\Program Files (x86)\Microsoft Visual Studio\2022\BuildTools\MSBuild\Current\Bin\MSBuild.exe" `
WinTesla.sln /p:Configuration=Release /p:Platform=Win32 /m
Debug|Win32 also builds. x64 is not configured — this is a 32-bit build.
The solution is WinTesla.sln with four v143 projects:
| Project | Type | Output |
|---|---|---|
| MUNGA_L4/Munga_L4.vcxproj | Static lib | lib\Munga_l4.lib |
| RP_L4/RP_L4.vcxproj | App (Windows) | Release\rpl4opt.exe — the game |
| RP_L4/RPL4TOOL.vcxproj | App (Console) | Release\RPL4TOOL.exe |
| DivLoader/DivLoader.vcxproj | Static lib | lib\DivLoader.lib (Release) |
Build order is resolved by ProjectReference (RP_L4 and RPL4TOOL both reference
Munga_L4).
Packaging: pack-dist.ps1 assembles a runnable game into
dist\ (exe + PDB, game data, OpenAL/libsndfile runtimes, desktop
environ.ini, start-windowed.bat, README). Pass -Zip to also produce
dist\RedPlanet412-prototype.zip for handing to someone else.
3. VS2022 migration notes (what changed and why)
Settings preserved from the VC9 projects: /Zp1 struct packing in Munga_L4
and RP_L4 (the engine's on-disk/on-wire binary formats depend on it — RPL4TOOL
and DivLoader never had it), Unicode, subsystems, x86, /DYNAMICBASE:NO,
optimization levels, and /FORCE:MULTIPLE (see below). Deliberate changes:
- CRT unified to
/MD(Release) //MDd(Debug). The VC9 build mixed/MT(Munga_L4, RPL4TOOL) with/MD(RP_L4) and forced the link. - Import libs are no longer merged into
Munga_L4.libby the librarian; the exes link OpenAL32/d3d9/d3dx9/dinput8/dxguid/ws2_32 directly. WINDOWS_IGNORE_PACKING_MISMATCHis defined: the modern Windows SDKstatic_asserts against/Zp1; the VC9 build always compiled Windows headers at/Zp1, so this preserves those exact semantics. Un-/Zp1-ing the engine (pragma-pack only the serialized structs) is future work._SILENCE_STDEXT_HASH_DEPRECATION_WARNINGSis defined: the code still usesstdext::hash_map; porting tostd::unordered_mapis future work.legacy_stdio_definitions.libis linked: the June-2010dxerr.libreferences pre-UCRT stdio symbols.- Source fixes (behavior-preserving): standard copy-ctor/assignment
overloads added to
Time(rvalues can't bind tovolatile&in standard C++);operator==(SOCKADDR_IN&,...)inNETWORK.hmadeinline; the L4DINPUT callbacks renamedDIEnum*(they collided with L4CTRL's under LTCG);std::ios.in→std::ios::ininCAMMGR.cpp. /FORCE:MULTIPLEis still required:gOpNames,gReplacementData(hash_maps defined in a header) andGlobalEggFileNameare genuinely defined in multiple TUs (LNK4006 warnings, same as the VC9 build). Moving them to a single TU is future cleanup.
4. Runtime notes
Fixed (2026-07-12): standalone mission load used to crash with an access
violation in d3d_OBJECT::LoadTexture (MUNGA_L4/L4D3D.cpp):
D3DXCreateTextureFromFileA failures were never checked and the NULL texture
was cached and AddRef()ed. It crashed identically on VC9 — a latent defect
in the 2007 DPL→D3D9 port, exposed by the pod-skin textures (VIDEO\player1–8)
that a bare working copy doesn't contain (they normally come from the
replacement-material/presets path, WTPresets → VIDEO\<name>.png). Missing
textures now log L4D3D.cpp couldn't load texture … and render untextured;
the game boots to a running window with -windowed -res 640 480 -egg TEST.EGG
from a working copy like assets/RP411/.
For runtime debugging the v143 build produces full PDBs — run
cdb -g -G -lines -y Release rpl4opt.exe ... from the working directory
(cdb ships in this machine's Windows Kits).
Running without the cockpit (Workstream A prototype)
Two new environment options remove the hardware dependency entirely:
-
L4CONTROLS=PAD;KEYBOARD— selects PadRIO (MUNGA_L4/L4PADRIO.cpp), an in-process RIO that speaks the full RIO control surface (buttons, axes, lamps) from an XInput controller + the PC keyboard. The stockVTVRIOMapperpath runs unchanged. Hot-plugging works; with no controller it falls back to keyboard only. -
L4PLASMA=SCREEN— renders the 128×32 plasma display as its own desktop window ("Plasma Display", plasma orange,L4PLASMASCALEsets the pixel size, default 4). It opens directly below the main view;L4PLASMAPOS=x,yoverrides. No COM port. Closing the window hides it. -
L4MFDSPLIT=1— assembles the whole pod interior in one window. The pod hardware drove five monochrome MFDs from the color channels of two video outputs (window 3 = upper MFDs in R/G/B, window 4 = lower MFDs in R/G) and mounted the map display portrait. In split mode the main game window becomes the cockpit shell and every display is a chrome-less child pane, arranged as in the pod:[ MFD UL ] [ MFD UC ] [ MFD UR ] [ plasma (reduced) ][ viewscreen (centered) ] [ MFD LL ] [ Map ] [ MFD LR ]The cockpit is a fixed 1920×1080 internal canvas (scaled down uniformly on smaller work areas): the viewscreen fills the whole canvas (launch with
-res 1920 1080for native 1:1 3D), with compact 320×240 MFD glasses in the four corners, the score glass top-center, and the portrait map bottom-center. The panes deliberately overlap the viewscreen and render over it — in the pod the MFD bezels partially occluded the viewport, and the same trick gives a full-screen 3D view with the cockpit floating over its edges. MFDs render green-screen and the map full-color/rotated, CPU-side from the shared gauge canvas (the packed D3D windows stay hidden); the 3D scene presents into the viewscreen pane viaPresent'shDestWindowOverride(gMainPresentWindow), clipped around the panes (viewscreen pinned to the bottom of the z-order). Mouse clicks over the viewscreen fall through to the game window (STATIC pane hit-test transparency). The plasma glass is currently hidden in cockpit mode. This replaces the external BitBlt-mirror launcher wrapper.Each split window also carries its display's physical button bank (geometry per vRIO's
CockpitLayout): 4 red buttons above and below each MFD glass (RIO addresses descending from the cluster anchor — upper left 0x2F, upper center 0x27, upper right 0x37, lower left 0x0F, lower right 0x07), and 6 amber buttons down each side of the map (Secondary 0x10–0x15 left, Screen 0x18–0x1D right; the columns' other addresses are Tesla relays, not buttons). They light from the lamp states the game commands (dim/bright, flash modes animate) and press the corresponding RIO unit with the mouse — active whenPadRIOis the control device, dark and inert with real serial hardware.
Bindings (vRIO's default profile, condensed):
| Input | Pod control |
|---|---|
| Left stick / WASD | joystick X/Y |
| LT / RT, Q / E | left / right pedal |
| Right stick Y, PgUp / PgDn | throttle (rate; position holds) |
| A / Space | joystick trigger |
| B / R | reverse thrust (ButtonThrottle1) |
| DPad / arrows | joystick hat (look) |
| X, Y, LB, RB | pinky / thumb-low / thumb-low / thumb-high |
| Start / F1, Back / F2 | config buttons (AuxUpperRight 1 / 2) |
L4PADFLIP=XY (or X / Y) inverts the stick axes if the feel is wrong.
Example desktop environ.ini:
L4CONTROLS=PAD;KEYBOARD
DPLARG=1
L4DPLCFG=RPDPL.INI
L4GAUGE=640x480x16
L4PLASMA=SCREEN
L4MFDSPLIT=1
TARGETFPS=60
Lamp commands land in PadRIO::lampState[] — the hook for the planned
on-screen cockpit panel (vRIO buttons arranged around the displays).
Also note: Fail() compiles to abort() in release (MUNGA/DEBUGOFF.h) —
e.g. running with L4CONTROLS=KEYBOARD alone aborts at VTV creation because
no keyboard-only pod mapper exists (the old CRT showed a blocking R6010
dialog; the UCRT fail-fasts). Use L4CONTROLS=RIO;KEYBOARD with vRIO serving
the RIO side, exactly like the arcade config.
5. Legacy VS2005/2008 build
The original .vcproj files and solution are kept as
WinTesla_vc9.sln and still build with VC++ 2008 Express
SP1 + DXSDK June 2010:
@echo off
call "C:\Program Files (x86)\Microsoft Visual Studio 9.0\Common7\Tools\vsvars32.bat"
set "DXSDK_DIR=C:\Program Files (x86)\Microsoft DirectX SDK (June 2010)\"
vcbuild /nologo /rebuild WinTesla_vc9.sln "Release|Win32"
See docs/BUILD-NOTES.md for the original repository cleanup history and the findings behind the legacy build.