PCC-Decoder-Bugfix: RLE-Runs duerfen Zeilengrenzen ueberschreiten (Row-Reset war falsch)
Stefan hat zurecht bemaengelt dass KARTE.PCC/KELLOGGS.PCC verzerrt/verrutscht
aussehen (Smacks-Frosch an falscher Position, Notch-Fehlstelle im Logo-Rahmen).
Root Cause: Der Decoder hat RLE-Runs am Ende jeder Bildzeile hart abgeschnitten
und den Rest verworfen (klassisches PCX-Verhalten angenommen). Dieses Format
haelt sich aber NICHT an die PCX-Konvention 'ein Run ueberschreitet nie eine
Zeile' -- Runs laufen frei ueber Zeilengrenzen. Verifiziert per Pixel-fuer-Pixel-
Vergleich gegen echten DOSBox-Screenshot (world map): mit durchgehender
Dekodierung (kein Row-Reset) ist das Ergebnis jetzt pixel-identisch zur Referenz.
- tools/pcc_to_png.py: Row-Reset entfernt, decodiert jetzt width*height Pixel
am Stueck aus dem RLE-Strom
- png_out/: alle 77 PNGs mit dem Fix neu generiert
- tools/wip_bob_sprite_research/: Backup der laufenden (noch ungeloesten)
BOB-Sprite-Format-Exploration von aria-wohnung, damit nichts bei einem
VM-Neustart verloren geht
- NOTES.md: Root-Cause-Analyse dokumentiert, alte Fehldiagnose ('byte-identisch
zwischen Row-Reset und kontinuierlich') korrigiert, Rauser-Intro-Frage
beantwortet (3 Frames vorhanden, Text-Logo, keine Video-Datei)
This commit is contained in:
@@ -0,0 +1,51 @@
|
||||
from PIL import Image
|
||||
import math
|
||||
|
||||
def rle_decode_pcx_style(data):
|
||||
out = bytearray()
|
||||
i = 0
|
||||
n = len(data)
|
||||
while i < n:
|
||||
b = data[i]
|
||||
if (b & 0xC0) == 0xC0:
|
||||
count = b & 0x3F
|
||||
i += 1
|
||||
if i >= n:
|
||||
break
|
||||
val = data[i]
|
||||
out.extend([val]*count)
|
||||
i += 1
|
||||
else:
|
||||
out.append(b)
|
||||
i += 1
|
||||
return bytes(out)
|
||||
|
||||
base = "/home/aria/kellogg_remake/extracted_pre/"
|
||||
fn = "O.BOB"
|
||||
data = open(base+fn, "rb").read()
|
||||
dec = rle_decode_pcx_style(data)
|
||||
print("decoded len:", len(dec))
|
||||
|
||||
widths = list(range(8, 60, 2))
|
||||
cell_h = 80
|
||||
cell_w = 60
|
||||
cols = 8
|
||||
rows = math.ceil(len(widths)/cols)
|
||||
sheet = Image.new("L", (cols*cell_w, rows*cell_h), 40)
|
||||
|
||||
for idx, w in enumerate(widths):
|
||||
h = (len(dec) + w - 1)//w
|
||||
padded = dec + bytes(w*h - len(dec))
|
||||
img = Image.frombytes("L", (w, h), padded)
|
||||
# scale to fit cell, keep aspect
|
||||
scale = min(cell_w/w, cell_h/h)
|
||||
nw, nh = max(1,int(w*scale)), max(1,int(h*scale))
|
||||
img_r = img.resize((nw, nh), Image.NEAREST)
|
||||
cx = (idx % cols) * cell_w
|
||||
cy = (idx // cols) * cell_h
|
||||
sheet.paste(img_r, (cx, cy))
|
||||
|
||||
sheet = sheet.resize((sheet.width*3, sheet.height*3), Image.NEAREST)
|
||||
outpath = "/home/aria/kellogg_remake/tools/o_bob_grid.png"
|
||||
sheet.save(outpath)
|
||||
print("saved", outpath, "widths:", widths)
|
||||
Reference in New Issue
Block a user