#!/usr/bin/env python3 """Packs an image as Argonaut .cor (counterpart of cor2png.py). The image is converted to 640x480 RGB and compressed with the game's LZ scheme: n < 0x80 -> n bytes of raw data follow (n = 1..127) 1LLL oooo oooooooo -> copy L+3 bytes (3..10) from o bytes (1..4095) back Usage: png2cor.py input.png output.cor (requires Pillow) """ import struct import sys MAGIC = bytes.fromhex('1798af89fe42d112') MAXOFF, MINLEN, MAXLEN = 0x0FFF, 3, 10 def pack(raw): out = bytearray() lit = bytearray() last = {} # 3-byte prefix -> list of recent positions def flush(): for k in range(0, len(lit), 127): part = lit[k:k + 127] out.append(len(part)) out.extend(part) lit.clear() i, n = 0, len(raw) while i < n: best_len, best_off = 0, 0 if i + MINLEN <= n: key = raw[i:i + 3] for p in reversed(last.get(key, ())): off = i - p if off > MAXOFF: break ln = 3 while ln < MAXLEN and i + ln < n and raw[p + ln] == raw[i + ln]: ln += 1 if ln > best_len: best_len, best_off = ln, off if ln == MAXLEN: break step = best_len if best_len >= MINLEN else 1 for j in range(i, min(i + step, n - 2)): lst = last.setdefault(raw[j:j + 3], []) lst.append(j) if len(lst) > 16: del lst[0] if best_len >= MINLEN: flush() out.append(0x80 | ((best_len - 3) << 4) | (best_off >> 8)) out.append(best_off & 0xFF) i += best_len else: lit.append(raw[i]) i += 1 flush() return MAGIC + struct.pack('