Files

74 lines
2.8 KiB
Python

#!/usr/bin/env python3
"""ARE-Format-Decoder (geknackt 26.07.2026, NOTES Eintrag (24)).
Aufbau einer .ARE-Datei (alles Big-Endian):
@8..48 Header: 10 u16-Paare (u.a. Zeit?, Masse, markante Punkte --
Bedeutung teils offen; Paar 0 = (Levelzeit?, Pixelbreite?))
@60 weiteres Koordinatenpaar
@352 SEKTOR-TABELLE: (map_px_w/64 aufgerundet) x (map_px_h/64
aufgerundet) BE-u16-Offsets, Zeile fuer Zeile; 0xffff = leerer
Sektor, sonst zeigt (Offset + 352) auf die Objektliste.
Objektliste: 0xffff-Marker, dann Records aus 3 BE-u16:
[Typ] [dx] [dy] (dx/dy = Pixeloffset im 64x64-Sektor)
bis zum naechsten 0xffff (Start des naechsten Blocks).
Bekannte Typen (W1L1-Abgleich):
151 = Cerealie (Sammelitem, HUD-Zaehler), 154 = Cerealie im Wasser
199 = Tuer (liegt exakt auf der Haus-Tuer 12,37)
71/72/73/76 = ?-Box-Inhalte (liegen auf den ctype-4-Tiles = ?-Boxen)
194..208 = Level-Moebel (Lampen, Deko), 1/2/3/11/12/17/18/20/31 =
vermutlich GEGNER-Spawns (per DOSBox noch zuzuordnen), 101/102 = Levelende?
Aufruf: python3 tools/are_dump.py W1L1
"""
import os
import struct
import sys
sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..'))
from game import formats # noqa: E402
def parse_are(are_bytes, map_w_tiles, map_h_tiles):
'''Liefert Liste (x_px, y_px, typ), Koordinaten in Map-Pixeln.'''
d = are_bytes
sec_w = (map_w_tiles * 16 + 63) // 64
sec_h = (map_h_tiles * 16 + 63) // 64
objs = []
for sy in range(sec_h):
for sx in range(sec_w):
idx = sy * sec_w + sx
off = struct.unpack('>H', d[352 + idx * 2:354 + idx * 2])[0]
if off == 0xffff:
continue
q = 352 + off
while q < len(d) - 1:
v = struct.unpack('>H', d[q:q + 2])[0]
if v == 0xffff:
if q == 352 + off:
q += 2
continue
break
typ, dx, dy = struct.unpack('>3H', d[q:q + 6])
objs.append((sx * 64 + dx, sy * 64 + dy, typ))
q += 6
return objs
def main():
name = sys.argv[1] if len(sys.argv) > 1 else 'W1L1'
dat = os.environ.get('KELLOGG_DAT', os.path.join(
os.path.dirname(__file__), '..', 'game', 'original', 'PCKELL.DAT'))
c = formats.DATContainer(dat)
w, h, _ = formats.parse_map(c.entries[name + '.MAP'])
objs = parse_are(c.entries[name + '.ARE'], w, h)
from collections import Counter
print(f'{name}: {len(objs)} Objekte, Map {w}x{h} Tiles')
print('Typen:', dict(sorted(Counter(t for _, _, t in objs).items())))
for x, y, t in objs:
print(f' Typ {t:3d} (0x{t:02x}) px ({x:4d},{y:4d}) Tile ({x // 16},{y // 16})')
if __name__ == '__main__':
main()