assets.py exports C code

This commit is contained in:
Luciano Ciccariello 2024-01-06 23:35:13 +00:00
parent c0840259c8
commit 91b3e50573
7 changed files with 112 additions and 57 deletions

View File

@ -439,8 +439,9 @@ $(BUILD_DIR)/$(ASSETS_DIR)/%.animset.json.o: $(ASSETS_DIR)/%.animset.json
./tools/splat_ext/animset.py gen-asm $< $(BUILD_DIR)/$(ASSETS_DIR)/$*.s
$(AS) $(AS_FLAGS) -o $(BUILD_DIR)/$(ASSETS_DIR)/$*.o $(BUILD_DIR)/$(ASSETS_DIR)/$*.s
$(BUILD_DIR)/$(ASSETS_DIR)/%.json.o: $(ASSETS_DIR)/%.json
./tools/splat_ext/assets.py $< $(BUILD_DIR)/$(ASSETS_DIR)/$*.s
$(AS) $(AS_FLAGS) -o $(BUILD_DIR)/$(ASSETS_DIR)/$*.o $(BUILD_DIR)/$(ASSETS_DIR)/$*.s
mkdir -p $(dir $@)
./tools/splat_ext/assets.py $< > $(BUILD_DIR)/$(ASSETS_DIR)/$*.c
$(CPP) $(CPP_FLAGS) -lang-c $(BUILD_DIR)/$(ASSETS_DIR)/$*.c | $(SOTNSTR) | $(ICONV) | $(CC) $(CC_FLAGS) $(PSXCC_FLAGS) | $(MASPSX) | $(AS) $(AS_FLAGS) -o $(BUILD_DIR)/$(ASSETS_DIR)/$*.o
$(BUILD_DIR)/$(ASSETS_DIR)/%.tilelayout.bin.o: $(ASSETS_DIR)/%.tilelayout.bin
$(LD) -r -b binary -o $(BUILD_DIR)/$(ASSETS_DIR)/$*.o $(ASSETS_DIR)/$*.tilelayout.bin
$(BUILD_DIR)/$(ASSETS_DIR)/%.bin.o: $(ASSETS_DIR)/%.bin

View File

@ -1,7 +1,7 @@
{
"struct": {
"name_addr": "str_ptr",
"desc_addr": "str_ptr",
"name": "sstr",
"desc": "str",
"attBonus": "s16",
"defBonus": "s16",
"strBonus": "s8",

View File

@ -28,6 +28,10 @@ import utils
def get_serializer(dataType: str):
match dataType:
case "str":
return None
case "sstr":
return None
case "str_ptr":
return utils.from_ptr_str
case "bool":
@ -50,6 +54,12 @@ def get_serializer(dataType: str):
def get_parser_and_size(dataType: str):
match dataType:
case "str":
return (None, 4)
case "sstr":
return (None, 4)
case "str_ptr":
return (utils.to_ptr_str, 4)
case "str_ptr":
return (utils.to_ptr_str, 4)
case "bool":
@ -70,15 +80,20 @@ def get_parser_and_size(dataType: str):
print(f"Failed to find parser for {dataType}")
def serialize_asset(content: str, asset_config: str) -> bytearray:
def serialize_asset(content: str, asset_config: str) -> str:
raw_json_data = json.loads(content)
config = json.loads(asset_config)
asset_type = raw_json_data["type"]
symbol_name = raw_json_data["symbol_name"]
asset_data = raw_json_data["asset_data"]
item_count = len(asset_data)
serialized_data = bytearray()
output = f"#include <game.h>\n\n// clang-format off\n"
output += f"{asset_type} {symbol_name}[] = {{\n"
for i in range(0, item_count):
item = asset_data[i]
row_values = []
for entry, entryType in config["struct"].items():
serializer = get_serializer(entryType)
json_value = item[entry]
@ -114,17 +129,20 @@ def serialize_asset(content: str, asset_config: str) -> bytearray:
bit_index += field_bitsize
packed_value = int(packed_bitstring, 2)
serialized_data += serializer(packed_value)
# Anything else can go straight to serializer
elif type(json_value) is str:
if entryType == "sstr":
row_values.append(f'_S("{json_value}")')
else:
row_values.append(f'"{json_value}"')
elif type(json_value) is int:
row_values.append(str(json_value))
elif type(json_value) is bool:
row_values.append("true" if json_value == True else "false")
else:
serialized_data += serializer(item[entry])
# Take serialized data (raw bytes) and turn into asm file
asm_output = ""
asm_output += ".section .data\n\n"
asm_output += f".global {symbol_name}\n\n"
asm_output += f"{symbol_name}:\n"
for databyte in serialized_data:
asm_output += f".byte {int(databyte)}\n"
return asm_output
raise Exception(f"unhandled type '{type(json_value)}")
output += " {" + ", ".join(row_values) + "},\n"
output += "};\n"
return output
class PSXSegAssets(N64Segment):
@ -143,7 +161,8 @@ class PSXSegAssets(N64Segment):
data = self.parse_asset(rom_bytes[self.rom_start : self.rom_end], rom_bytes)
json_output = {}
json_output["symbol_name"] = self.args[0]
json_output["type"] = self.args[0]
json_output["symbol_name"] = self.args[1]
json_output["asset_data"] = data
with open(path, "w") as f:
f.write(json.dumps(json_output, indent=4))
@ -181,8 +200,19 @@ class PSXSegAssets(N64Segment):
)
data_pointer = 0
for entry, entryType in config["struct"].items():
parser, dataSizeBytes = get_parser_and_size(entryType)
parsed_value = parser(item_data[data_pointer:])
if entryType == "str":
dataSizeBytes = 4
parsed_value = utils.sotn_menu_desc_to_str(
get_ptr_data(item_data[data_pointer:])
)
elif entryType == "sstr":
dataSizeBytes = 4
parsed_value = utils.sotn_menu_name_to_str(
get_ptr_data(item_data[data_pointer:])
)
else:
parser, dataSizeBytes = get_parser_and_size(entryType)
parsed_value = parser(item_data[data_pointer:])
if entry in config["fields"]:
field_def = config["fields"][entry]
if type(field_def) == list:
@ -230,13 +260,10 @@ class PSXSegAssets(N64Segment):
if __name__ == "__main__":
input_file_name = sys.argv[1]
output_file_name = sys.argv[2]
config_file_name = input_file_name.replace(".json", "_config.json")
config_file_name = config_file_name.replace("assets/dra", "tools/splat_ext")
with open(config_file_name, "r") as config_in:
config_json = config_in.read()
with open(input_file_name, "r") as f_in:
data = serialize_asset(f_in.read(), config_json)
with open(output_file_name, "w") as f_out:
f_out.write(data)
print(serialize_asset(f_in.read(), config_json))

View File

@ -1,6 +1,6 @@
{
"struct": {
"name_addr": "str_ptr",
"name_addr": "sstr",
"hitPoints": "s16",
"attack": "u16",
"attackElement": "u16",

View File

@ -1,34 +1,34 @@
{
"struct": {
"name_addr": "str_ptr",
"desc_addr": "str_ptr",
"attack": "s16",
"defense": "s16",
"element": "u16",
"itemCategory": "u8",
"weaponId": "u8",
"palette": "u8",
"unk11": "u8",
"playerAnim": "u8",
"unk13": "u8",
"unk14": "u8",
"lockDuration": "u8",
"chainLimit": "u8",
"unk17": "u8",
"specialMove": "u8",
"isConsumable": "bool",
"enemyInvincibilityFrames": "u8",
"unk1B": "u8",
"comboSub": "u32",
"comboMain": "u32",
"mpUsage": "s16",
"stunFrames": "s16",
"hitType": "s16",
"hitEffect": "s16",
"icon": "s16",
"iconPalette": "s16",
"criticalRate": "s16",
"unk32": "s16"
},
"fields": {}
}
{
"struct": {
"name": "sstr",
"desc": "str",
"attack": "s16",
"defense": "s16",
"element": "u16",
"itemCategory": "u8",
"weaponId": "u8",
"palette": "u8",
"unk11": "u8",
"playerAnim": "u8",
"unk13": "u8",
"unk14": "u8",
"lockDuration": "u8",
"chainLimit": "u8",
"unk17": "u8",
"specialMove": "u8",
"isConsumable": "bool",
"enemyInvincibilityFrames": "u8",
"unk1B": "u8",
"comboSub": "u32",
"comboMain": "u32",
"mpUsage": "u16",
"stunFrames": "u16",
"hitType": "u16",
"hitEffect": "u16",
"icon": "u16",
"iconPalette": "u16",
"criticalRate": "u16",
"unk32": "u16"
},
"fields": {}
}

View File

@ -0,0 +1,10 @@
{
"struct": {
"name": "str",
"desc": "str",
"unk08": "u16",
"unk0A": "u16",
"unk0C": "s32"
},
"fields": {}
}

View File

@ -0,0 +1,17 @@
{
"struct": {
"name": "str",
"combo": "str",
"desc": "str",
"mpUsage": "u8",
"nFramesInvincibility": "s8",
"stunFrames": "s16",
"hitboxState": "s16",
"hitEffect": "s16",
"entityRoomIndex": "s16",
"attackElement": "u16",
"attack": "s16",
"unk1A": "s16"
},
"fields": {}
}