Skip to content

Latest commit

 

History

History
193 lines (153 loc) · 9.76 KB

12-open-questions.md

File metadata and controls

193 lines (153 loc) · 9.76 KB

Open questions

Everything this pipeline did not settle, with the measurement beside it. An honest question is worth more than a plausible answer.

1. The RNC\2 decruncher does not round-trip

The measurement. The routine is 380 bytes at hunk 0x1DA30 of /captiveII and it is fully transcribed in 05-compression.md and tools/rnc2.py. On loading.asp (1,825 packed bytes, 3,768 unpacked) the transcription decodes:

  • token 1 correctly — a ten-byte literal run that writes 00 02 50 fd 60 00 32 65 00 00 to output offsets 3,758–3,767, which is byte for byte the last ten bytes of the packed stream. A backwards decoder's first token has to be exactly that, so the bit reader, the sentinel mechanism, the literal-count code and the direction are all confirmed;
  • token 1's match correctly — a short match, six-bit offset field, offset 8, length 2, reading inside the ten bytes just written;
  • token 2 incorrectly — a short match with a six-bit offset of 24 when only twelve bytes exist. Bits 0,0,0 then 0,1,1,0,0,0 out of src[1810] = 0x0C and src[1809] = 0x2E.

Allowing reads past the end of the buffer, the decode runs to 203 tokens and stops with the write pointer at 1,302 instead of 0 and the read pointer three bytes past the start.

What was ruled out. A search over both branch senses, the presence of the priming byte, all six permutations of the three offset tiers, three short-match base values, three interpretations of the source pointer for the copy, the literal-count loop's start values and comparison sense, and ±1 on the copy counts. None reaches the end of a file.

What is most likely. A one-bit error somewhere in the match grammar, or a misread of the two DBcc unary tiers. Anyone with a 68000 emulator can settle it in an afternoon by single-stepping the routine on loading.asp and diffing the token stream against rnc2.py.

What it costs. The contents of intro.sty, end-good.sty, end-bad.sty, StartUp.ASP, loading.asp and c/warning's data hunk — the intro, both ending sequences, the loading screen and the reset warning. Their directory is plain text and is listed below.

2. What is inside the .ASP scripts

The three .sty directories (tools/sty.py) name 42 packed scripts, and StartUp.ASP and loading.asp are two more. The head of a packed stream is a literal run, so the first bytes of the unpacked file are readable without decoding: loading.asp begins FORM ·· ANIM NAME ·· "Loading" ·· BU. So .ASP is an IFF animation format played by c/playasp 1.7, and the scene list — 20 distinct names in 23 intro.sty entries, since three scenes have two directory entries each — is:

intro.sty     INTRO  Medal  DeskBord  present  LegOff  HitComp  ScrInfo
              Phonecal  phoneclo  scanline  opentube  PALM  TUBE  outtube
              Armoury  van  city  talkfld  Liberation  credits
end-good.sty  Earth  Space1  Space2  ScanShip  Hatch  OutHatch  ManScan
              DroidFace  TrillTalk  HandDisk  GATE  OverHead  Emperor
end-bad.sty   Police  CHIP  radar  BASE  FROZEN

The chunk layout inside a decompressed .ASP is unknown, as is what c/playasp's four command lines (-m^2, -m^3, -m^4, K) select.

3. PLST — the polygon lists

What is known. EXVL decodes completely: UWORD count then count × 16 bytes of WORD x, WORD y, WORD z and ten bytes of run-time scratch. That reproduces the chunk length exactly on 294 of the 367 objects in the 40 files.

What is not. PLST opens with 0x0000 and one of 0x0028, 0x002C, 0x002E — a header length that varies by object — and the four words before the first polygon are the object's bounding box. The polygon records themselves, the vertex indices, the surface attributes and how a wall sprite from a WallNN.VGM bank is chosen for a face are all unread. PLST is between 474 and 16,032 bytes per file and is 60 % of the geometry data.

Seventy-three EXVL chunks carry a tail after the last vertex, 4 to 74 bytes, always an even length. The bytes look like vertex indices — on 42 of the 73 every byte is below that object's own vertex count, and 41 of the 73 end in 00 — but 31 of them contain a byte the object has no vertex for, and one reaches 255. So it is an index list into something, and not necessarily into EXVL. Distribution of tail lengths: 0 (×294), 4 (×6), 6 (×10), 10 (×8), 12 (×11), 16, 18, 24 (×5), 30 (×2), 32 (×21), 34 (×4), 42, 44, 46, 74.

4. What the second axis of the 0/1/2/3 sets is

Sets 0 and 2 have identical vertex counts and identical PLST lengths across all seven families, and so do sets 1 and 3; only the file sizes differ, by 15–30 % (07-3d-engine.md). So the four sets are two geometries crossed with two of something else, not four levels of detail. The difference is inside PLST and is most likely surface or shading data, but that follows from question 3.

5. The VFTX chunk

/Demo.vfx (5,430 bytes) and the tail of Objects.x3g are the only two instances. Both begin

'VFTX' 00 80 80 00 81 01 82 02 80 00 9f 1f 9e 1f 9e 1e 9e 1d 9d 1c ...

— byte pairs where the first of each pair has bit 7 set and the second does not, differing by a constant 0x80 for long runs and then diverging. It is a texture, shading or dither table; nothing on the disc reads Demo.vfx, and the Objects.x3g copy is reachable only through whatever PLST says.

6. The nested layout inside 3dView.img

The other three ImgA containers hold images directly. 3dView.img's 23 entries each begin with a count word and a run of 16-bit sub-offsets before any image header, so it is a container of containers, and the first sub-entry of entry 0 reads 0006 000E 00F4 01B0 0242 02C6 0320 — a count of 6 and six offsets. The inner image headers do not match the outer ImgA image header layout at the offsets those pointers give, so the inner records use a shorter header that has not been worked out. All 23 outer entries are 14 pixels wide and 74 to 244 rows tall, which is the vertical furniture beside the viewport.

7. What the four AmSp banks in a WallNN.VGM divide by

Every one of the 71 files holds exactly four banks of 42, 45, 24 and 41 sprites with identical geometry (08-graphics.md). Distance is the obvious reading and the sprite sizes are consistent with it — bank 2's sprites reach 96×100 and bank 3's are mostly 16 wide — but nothing on the disc states it, and 42/45/24/41 is not a shape that suggests an obvious partition of viewing angles either.

8. What $3299(a5) is set by

The byte at $3299(a5) gates the opens of nonvolatile.library and lowlevel.library and nothing else (06-executables.md). It is exactly the two CD32-only modules, so it reads as an "assume a plain A1200" switch — but the code that writes it was not found. A command-line argument, a RAM:Game.DAT field, a SetJoyPortAttrsA failure and a machine probe are all consistent with what is visible.

9. Where the save game actually lives

Three mechanisms are present and it is not settled which is primary:

  • nonvolatile.library is opened and all four of its vectors are called exactly once — ReadNVData, WriteNVData, FreeNVData, GetCopyNVList;
  • RAM:Game.DAT is a string in the executable, next to .SAV;
  • the boot script mounts a recoverable RAM disk (ramdrive.device, 132 KB, relabelled Ram_Reset) and installs a bootable startup sequence on it that runs c/WARNING (04-boot-chain.md);
  • Lib-Saves is a floppy volume name compiled into the binary.

The reading that fits all four is: the live game state lives in RAM: and survives a reset in the recoverable RAM disk, c/WARNING tells the player what happened, nonvolatile.library holds something small and permanent (a high-score table, or a pointer), and Lib-Saves is the floppy release's answer that the CD build kept the code for. Confirming it needs the packed c/warning text, which needs question 1.

10. The 8SVX headers are wrong in two different ways

The seven named samples inside intro.sty have sCompression = 3 and 4, values IFF 8SVX does not define, and oneShotHiSamples = twice the sample count. The 39 samples in Samples*.BIN have sCompression = 0 and oneShotHiSamples = 0 with the length in repeatHiSamples. The 2,433 speech clips have sCompression = 0 and a sensible oneShotHiSamples. Three converters, three conventions, and nothing on the disc reads any of those fields. Whether the intro.sty seven are actually delta-compressed is not established; their entropy is consistent with raw PCM but that is weak.

11. Who D J Pocock is

The ISO's data-preparer field reads D J Pocock - ISOCD 1.04 by Pantaray, Inc. USA -. The name appears nowhere else in 169 MB. On four of the six other discs in this series the preparer turns out to be findable in the title's own credits; here there is no credits screen in readable form (the credits are credits.asp, inside intro.sty, behind question 1).

12. Why 232 unclaimed sectors

Marvin, Prey CD32, Speris and Legends each leave exactly 32 zero sectors at the end of the ISO volume; this disc, cut with the same ISOCD 1.04, leaves 232, and the image overruns the declared volume by 103 sectors where the recurring value elsewhere is 152 or 106. All 335 sectors are zero. Whether the 232 is a function of volume size, of the mastering session, or of something else needs a sixth ISOCD disc.

13. What the c/warning screen says

548 bytes of code and 7,184 bytes of packed data. It opens intuition.library and graphics.library, it is the entire content of the reset-surviving RAM disk, and it is the one thing on the disc a player would see that nobody has read. Question 1 again.