Initial commit: RE tooling and docs for The I of the Dragon localization/HD
This commit is contained in:
@@ -0,0 +1,72 @@
|
||||
import argparse, os, struct, csv, sys
|
||||
|
||||
|
||||
def align16(x):
|
||||
return (x + 15) & ~15
|
||||
|
||||
|
||||
def collect(args):
|
||||
items = []
|
||||
if args.csv and os.path.exists(args.csv):
|
||||
with open(args.csv, newline="", encoding="utf-8") as f:
|
||||
for row in csv.DictReader(f):
|
||||
items.append((row["name"], row["file"]))
|
||||
else:
|
||||
for root, dirs, files in os.walk(args.dir):
|
||||
for fn in files:
|
||||
full = os.path.join(root, fn)
|
||||
rel = os.path.relpath(full, args.dir)
|
||||
name = rel.replace("/", "\\")
|
||||
items.append((name, rel))
|
||||
return items
|
||||
|
||||
|
||||
def main():
|
||||
ap = argparse.ArgumentParser(description="Rebuild a Dragon .res archive from a directory (16-byte aligned blobs).")
|
||||
ap.add_argument("dir")
|
||||
ap.add_argument("out")
|
||||
ap.add_argument("--csv", default=None)
|
||||
args = ap.parse_args()
|
||||
|
||||
items = collect(args)
|
||||
blobs = []
|
||||
for name, rel in items:
|
||||
full = os.path.join(args.dir, rel)
|
||||
if not os.path.isfile(full):
|
||||
print("missing: %s" % full, file=sys.stderr)
|
||||
sys.exit(2)
|
||||
blobs.append((name, open(full, "rb").read()))
|
||||
|
||||
hdr = 4
|
||||
for name, _ in blobs:
|
||||
hdr += 4 + len(name) + 8
|
||||
data_start = align16(hdr)
|
||||
|
||||
out = bytearray()
|
||||
out += struct.pack("<I", len(blobs))
|
||||
index = bytearray()
|
||||
offset = data_start
|
||||
payload = bytearray()
|
||||
for i, (name, blob) in enumerate(blobs):
|
||||
nb = name.encode("latin1")
|
||||
index += struct.pack("<I", len(nb)) + nb + struct.pack("<II", offset, len(blob))
|
||||
payload += blob
|
||||
if i != len(blobs) - 1:
|
||||
pad = align16(len(blob)) - len(blob)
|
||||
payload += b"\x00" * pad
|
||||
offset += len(blob) + pad
|
||||
else:
|
||||
offset += len(blob)
|
||||
assert len(index) + 4 == hdr, (len(index) + 4, hdr)
|
||||
out += index
|
||||
out += b"\x00" * (data_start - len(out))
|
||||
out += payload
|
||||
|
||||
with open(args.out, "wb") as f:
|
||||
f.write(out)
|
||||
print("repacked %d files -> %s (%d bytes)" % (len(blobs), args.out, len(out)))
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
|
||||
Reference in New Issue
Block a user