BOB/ICO/MAP-Formate geloest, PCKELL.DAT als echten Asset-Container entdeckt
- PCKELL.DAT ist der eigentliche Asset-Container (Index am Dateiende), nicht PCKELL.PRE -- alle 178 Assets fehlerfrei extrahierbar (tools/dat_extract.py, tools/kellogg_formats.DATContainer) - BOB (Sprites): self-modifying x86 draw-code decodiert, alle 32 Dateien / 462 Frames korrekt (Tony, Gegner, Items) -- tools/kellogg_formats.parse_bob - ICO (16x16 EGA-Tilesets) und MAP (Level-Grids, big-endian) decodiert und gerendert -- alle 19 ICO- und 22 MAP-Dateien fehlerfrei, Level W1L0 sieht korrekt aus (Haeuser, Baeume, Berge an den erwarteten Stellen) - Palette-Regeln (BOB/ICO/MAP -> passende PCC) aus der C#-Referenz uebernommen und in Python neu implementiert - Aufraeumen: PRE-basierte Extraktion (split_pre.py, extracted_pre) und alle Blindflug-Explorationsskripte aus der ersten BOB-Sackgasse entfernt, VM-Arbeitsverzeichnis von Debug-Screenshots befreit - pcc_to_png.py aktualisiert (Xmax/Ymin-Dimensionsfix, jetzt visuell gegen DOSBox-Referenz verifiziert statt nur behauptet) Offen: ARE (Kollisionszonen, auch Referenz-Projekt unvollstaendig) und SAM/TFX (TFMX-Sound) noch nicht angefasst. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,39 @@
|
||||
import struct, os
|
||||
from collections import Counter
|
||||
|
||||
SRC = '/home/aria/kellogg_remake/raw/PCKELL.DAT'
|
||||
OUT = '/home/aria/kellogg_remake/extracted_dat'
|
||||
os.makedirs(OUT, exist_ok=True)
|
||||
|
||||
with open(SRC, 'rb') as f:
|
||||
data = f.read()
|
||||
|
||||
num_entries = struct.unpack_from('<H', data, len(data)-4)[0] + 1
|
||||
offset = struct.unpack_from('<i', data, len(data)-8)[0]
|
||||
index_offset = offset
|
||||
|
||||
entries = []
|
||||
for i in range(num_entries):
|
||||
name_len = struct.unpack_from('<H', data, offset)[0]
|
||||
offset += 2
|
||||
filename = data[offset:offset+name_len].decode('ascii', errors='replace')
|
||||
offset += name_len
|
||||
e_offset = struct.unpack_from('<i', data, offset)[0]
|
||||
offset += 4
|
||||
entries.append([filename, e_offset])
|
||||
|
||||
for i, e in enumerate(entries):
|
||||
length = (entries[i+1][1] if i+1 < len(entries) else index_offset) - e[1]
|
||||
e.append(length)
|
||||
|
||||
ext_counter = Counter()
|
||||
for filename, e_offset, length in entries:
|
||||
payload = data[e_offset:e_offset+length]
|
||||
with open(os.path.join(OUT, filename), 'wb') as out:
|
||||
out.write(payload)
|
||||
ext = os.path.splitext(filename)[1].upper()
|
||||
ext_counter[ext] += 1
|
||||
|
||||
print('Extracted', len(entries), 'files to', OUT)
|
||||
for ext, cnt in sorted(ext_counter.items()):
|
||||
print(ext, cnt)
|
||||
Reference in New Issue
Block a user