Crusader_Decomp/tools/hexdump_region.py
2026-04-12 14:45:08 +02:00

45 lines
1.6 KiB
Python

import argparse
import sys
def hexdump(data, base=0, width=16):
for i in range(0, len(data), width):
chunk = data[i:i+width]
hex_bytes = ' '.join(f"{b:02x}" for b in chunk)
ascii_repr = ''.join((chr(b) if 32 <= b < 127 else '.') for b in chunk)
print(f"{base+i:08x}: {hex_bytes:<48} {ascii_repr}")
def main():
p = argparse.ArgumentParser()
p.add_argument('--file', required=True)
p.add_argument('--addr', required=True, help='PSX virtual address (e.g. 0x80064355)')
p.add_argument('--before', type=int, default=64)
p.add_argument('--after', type=int, default=256)
p.add_argument('--base', type=lambda x: int(x,0), default=0x80000000, help='PSX RAM base address used for dump offset')
args = p.parse_args()
addr = int(args.addr, 0)
base = args.base
offset = addr - base
if offset < 0:
print(f"Computed negative offset {offset} for addr {hex(addr)} base {hex(base)}", file=sys.stderr)
sys.exit(2)
try:
with open(args.file, 'rb') as f:
f.seek(0, 2)
size = f.tell()
if offset >= size:
print(f"Offset {offset:#x} beyond file size {size:#x}")
sys.exit(3)
start = max(0, offset - args.before)
f.seek(start)
data = f.read(args.before + args.after)
print(f"File: {args.file}")
print(f"PSX addr: {hex(addr)}, file offset: {hex(offset)}, dump start: {hex(start)}, len: {len(data)}")
hexdump(data, base=start)
except FileNotFoundError:
print(f"File not found: {args.file}")
sys.exit(4)
if __name__ == '__main__':
main()