pvision solved (texture-value ramp) + i860/hardware reverse-engineering
Predator/IR vision: reverse-engineered from the original firmware and
confirmed by the build team -- it is the Division board's TEXTURE-VALUE RAMP
mode (a "check your texture maps" diagnostic the devs hijacked), NOT a
grayscale squash or a false-colour palette. Located in VREND.MNG (effect
handler @0xe6c0, wire action 0x1b, type -1 ON / -2 OFF); ramp colours from
VR_DRAW.C. Renderer reworked to match: vrview_gl now does the 4-ramp
lerp(color0,color1,luminance(texel)) in the mesh pass (grayscale+defog
removed). Live-rendered on a new night-clear arena egg; crew A/B verdict
pending.
Firmware-decomp toolchain (emulator/firmware-decomp/), all built from the
project's own artifacts and validated:
- coff860.py i860 COFF reader (symbols/sections), names match AS860 source
- derive860.py derives the i860 opcode map from matched .S<->.O pairs
- dis860.py i860 disassembler (98% on clean ground truth; proven on
VREND.MNG -- velocirender_statistics decodes correctly)
- sigmatch860.py reloc-invariant signature matcher onto the stripped image
- i860-encoding.md / FIRMWARE-SYMBOLS.txt / README.md
PVISION-IMPLEMENTATION-GUIDE.md: self-contained hand-off for the BT411 team.
HARDWARE-ARCHITECTURE.md + hardware-photos/ (15 board shots): the Division
VelociRender card is a 2-board stack driving a 3-processor pipeline --
INMOS IMS T425-J25S (comms/control, runs vrendmon.btl) + Intel i860 XP-50 (FP
geometry, runs vrender.mng) + Division PXPL IGC 5.2 ASIC with ~48x PXPL EMC
5.1 (UNC Pixel-Planes-5 SIMD array; "EMC" = the firmware's configEMCs) +
Analog Devices ADV7150 RAMDAC + NTSC. Plus the VWE Video Distribution Board
(P/N 1404: AMD MACH130 + 3x Brooktree Bt477) for the 3-VGA-head cockpit split.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -498,3 +498,90 @@ first appear in the 0x1f stream -- next session, have the pilot narrate
|
||||
("holding hat-left NOW") and read the log; if nothing appears during holds,
|
||||
compare against a 7/07-style run (gauge_arena_sound.conf, no net stack) to
|
||||
isolate what enables the eyepoint emission.
|
||||
|
||||
---
|
||||
|
||||
## 2026-07-14: Where the IR / thermal palette actually lives (source hunt)
|
||||
|
||||
Operator question: does the game tell the Division card *which* palette to use
|
||||
for IR/predator vision, or is the card's firmware around to decompile? Answer:
|
||||
**the game specifies no palette at all -- it just flips a switch; the palette
|
||||
is baked into the i860 board firmware.**
|
||||
|
||||
Chain of evidence (all from THIS project's primary sources -- OUR dump is the
|
||||
authority; BT411 is a downstream reconstruction *of* this and is NOT cited):
|
||||
|
||||
1. **Our own game source: `CODE/RP/MUNGA_L4/L4VIDEO.CPP:5535`,
|
||||
`DPLRenderer::DPLTogglePVision()`** -- the real, shipped, non-stubbed
|
||||
implementation (the engine `DPLRenderer` is shared by BT and RP). Comment
|
||||
reads `toggles the state of dpl "predator" vision`. Verbatim:
|
||||
```cpp
|
||||
static Logical pvision_on = 0;
|
||||
dpl_EXPLOSION_EFFECT_INFO sfx_info;
|
||||
sfx_info.x = sfx_info.y = sfx_info.z = 0;
|
||||
if ((pvision_on ^= 1) != 0) { ... sfx_info.type = -1; } // pvision ON
|
||||
else { ... sfx_info.type = -2; } // pvision OFF
|
||||
dpl_Effect(dpl_effect_type_explosion, NULL, &sfx_info);
|
||||
```
|
||||
Pvision is sent as a **special "explosion" effect at the origin with
|
||||
`type = -1 / -2`**. The struct (`CODE/RP/MUNGA_L4/libDPL/dpl/DPLTYPES.H:278`,
|
||||
`{float x,y,z; int32 type; dpl_TEXTURE *tex;}`) has **no colour field** --
|
||||
so the game hands the board zero palette information. (This also corrects an
|
||||
earlier disasm misread that thought an RGB triple + matrix was being sent;
|
||||
there is none.)
|
||||
|
||||
2. **DPL3 SDK source (`sda4/DPL3`, `sda4/DPL3RLS`).** The board effect
|
||||
dispatcher `PAZsfx()` (`VRENDER/SFX.C:751`) only handles explosion codes
|
||||
`0/1/2`; there is **no `-1/-2` branch and no DAC/palette flip anywhere in
|
||||
this source**. This VRENDER source is the 1994-95 vintage (DPL3RLS build
|
||||
dirs `VR_40826`..`VR_50329`) -- it **predates the pvision feature**.
|
||||
|
||||
3. **The exe itself.** Same as (1): the on/off flag is all that crosses the
|
||||
wire. Nothing selects a colour.
|
||||
|
||||
So the palette is the **board's built-in response to explosion type -1/-2**,
|
||||
i.e. it lives in the i860 firmware, not in the game, the SDK, or the exe.
|
||||
|
||||
### Is the firmware around / decompilable? Yes.
|
||||
|
||||
The board-load images are in the dump as `VRENDMON.BTL` (plus the `VREND2..9`
|
||||
overlays per game). Dated build tree `sda4/VREND/` runs **Oct 1995 -> Jun 1996**
|
||||
(`51019` ... `60623EDO`), newer than the source we have; the production images
|
||||
are `sda4/BTLIVE/` and `sda4/RPLIVE/`. The newest (`VREND/60623EDO/
|
||||
VRENDMON.BTL`, 13 Jun 1996, 85 KB) is **raw i860 machine code** -- opens
|
||||
`f0 b4 d1 d1 ...`, no COFF/ELF wrapper, no symbol/string table (grep for
|
||||
vision/pred/therm/heat/palette = nothing; strings are stripped/packed).
|
||||
|
||||
Bottom line for the crew:
|
||||
- The **exact** IR palette can only come from **reversing the i860
|
||||
`VRENDMON.BTL`** (Ghidra has an i860 module; same workflow the BT411 team
|
||||
already runs). Target: the colour/DAC transform gated by the effect
|
||||
`type == -1`. It's a real RE effort (stripped code) but the binary is here.
|
||||
- Until then our `heat` palette is an educated interim; the IR-vision-options
|
||||
sheet (heat/green/amber/mono) is the fast path if a crew member simply
|
||||
*recognises* the original look.
|
||||
- Empirical cross-check: hitting the cockpit IR button in the live sim already
|
||||
drives `board.pvision` through action `0x1b` mode `-1/-2` -- exactly the
|
||||
explosion-type encoding above -- so the mechanism is confirmed end to end;
|
||||
only the colour LUT is unknown.
|
||||
|
||||
### Revised model (operator, 2026-07-14): grayscale squash + fog off, not a palette
|
||||
|
||||
Operator's read: predator vision is probably **not** a false-colour palette
|
||||
swap -- it's a **per-pixel squash to grayscale plus fog turned OFF** (so
|
||||
targets read through night/weather). This fits everything: the game sends no
|
||||
colour, and "see through the murk" is the same family of trick as the
|
||||
searchlight (which turned out to be a view-fog push-back, not a light cone).
|
||||
`heat`/`green`/`amber` were only ever an interim guess at the *name*
|
||||
"predator".
|
||||
|
||||
Renderer changed to match (`dpl3-revive/patha/vrview_gl.py`):
|
||||
- default `VRVIEW_PVISION_PALETTE` flipped `heat` -> `mono` (grayscale squash).
|
||||
- when pvision is active, the **scene pass forces `fog_on = 0`** (a present-
|
||||
pass recolour alone cannot undo fog already baked into the pixels).
|
||||
- green/amber/heat ramps retained purely as opt-in crew A/B (`VRVIEW_
|
||||
PVISION_PALETTE=green|amber|heat`).
|
||||
|
||||
Still a hypothesis pending a live look + crew memory; the ground-truth remains
|
||||
recoverable by reversing the i860 `VRENDMON.BTL` (colour/DAC transform gated by
|
||||
effect `type == -1`).
|
||||
|
||||
@@ -0,0 +1,78 @@
|
||||
[sdl]
|
||||
output=opengl
|
||||
# higher,higher not highest: HIGH_PRIORITY_CLASS starved the host desktop;
|
||||
# with the retry patches a rare dropout self-recovers (see gauge_rio.conf).
|
||||
priority=higher,higher
|
||||
[dosbox]
|
||||
memsize=32
|
||||
machine=svga_s3
|
||||
[cpu]
|
||||
core=dynamic
|
||||
cputype=pentium
|
||||
cycles=max
|
||||
[sblaster]
|
||||
sbtype=sb16
|
||||
sbbase=220
|
||||
irq=5
|
||||
dma=1
|
||||
hdma=5
|
||||
[mixer]
|
||||
# match the EMU8000s' native rate (no resample) and buffer ~60ms so brief
|
||||
# emulation-thread stalls (RIO retry recovery) don't audibly chop
|
||||
rate=44100
|
||||
blocksize=1024
|
||||
prebuffer=60
|
||||
[ne2000]
|
||||
# real pods loaded the ODI stack in AUTOEXEC before ANY game launch --
|
||||
# weapons-fire test: bare -egg run WITH the packet stack resident (the game's
|
||||
# WATTCP identity is 200.0.0.113 from REL410\BT\WATTCP.CFG). nicbase 340:
|
||||
# 300 clashes with the VDB and blanks heads. backend=slirp: THIS build lacks
|
||||
# pcap ("Backend not supported"); slirp = user-mode NAT, no LAN peers, but
|
||||
# the packet driver functions and accepts sends -- enough for a solo fire
|
||||
# test. For pod<->console runs use a pcap-enabled build (net_full.conf).
|
||||
ne2000=true
|
||||
nicbase=340
|
||||
nicirq=3
|
||||
backend=slirp
|
||||
[serial]
|
||||
# RIO on COM1 with the low-latency options (rxpollus/rxburst) so the board's
|
||||
# few-ms ACK deadline is met; plasma display on COM2 (real pod has both).
|
||||
serial1=namedpipe pipe:vrio rxpollus:100 rxburst:16
|
||||
serial2=namedpipe pipe:vplasma
|
||||
[autoexec]
|
||||
mount c "C:\VWE\TeslaRel410\ALPHA_1"
|
||||
mount d "C:\VWE\TeslaRel410\emulator\net-boot"
|
||||
d:
|
||||
echo === loading NE2000 packet-driver stack (as production AUTOEXEC did) ===
|
||||
d:\lsl
|
||||
d:\ne2000
|
||||
d:\odipkt
|
||||
c:
|
||||
cd \REL410\BT
|
||||
set VIDEOFORMAT=svga
|
||||
rem production pod card init (PARAMETR.BAT:181-186): DIAGNOSE + AWEUTIL per
|
||||
rem card -- AWEUTIL /S does the EMU8000 bring-up and DRAM detect the HMI SOS
|
||||
rem driver relies on; skipping it left the cards uninitialized (silent).
|
||||
rem aweutil /s SKIPPED for now: it verifies the AWE32 GM ROM, which the
|
||||
rem emulated cards lack (hangs in a retry loop) -- restore once the ROM is
|
||||
rem dumped from a real card. diagnose /s kept (passes, sets mixer config).
|
||||
set BLASTER=A220 I5 D1 H5 P330 T6
|
||||
c:\sb16\diagnose /s
|
||||
set BLASTER=A240 I7 D3 H6 P300 T6
|
||||
c:\sb16\diagnose /s
|
||||
set BLASTER=A220 I5 D1 H5 P330 T6
|
||||
set TEMP=c:\
|
||||
rem arena1 city mission (TESTARN.EGG: map=arena1, time=day), RIO attached,
|
||||
rem bare -egg launch (no netnub) = the user's real-world test-egg setup.
|
||||
set HEAPSIZE=15000000
|
||||
set L4GAUGE=640x480x16
|
||||
call setenv.bat r f s p
|
||||
32rtm.exe -x
|
||||
rem stdout -> log: this optimized build still emits DEBUG_STREAM lines (the
|
||||
rem RIO retry spam proved it) -- capture the weapon fire-refusal reason.
|
||||
rem DOS flushes in 4KB chunks; the tail lands on clean exit (mission timer).
|
||||
btl4opt.exe -egg testnclr.egg > c:\weaponlog.txt
|
||||
32rtm.exe -u
|
||||
echo ALPHA1-RUN-DONE
|
||||
pause
|
||||
|
||||
Reference in New Issue
Block a user