DARKER Research archive

Dynamic cockpit inspection and HUD consumers

Interactive cockpit · Data · Native checks

The preview combines the recovered instruments with controllable display state for Caero, Skimma and upgraded Skimma. The windscreen is deliberately a plain inspection background; it is not a rendered world. It includes cumulative gauge strips, Caero compass and coordinates, primary/secondary icons, movable radar contacts, Skimma bearing/weapon-state sprites, three native vector-marker outlines and demonstration indicator timing.

The controls supply display states directly. They do not yet run flight, targeting, damage, charging or mission simulation. This distinction is particularly important for reserve values, shield startup and receiver behaviour.

Strip updates and engine dimming

457B–45A6 compares old/new seven-bit counts:

All 13 descriptors pass five native transition cases each. Caero engine field 4552 additionally passes the 1→129 transition: alternate packed source 2000h, strip zero, count one. The physical Caero source is (64,8), after the viewport row-table offset, instead of the normal (40,22). Its new alternate PNG is exported beside on/base, bringing that directory to 365 PNGs. The dynamic preview's engine-dimming toggle uses that patch while preserving the strip mask.

The preview redraws from the static cockpit then applies the first N strips; this reproduces final ordinary count states without requiring a history of previous slider positions. The optional receiver example uses the observed 0/1 blink field; it is not a complete implementation of Nayas message/hangar conditions.

Skimma 454E: selected weapon reserve/reload counter

C90A–C94E clears field 454E, scans the craft's weapon slots, and copies 5E13 + selected_index when that weapon is selected and enabled. Other weapons' counters do not populate this field. Thirty-six synthetic native cases cover all three indices, counter values 0–5, and enabled/disabled states.

5E1F–5E31 decrements this reserve counter when the working counter at 5E10 + index is empty, then reloads the working counter through 5E50. 5E44–5E58 refill the counters. Native reserve-capacity bytes at 5E1C are 5, 3 and 4 in weapon-index order (corrected from the earlier reordered description). This supports the label selected weapon reserve / reload count, superseding “unidentified Skimma indicator.” It does not establish a manual terminology or complete firing/rearming model.

Caero aircraft threat lights

The four red squares above the damage instrument indicate up to four nearby aircraft aiming at the player, rather than compass sectors or incoming missiles. The strongest threat is on the left. A pursuing fighter is a common cause, but an aircraft ahead of the player and aiming towards them can also illuminate a light.

Each simulation update resets four angular-error bytes at 576A–576D to 64 (3DF9). After an aircraft steers and moves, 8A58–8AA0 contributes a value only if its selected target is the player (D986) and the high byte of its previously calculated horizontal distance is below 11 (distance below 0B00h, 11 map cells). There is no additional missile-launch, weapon-readiness or line-of-sight test here.

The score adds the folded high bytes of heading and pitch errors between the aircraft's updated orientation and its earlier target bearing. Negative high bytes are complemented, not negated. The four smallest scores below 64 are retained, stored worst first. 574F–5767 converts each score to a brightness level: 14 - floor(error × 56 / 256); an unused score of 64 becomes zero. Thus better aim means brighter red, not greater proximity once inside the range limit.

Fields 4547–454A dispatch to 45DD. They draw compact-font glyph 81h at Y=180, with X=232, 224, 216, 208 respectively. Levels 1–14 use ink indices E5h + level; the edge is black for level 1 and DFh + level otherwise. Zero restores the underlying cockpit rectangle. These are shaded glyphs, not four flat-colour fills. The surface-aircraft path supplies the readings; the underground HUD producer skips this update. Isolated native checks cover 128 ranking/brightness cases and the glyph/restore calls at representative levels.

Normal Caero radar contacts

5AC9 reads player position and heading; 5AE9–5B55 walks an object list. The two normal display calls use lists at 6FD8 and 6FC8, with callback offsets BC and B9. The UI names them Group A/B without assigning an unverified allegiance.

Each contact:

  1. Must lie in the 42×42-cell candidate window, from −21 inclusive to +21 exclusive on each axis for integer-cell offsets.
  2. Is rejected when object flag bit 08h is set.
  3. Must pass the 59A3 radio-coverage predicate.
  4. Is rotated with the original signed sine/cosine table and signed high-word products, preserving truncation.
  5. Is clipped to squared radius 441 around screen (54,215).
  6. Produces one pixel. Base palette indices are F9h/F2h for the two callbacks, reduced by floor(radius_squared/32).

The JavaScript integer-cell projection matches 144 original-code cases across eight headings, boundary/interior positions and both groups, plus an explicit hidden-contact rejection. The native coverage predicate is stubbed as covered in these tests; the preview's coverage checkbox simply suppresses its synthetic contacts. Full per-region radio coverage, interference, tower markers, fractional-cell positions and enlarged/Skimma radar remain separate from this display probe. Existing radio-beacon investigation documents the coverage network.

Coordinate digits above the cockpit radar use row on the left (4546, X=44) and column on the right (4545, X=56). This follows the producer's low/high-byte position mapping and callback-directory order.

Vector target markers

These outlines are procedural assets, not bitmap crops. 5F39 supplies two halves to E302/E305; the byte stream controls the paired outlines. Native execution with captured plane-mask writes yields:

Stream Inspection label Captured pixels
5FCC Target shape A 32
5FDD Target shape B 24
5FEA Skimma aiming shape 60

The target path at 5F1F–5F39 selects the first shape for type values below 2 and the second otherwise. Native acquisition/type meanings and lock-strength colour changes are not fully translated here. The preview uses fixed explicit colour inputs (E9F3h for target shapes; 0E0Eh for the Skimma shape), stores the resulting colour indices, and allows moving the marker around the windscreen. There is no claim that those fixed colours represent every lock state.

Geometry is captured around (160,84) with a linear row table and stored relative to that anchor. The preview places it at the active viewport centre: (160,92) for Caero and (160,90) for Skimma. Follow-up: procedural HUD graphics now captures the enlarged-radar contact shape and Skimma weapon ring. The latter has fixed angular positions and a changing radius; the earlier rotating-ring description was speculative.

Timing and runtime patches

The missile-camera indicator at 54A3–54EE uses a green 4×3 rectangle at (300,0), palette index BEh. In ordinary views it requires the missile-view flag and nonzero timer bits 0180h: 128 ticks off, then 384 ticks on, repeating every 512 ticks (roughly one second). In missile camera modes (7 and above) it stays lit regardless of those timer bits. Isolated execution confirms these branches and rectangle arguments. The preview reproduces that bit pattern with an optional approximately 500-tick/second inspection clock; stopped-clock mode keeps the selected indicator visible. Menu/view-mode branches and stereo placement are not simulated.

Original runtime code differs from the untouched unpacked image at several drawing call sites. Probes use the saved DOSBox memory capture analysis/hidden-commands/ui/after-command-memory.bin.gz, loaded image segment 01A2, for the radar/shape routines. This resolves the original patched pixel/outline drawing calls rather than treating misleading pre-initialisation relative targets as real consumers. The scene-state fixtures are synthetic. Count transitions and the weapon-counter producer use the unpacked image where their consumed paths do not require those drawing patches.

Validation and reproduction

python3 tools/extract_hud.py
PYTHONPATH=/tmp/darker-python python3 tools/extract_dynamic_hud.py

Requires the prior sprite/procedural exports. The report contains 144 radar projection cases, one hidden-contact rejection, 36 selected-weapon-counter cases, 66 strip-transition cases and three native vector rasterisations (116 captured pixels). Browser checks cover all three craft selections, gauge limits, weapon/bearing states, marker choices and clock toggles. No original DOS files are changed.

Outstanding work: run the actual producer functions together over simulated flight/mission state; translate full lock acquisition and colour feedback, radio coverage/interference and all radar modes; connect shield startup/reload timing and receiver messages; complete the height-coded navigation-contact traversal and its live reference-height producer. The mono enlarged-radar surround, heading and coordinates, plus a height-colour glyph sample, are now recovered. Ring, Caero attitude pixels and enlarged contact projection are now available in the procedural HUD follow-up. The current browser is a display-state inspection rig, not a finished reimplementation of the HUD.

Craft-specific preview limits

Gameplay corrections and existing native branches constrain the assembled preview: