48 lines
2.2 KiB
Python
48 lines
2.2 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
|
|
|
|
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)
|
|
for i, new in enumerate(new_data):
|
|
id = new.get('ID', i)
|
|
for k, v in new.items():
|
|
if k != 'ID' and v is not None: # Allow holes in the table for values we don't care about overwriting
|
|
existing_data[id][k] = v
|
|
self.build(table, existing_data, out_buffer)
|
|
|
|
|
|
def load_ff5_snes_struct_definitions() -> dict:
|
|
existing_structs = get_base_structarraytypes()
|
|
parse_struct_definitions_from_tsv_filename('ChocolateBirdData/structs_SNES_stubs.tsv', existing_structs)
|
|
parse_struct_definitions_from_tsv_filename('ChocolateBirdData/5/structs/SNES_stubs.tsv', existing_structs)
|
|
parse_struct_definitions_from_tsv_filename('ChocolateBirdData/5/structs/SNES.tsv', existing_structs)
|
|
parse_struct_definitions_from_tsv_filename('ChocolateBirdData/5/structs/SNES_save.tsv', existing_structs)
|
|
return existing_structs
|
|
|
|
|
|
class FF5SNESHandler(ROMHandler):
|
|
offset_key: str = 'SNES'
|
|
struct_definitions: dict = load_ff5_snes_struct_definitions()
|
|
addresses: dict = {entry['Label']: entry for entry in load_tsv('ChocolateBirdData/5/addresses_SNES_PSX.tsv')}
|