Skip to content

Campaign / Mission / Pilot

The single-player meta-game: the theater mission map screen, the scripted ZONE threats, pilot save/logbook, and the .CAM campaign state machine that strings missions together with scoring. Re-carved from a grab-bag nominal range into its true clusters (the mission-map editor 0x421C70–0x42B800 plus pilot/campaign/mission cores in 0x467110–0x490000).

Provenance: Ghidra static analysis of the game executable with FA.SMS symbols applied; recorded in the symbol database and applied to the Ghidra project. Progress: reconstruction matrix. Markers follow spec-authoring.md: confirmed · inferred · unknown.

The pieces

  • Mission map (MAP*, 0x421C70–0x42B800): the theater-map screen — world↔screen coordinate transforms (MAPScreenToWorld), background/grid/icon/path drawing, waypoint editing (MAPWPListBounds), and the object placement the mission builder uses.
  • ZONE threats: scripted threat zones that fire projectiles/explosions on a time schedule — ZONEActive (active-window test), ZONEServiceRange, ZONEPickTarget.
  • Pilot (PLT*, 0x467180–0x468FD0): the pilot save (PILOT.BKP), sorted rosters, and the logbook / "paper" record builder.
  • Campaign (.CAM state machine, 0x480750–0x4869A0): _CallCampaignProc drives the _campaignState (active → dead/fail → planning); mission load runs through _CallMissionProc + _MISSIONInit2, and scoring accumulates via _MISSIONAddScore.

Campaign flow: the .CAM state machine drives mission selection; each mission loads, plays, and scores back into the pilot record.

Functions

Full record: db/symbols/campaign.csv.

VA Symbol Role
0x4224B3 MAPScreenToWorld inverse map projection (screen → world)
0x42256A MAPLoadBG load the theater-map background
0x421D40 ZONEActive scripted-threat active-window test
0x422120 ZONEPickTarget pick a target plane for a zone
0x422190 MAPWPListBounds walk a waypoint list

Open Questions

1. TIME/FPS utility block — resolved

0x4869A0–0x486E60 is a self-contained game-clock + FPS + timer-interrupt cluster, not campaign code. Its functions are almost all FA.SMS-named: TIMESystemTime (0x4869A0), TIMEInit/TIMERestart/TIMEUpdate, TIMESetCompression (0x486C60), FPSInit/FPSUpdate/ FPSPrint/FPSPrint2/FPSReturn, and InstallTimerInt (0x486E20), plus two helpers — FUN_00486BF0 (a QueryPerformanceCounter-based high-resolution frame-time via __alldiv) and FUN_00486DC0 (a strlen used by the FPS string formatting). It drives the very globals in game-loop.md § Frame Timing (_timerTicks, _currentTime, _timeCompression). Disposition: it is its own small timing subsystem — recommend a standalone timing row in db/subsystems.csv (≈13 functions, 2 still FUN_) rather than annexing it to campaign; tracked alongside the game-loop discovery #257.

Status: resolved — re-static (identified as the TIME/FPS timing cluster; homing tracked in #257).