TabComp/includes/rom_serde.py

49 lines
2.3 KiB
Python

from ChocolateBirdData.reference_implementation import get_base_structarraytypes, parse_struct_definitions_from_tsv_filename, get_structarraytype, LeftoverBits, ReadBuffer, WriteBuffer
from includes.helpers import load_tsv, deep_update
class ROMHandler:
offset_key: str
struct_definitions: dict
def extract(self, table: str, in_buffer) -> list[dict]:
# Deserialize a table
leftover_bits = LeftoverBits()
entry = self.addresses[table] # Remember to try/catch
offset = entry[self.offset_key]
buf = ReadBuffer(in_buffer, offset)
return get_structarraytype(entry['format'], self.struct_definitions).get_value(buf, leftover_bits)
def build(self, table: str, new_data: list[dict], out_buffer):
# Serialize complete data. This WILL fail if the input data is incomplete.
leftover_bits = LeftoverBits()
entry = self.addresses[table] # Remember to try/catch
offset = entry[self.offset_key]
buf = WriteBuffer(out_buffer, offset)
get_structarraytype(entry['format'], self.struct_definitions).put_value(buf, new_data, leftover_bits)
def build_partial(self, table: str, new_data: list[dict], in_buffer, out_buffer):
# Safely merge partial data over the existing data, then serialize it.
existing_data = self.extract(table, in_buffer)
deep_update(existing_data, new_data)
self.build(table, existing_data, out_buffer)
def load_struct_definitions(*filenames) -> dict:
existing_structs = get_base_structarraytypes()
for filename in filenames:
parse_struct_definitions_from_tsv_filename(filename, existing_structs)
return existing_structs
class FF5SNESHandler(ROMHandler):
offset_key: str = 'SNES'
struct_definitions: dict = load_struct_definitions('ChocolateBirdData/structs_SNES_stubs.tsv', 'ChocolateBirdData/5/structs/SNES_stubs.tsv', 'ChocolateBirdData/5/structs/SNES.tsv', 'ChocolateBirdData/5/structs/SNES_save.tsv')
addresses: dict = {entry['Label']: entry for entry in load_tsv('ChocolateBirdData/5/addresses_SNES_PSX.tsv')}
class FF5GBAHandler(ROMHandler):
def __init__(self, region: str) -> None:
self.offset_key = region
struct_definitions: dict = load_struct_definitions('ChocolateBirdData/structs_SNES_stubs.tsv', 'ChocolateBirdData/5/structs/SNES_stubs.tsv', 'ChocolateBirdData/5/structs/GBA.tsv', 'ChocolateBirdData/5/structs/SNES_save.tsv')
addresses: dict = {entry['Label']: entry for entry in load_tsv('ChocolateBirdData/5/addresses_GBA.tsv')}