()
| 2 | import struct |
| 3 | |
| 4 | def main(): |
| 5 | parser = argparse.ArgumentParser( |
| 6 | description="This basically is bin2c" |
| 7 | ) |
| 8 | parser.add_argument("address", help="Memory address (e.g., 0x80234500)") |
| 9 | parser.add_argument("size", type=int, help="Number of elements") |
| 10 | parser.add_argument("datatype", choices=[ |
| 11 | "s8", "u8", "s16", "u16", "s32", "u32", "s64", "u64", "f32", "f64" |
| 12 | ], help="Data type of elements") |
| 13 | args = parser.parse_args() |
| 14 | |
| 15 | fmt_map = { |
| 16 | "s8": ("b", 1), "u8": ("B", 1), |
| 17 | "s16": ("h", 2), "u16": ("H", 2), |
| 18 | "s32": ("i", 4), "u32": ("I", 4), |
| 19 | "s64": ("q", 8), "u64": ("Q", 8), |
| 20 | "f32": ("f", 4), "f64": ("d", 8), |
| 21 | } |
| 22 | fmt_char, type_size = fmt_map[args.datatype] |
| 23 | total_bytes = args.size * type_size |
| 24 | |
| 25 | address = int(args.address, 16) |
| 26 | dol_offset = address - 0x80003000 # lazy way to get get offset in the dol |
| 27 | |
| 28 | # open dol, jump to offset and read data |
| 29 | with open("orig/MarioClub_us/sys/main.dol", "rb") as f: |
| 30 | f.seek(dol_offset) |
| 31 | data = f.read(total_bytes) |
| 32 | |
| 33 | fmt = f">{args.size}{fmt_char}" |
| 34 | values = struct.unpack(fmt, data) |
| 35 | |
| 36 | # if datatype is only 8 bits, print 8 per line, otherwise print 4 |
| 37 | vals_per_line = 4 if type_size != 1 else 8 |
| 38 | |
| 39 | for i, val in enumerate(values): |
| 40 | if i % vals_per_line == 0: |
| 41 | print(" ", end="") |
| 42 | if isinstance(val, float): |
| 43 | print(f"{val:.8g}", end=", ") |
| 44 | else: |
| 45 | print(f"0x{val & ((1 << (type_size * 8)) - 1):0{type_size * 2}X}", end=", ") |
| 46 | if i % vals_per_line == (vals_per_line - 1): |
| 47 | print() |
| 48 | if args.size % vals_per_line != 0: |
| 49 | print() |
| 50 | |
| 51 | if __name__ == "__main__": |
| 52 | main() |
no test coverage detected