Bring the graphics-dev collaborator's dpl3-revive into the repo as first-class
project code (they've handed it off; it's ours now). This is the proven
Division renderer that our in-process rt_draw has been trying to be.
What's here:
- parser/ B2Z/V2Z/SVT/SCN/SPL/BGF/BMF/BSL decoders (pure Python).
- spec/ reverse-engineered format + the definitive VelociRender wire
protocol (from the original DIVISION source, matches our live
VPX node/action tables exactly).
- source-ref/ read-only copies of the original DIVISION C (BIZREAD.C,
DPLTYPES.H, DPL.H) that define the formats.
- patha/ the "virtual VelociRender board": vrboard.py (24-action protocol
server), vrview.py (numpy software rasterizer, the reference),
vrview_gl.py (moderngl GPU backend, 832x512@60Hz), plus the
run/replay/regress tooling and evidence renders. Drives FLYK/BLADE/
Star Trek demos AND our btl4opt/rpl4opt game binaries.
- viewer/ WebGL archive generators (.py); prebuilt HTML/data regeneratable.
- samples/ small test models/textures.
- bt*.raw.bin real BTL4OPT arena wire captures (kept for offline renderer
testing/regression against OUR game).
.gitignore keeps the multi-hundred-MB demo capture dumps + debug logs +
regeneratable viewer bundles out of history (they stay on disk).
Phase 0 of the integration is validated: their board decodes our bt8 capture
with zero errors (3748 nodes, 507 instances, 4 mechs) and renders our arena
(terrain/dome/sky, correct Division DAC gamma). Plan + status in memory;
integration continues in emulator/RENDERER-COLLAB.md.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
74 lines
3.2 KiB
Python
74 lines
3.2 KiB
Python
#!/usr/bin/env python3
|
|
"""
|
|
verify_framing.py -- static check that the SHIPPED FLYK.EXE frames the VelociRender
|
|
protocol exactly the way vrboard.py assumes (framing derived from VR_COMMS.C source).
|
|
|
|
Confirms, inside the real binary's code object:
|
|
* the length-word broadcast mask (0xff<<16) = 0x00FF0000 (velocirender_transmit)
|
|
* the iserver control bit 0x80000000 (send_link_protocol)
|
|
* the packetize chunk size 512-4 = 508 = 0x1FC (velocirender_packetize)
|
|
* C012 link-adapter port I/O IN/OUT via DX (LINKIO.C)
|
|
* the default link base 0x150 (getXputer)
|
|
|
|
Usage: python verify_framing.py /path/to/FLYK.EXE
|
|
"""
|
|
import sys
|
|
from leimage import LE
|
|
try:
|
|
from capstone import Cs, CS_ARCH_X86, CS_MODE_32
|
|
except ImportError:
|
|
Cs = None
|
|
|
|
def le32(v): return bytes([v & 0xff, (v>>8)&0xff, (v>>16)&0xff, (v>>24)&0xff])
|
|
|
|
def scan(img, needle):
|
|
hits, i = [], img.find(needle)
|
|
while i != -1:
|
|
hits.append(i); i = img.find(needle, i+1)
|
|
return hits
|
|
|
|
def main(path):
|
|
le = LE(path)
|
|
base, img = le.image(1) # code object
|
|
print(f"code object: base={base:#x} size={len(img):#x} ({len(img)} bytes)\n")
|
|
|
|
checks = {
|
|
"length-word mask 0x00FF0000 (broadcast id | count)": le32(0x00FF0000),
|
|
"iserver control bit 0x80000000": le32(0x80000000),
|
|
"packetize chunk 0x000001FC (512-4)": le32(0x000001FC),
|
|
"default link base 0x00000150 (getXputer)": le32(0x00000150),
|
|
}
|
|
results = {}
|
|
for label, needle in checks.items():
|
|
hits = scan(img, needle)
|
|
results[label] = hits
|
|
mark = "OK " if hits else "-- "
|
|
where = ("VA " + ", ".join(f"{base+h:#x}" for h in hits[:4]) +
|
|
(" ..." if len(hits) > 4 else "")) if hits else "not found as literal"
|
|
print(f"[{mark}] {label:52} {len(hits):3} hit(s) {where}")
|
|
|
|
# x86 port I/O: IN/OUT with DX (EC in AL,DX / ED in eAX,DX / EE out DX,AL / EF out DX,eAX)
|
|
portio = {op: img.count(bytes([op])) for op in (0xEC,0xED,0xEE,0xEF)}
|
|
print(f"\nport-I/O opcodes (raw byte freq, upper bound): "
|
|
f"IN AL,DX={portio[0xEC]} IN eAX,DX={portio[0xED]} "
|
|
f"OUT DX,AL={portio[0xEE]} OUT DX,eAX={portio[0xEF]}")
|
|
|
|
# Disassemble a window around the first length-word-mask hit to show the OR that builds it.
|
|
if Cs and results[next(iter(results))]:
|
|
h = results["length-word mask 0x00FF0000 (broadcast id | count)"][0]
|
|
md = Cs(CS_ARCH_X86, CS_MODE_32)
|
|
lo = max(0, h-24)
|
|
print(f"\n--- disasm around length-word construction (VA {base+lo:#x}) ---")
|
|
for ins in md.disasm(img[lo:h+16], base+lo):
|
|
print(f" {ins.address:#010x} {ins.mnemonic:6} {ins.op_str}")
|
|
elif not Cs:
|
|
print("\n(capstone not available -- byte-literal scan only)")
|
|
|
|
print("\nVERDICT:", "framing constants present -> shipped FLYK matches the source-derived protocol"
|
|
if results["iserver control bit 0x80000000"] and
|
|
results["length-word mask 0x00FF0000 (broadcast id | count)"]
|
|
else "framing constants NOT all found as literals -- inspect (may be computed)")
|
|
|
|
if __name__ == '__main__':
|
|
main(sys.argv[1])
|