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>
208 lines
11 KiB
Markdown
208 lines
11 KiB
Markdown
# 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/](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
|
||
|
||
```powershell
|
||
& "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](WinTesla.sln) with four v143 projects:
|
||
|
||
| Project | Type | Output |
|
||
|---------|------|--------|
|
||
| [MUNGA_L4/Munga_L4.vcxproj](MUNGA_L4/Munga_L4.vcxproj) | Static lib | `lib\Munga_l4.lib` |
|
||
| [RP_L4/RP_L4.vcxproj](RP_L4/RP_L4.vcxproj) | App (Windows) | `Release\rpl4opt.exe` — **the game** |
|
||
| [RP_L4/RPL4TOOL.vcxproj](RP_L4/RPL4TOOL.vcxproj) | App (Console) | `Release\RPL4TOOL.exe` |
|
||
| [DivLoader/DivLoader.vcxproj](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](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.lib`** by the librarian;
|
||
the exes link OpenAL32/d3d9/d3dx9/dinput8/dxguid/ws2_32 directly.
|
||
- `WINDOWS_IGNORE_PACKING_MISMATCH` is defined: the modern Windows SDK
|
||
`static_assert`s 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_WARNINGS` is defined: the code still uses
|
||
`stdext::hash_map`; porting to `std::unordered_map` is future work.
|
||
- `legacy_stdio_definitions.lib` is linked: the June-2010 `dxerr.lib`
|
||
references pre-UCRT stdio symbols.
|
||
- **Source fixes** (behavior-preserving): standard copy-ctor/assignment
|
||
overloads added to `Time` (rvalues can't bind to `volatile&` in standard
|
||
C++); `operator==(SOCKADDR_IN&,...)` in `NETWORK.h` made `inline`; the
|
||
L4DINPUT callbacks renamed `DIEnum*` (they collided with L4CTRL's under
|
||
LTCG); `std::ios.in` → `std::ios::in` in `CAMMGR.cpp`.
|
||
- `/FORCE:MULTIPLE` is still required: `gOpNames`, `gReplacementData`
|
||
(hash_maps defined in a header) and `GlobalEggFileName` are 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](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](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 stock `VTVRIOMapper` path 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, `L4PLASMASCALE` sets the
|
||
pixel size, default 4). It opens directly below the main view;
|
||
`L4PLASMAPOS=x,y` overrides. 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 1080` for 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 via
|
||
`Present`'s `hDestWindowOverride` (`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 when `PadRIO` is 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`:
|
||
|
||
```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](WinTesla_vc9.sln) and still build with VC++ 2008 Express
|
||
SP1 + DXSDK June 2010:
|
||
|
||
```bat
|
||
@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](docs/BUILD-NOTES.md) for the original repository
|
||
cleanup history and the findings behind the legacy build.
|