mirror of
https://github.com/pmret/papermario.git
synced 2024-11-08 20:12:30 +01:00
3315d6010f
* all non-world rodata migrated * data disasm * kinda working * updated yaml * bloop * linker header * configure 2.0 * bin * mass rename to remove code_ * pause rename * battle partner stuff * whew * more renames * more renames * more renaming * it builds! * updates * remove main prefix * one more thing * crc, yay0 * .data, .rodata, .bss * img * dead_atan2 * it buildsgit add -A * split battle/partner/6FAD10 * rm &s on sleepy_sheep syms * sha1sum ninja rule description * OK but commented out PaperMarioMapFS and PaperMarioNpcSprites * uncomment * fix mapfs * match func_8003CFB4 * . * clean up and name npc_iter_no_op * npc.c * enable cc warnings * name npc_find_near * use singular options.asset_path * smores * cc_dsl only when needed * kinda fix configure for splat refactor2 * ok! * new msg format * remove old msg format docs * slight bug fixes, splat adjustment * git subrepo pull (merge) --force tools/splat subrepo: subdir: "tools/splat" merged: "cfc140bb76" upstream: origin: "https://github.com/ethteck/splat.git" branch: "master" commit: "cfc140bb76" git-subrepo: version: "0.4.3" origin: "https://github.com/ingydotnet/git-subrepo" commit: "2f68596" * git subrepo pull (merge) --force tools/splat subrepo: subdir: "tools/splat" merged: "85349befcd" upstream: origin: "https://github.com/ethteck/splat.git" branch: "master" commit: "85349befcd" git-subrepo: version: "0.4.3" origin: "https://github.com/ingydotnet/git-subrepo" commit: "2f68596" * Update symbol addrs * git subrepo pull tools/splat subrepo: subdir: "tools/splat" merged: "a44631e194" upstream: origin: "https://github.com/ethteck/splat.git" branch: "master" commit: "a44631e194" git-subrepo: version: "0.4.3" origin: "https://github.com/ingydotnet/git-subrepo" commit: "2f68596" Co-authored-by: Alex Bates <hi@imalex.xyz>
121 lines
3.9 KiB
Python
Executable File
121 lines
3.9 KiB
Python
Executable File
#! /usr/bin/python3
|
|
|
|
from sys import argv
|
|
from collections import OrderedDict
|
|
import re
|
|
import msgpack
|
|
import os
|
|
|
|
class Message:
|
|
def __init__(self, d: dict, header_file_index: int):
|
|
self.section = d.get("section")
|
|
self.index = d.get("index")
|
|
self.name = d.get("name")
|
|
self.bytes = d["bytes"]
|
|
self.header_file_index = header_file_index
|
|
|
|
if __name__ == "__main__":
|
|
if len(argv) < 3:
|
|
print("usage: combine.py [out.bin] [out.h] [compiled...]")
|
|
exit(1)
|
|
|
|
_, outfile, header_file, *infiles = argv
|
|
|
|
messages = []
|
|
#header_files = []
|
|
|
|
for i, infile in enumerate(infiles):
|
|
# if infile == "--headers":
|
|
# header_files = infiles[i+1:]
|
|
# break
|
|
|
|
with open(infile, "rb") as f:
|
|
messages.extend(Message(msg, i) for msg in msgpack.unpack(f))
|
|
|
|
with open(outfile, "wb") as f:
|
|
# sectioned+indexed, followed by just sectioned, followed by just indexed, followed by named (unsectioned & unindexed)
|
|
#messages.sort(key=lambda msg: bool(msg.section)<<2 + bool(msg.index))
|
|
|
|
names = set()
|
|
|
|
sections = []
|
|
#messages_by_file = {}
|
|
|
|
for message in messages:
|
|
if message.section is None:
|
|
# allocate a section
|
|
for section_idx, section in enumerate(sections):
|
|
if len(section) < 0xFFF:
|
|
break
|
|
message.section = section_idx
|
|
else:
|
|
section_idx = message.section
|
|
while len(sections) <= section_idx:
|
|
sections.append({})
|
|
section = sections[section_idx]
|
|
|
|
if message.index is None:
|
|
message.index = len(section)
|
|
|
|
# if message.name:
|
|
# if message.name in names:
|
|
# print(f"error: multiple messages with name '{message.name}'")
|
|
# exit(1)
|
|
# else:
|
|
# names.add(message.name)
|
|
|
|
# if message.header_file_index in messages_by_file:
|
|
# messages_by_file[message.header_file_index].add(message)
|
|
# else:
|
|
# messages_by_file[message.header_file_index] = set([message])
|
|
|
|
if message.index in section:
|
|
print(f"warning: multiple messages allocated to id {section_idx:02X}:{message.index:03X}")
|
|
|
|
if section[message.index].name and message.name:
|
|
print(f"warning: message '{section[message.index].name}' and '{message.name}' conflict")
|
|
|
|
section[message.index] = message
|
|
|
|
f.seek((len(sections) + 1) * 4) # skip past table of contents
|
|
|
|
section_offsets = []
|
|
for section in sections:
|
|
# convert dict into sorted list
|
|
section = [msg for idx, msg in sorted(section.items(), key=lambda ele: ele[0])]
|
|
|
|
message_offsets = []
|
|
for message in section:
|
|
message_offsets.append(f.tell())
|
|
f.write(message.bytes)
|
|
|
|
section_offset = f.tell()
|
|
section_offsets.append(section_offset)
|
|
for offset in message_offsets:
|
|
f.write(offset.to_bytes(4, byteorder="big"))
|
|
f.write(section_offset.to_bytes(4, byteorder="big"))
|
|
|
|
# padding
|
|
while f.tell() % 0x10 != 0:
|
|
f.write(b'\0\0\0\0')
|
|
|
|
f.seek(0)
|
|
for offset in section_offsets:
|
|
f.write(offset.to_bytes(4, byteorder="big"))
|
|
f.write(b'\0\0\0\0')
|
|
|
|
with open(header_file, "w") as f:
|
|
f.write(
|
|
f"#ifndef _MESSAGE_IDS_H_\n"
|
|
f"#define _MESSAGE_IDS_H_\n"
|
|
"\n"
|
|
'#include "messages.h"\n'
|
|
"\n"
|
|
)
|
|
|
|
for message in messages:
|
|
if message.name:
|
|
f.write(f"#define MSG_{message.name} MESSAGE_ID(0x{message.section:02X}, 0x{message.index:03X})\n")
|
|
|
|
f.write("\n#endif\n")
|