#!/usr/bin/env python3 """PCKELL.PRE Splitter v7 -- FINAL (2026-07-22) Format komplett verstanden: - .BOB-Eintraege (32x): kein Tag-Slot, Header direkt per Pfad-Praefix-Suche gefunden ("H:\\WIWA\\ENGINE\\GAMEDATA\\"), Header = Fundstelle-4. - Alle Nicht-BOB-Eintraege (PCC/MAP/ARE/ICO/SAM/TFX, 146x aus APPEND.LST, PLUS 3 weitere System-Dateien ohne APPEND.LST-Eintrag): Tag-Slot [1-Byte-Namenslaenge][Dateiname][Fuellmuell bis 256 Byte], danach [4-Byte-LE-Laenge][Rohdaten]. WICHTIGER FUND: APPEND.LST listet nur die 178 Spiel-Assets. PCKELL.PRE enthaelt zusaetzlich, im GLEICHEN Tag-Format, direkt im Anschluss an den letzten APPEND.LST-Eintrag (TITEL2.SAM), noch 3 System-/Runtime-Dateien: DPMI16BI.OVL, RTM.EXE, START.EXE (die DOS-Extender-Runtime -- macht Sinn, das ist ein self-contained Redistributable). Der letzte dieser 3 Eintraege endet EXAKT auf EOF (0x238966) -- damit ist das Format zu 100% verifiziert, keine Bytes bleiben unerklaert. Ergebnis: 178 (APPEND.LST) + 3 (System) = 181 Dateien total. """ import struct import os RAW = "/home/aria/kellogg_remake/raw/PCKELL.PRE" APPEND_LST = "/home/aria/kellogg_remake/raw/APPEND.LST" OUT_DIR = "/home/aria/kellogg_remake/extracted_pre" with open(RAW, "rb") as f: data = f.read() with open(APPEND_LST) as f: names = [l.strip() for l in f if l.strip()] # die 3 unlisted System-Dateien, empirisch gefunden direkt im Anschluss EXTRA_NAMES = ["DPMI16BI.OVL", "RTM.EXE", "START.EXE"] PATH_PREFIX = b"H:\\WIWA\\ENGINE\\GAMEDATA\\" N = len(data) pos = 0x100 entries = [] all_names = names + EXTRA_NAMES for i, name in enumerate(all_names): is_bob = name.upper().endswith(".BOB") if is_bob: marker = PATH_PREFIX + name.encode("ascii") p = data.find(marker, pos) if p == -1: print(f"FEHLER: Pfad fuer #{i} ({name}) nicht gefunden ab {pos:#x}") break header_start = p - 4 length = struct.unpack_from(" N: print(f"FEHLER: Datenende {data_end:#x} > Dateigroesse bei #{i} ({name}) length={length}") break entries.append((name, header_start, length, data_start, data_end, path)) pos = data_end print(f"{len(entries)} von {len(all_names)} Eintraegen gefunden.") if entries: print(f"Letztes Datenende: {entries[-1][4]:#x} von {N:#x} (Match: {entries[-1][4] == N})") mism = sum(1 for name, hs, length, ds, de, path in entries if path is not None and path.split("\\")[-1].upper() != name.upper()) print(f"BOB Pfad-Mismatches: {mism}") if len(entries) == len(all_names) and entries[-1][4] == N and mism == 0: os.makedirs(OUT_DIR, exist_ok=True) for name, hs, length, ds, de, path in entries: with open(os.path.join(OUT_DIR, name), "wb") as out: out.write(data[ds:de]) print(f">>> ERFOLG: {len(entries)} Dateien geschrieben nach {OUT_DIR}") import collections ext_count = collections.Counter(n.split(".")[-1].upper() for n, *_ in entries) print("Typen:", dict(ext_count)) else: print(">>> Unvollstaendig.") for e in entries[-5:]: print(" ", e[0], hex(e[1]), e[2])