diff options
| author | Tharo <17233964+Thar0@users.noreply.github.com> | 2021-11-16 23:04:31 +0000 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2021-11-16 18:04:31 -0500 |
| commit | 9ca6bfdac375b2008fcd2d19173c4017279eccde (patch) | |
| tree | 232a8cacb955d723fc7d0848686f4a867ee49298 /tools | |
| parent | a3b4dcf388f7b424aedce4e9e8b130fa5c82a5d9 (diff) | |
Create macros for and decompile elf_message scripts (#999)
* elf_message
* Review suggestions
Diffstat (limited to 'tools')
| -rw-r--r-- | tools/disasm_elf_msg.py | 256 |
1 files changed, 256 insertions, 0 deletions
diff --git a/tools/disasm_elf_msg.py b/tools/disasm_elf_msg.py new file mode 100644 index 000000000..4d58c9d27 --- /dev/null +++ b/tools/disasm_elf_msg.py @@ -0,0 +1,256 @@ +#!/usr/bin/env python3 + +import struct, sys + +item_ids = { + 0x00 : "ITEM_STICK", + 0x01 : "ITEM_NUT", + 0x02 : "ITEM_BOMB", + 0x03 : "ITEM_BOW", + 0x04 : "ITEM_ARROW_FIRE", + 0x05 : "ITEM_DINS_FIRE", + 0x06 : "ITEM_SLINGSHOT", + 0x07 : "ITEM_OCARINA_FAIRY", + 0x08 : "ITEM_OCARINA_TIME", + 0x09 : "ITEM_BOMBCHU", + 0x0A : "ITEM_HOOKSHOT", + 0x0B : "ITEM_LONGSHOT", + 0x0C : "ITEM_ARROW_ICE", + 0x0D : "ITEM_FARORES_WIND", + 0x0E : "ITEM_BOOMERANG", + 0x0F : "ITEM_LENS", + 0x10 : "ITEM_BEAN", + 0x11 : "ITEM_HAMMER", + 0x12 : "ITEM_ARROW_LIGHT", + 0x13 : "ITEM_NAYRUS_LOVE", + 0x14 : "ITEM_BOTTLE", + 0x15 : "ITEM_POTION_RED", + 0x16 : "ITEM_POTION_GREEN", + 0x17 : "ITEM_POTION_BLUE", + 0x18 : "ITEM_FAIRY", + 0x19 : "ITEM_FISH", + 0x1A : "ITEM_MILK_BOTTLE", + 0x1B : "ITEM_LETTER_RUTO", + 0x1C : "ITEM_BLUE_FIRE", + 0x1D : "ITEM_BUG", + 0x1E : "ITEM_BIG_POE", + 0x1F : "ITEM_MILK_HALF", + 0x20 : "ITEM_POE", + 0x21 : "ITEM_WEIRD_EGG", + 0x22 : "ITEM_CHICKEN", + 0x23 : "ITEM_LETTER_ZELDA", + 0x24 : "ITEM_MASK_KEATON", + 0x25 : "ITEM_MASK_SKULL", + 0x26 : "ITEM_MASK_SPOOKY", + 0x27 : "ITEM_MASK_BUNNY", + 0x28 : "ITEM_MASK_GORON", + 0x29 : "ITEM_MASK_ZORA", + 0x2A : "ITEM_MASK_GERUDO", + 0x2B : "ITEM_MASK_TRUTH", + 0x2C : "ITEM_SOLD_OUT", + 0x2D : "ITEM_POCKET_EGG", + 0x2E : "ITEM_POCKET_CUCCO", + 0x2F : "ITEM_COJIRO", + 0x30 : "ITEM_ODD_MUSHROOM", + 0x31 : "ITEM_ODD_POTION", + 0x32 : "ITEM_SAW", + 0x33 : "ITEM_SWORD_BROKEN", + 0x34 : "ITEM_PRESCRIPTION", + 0x35 : "ITEM_FROG", + 0x36 : "ITEM_EYEDROPS", + 0x37 : "ITEM_CLAIM_CHECK", + 0x38 : "ITEM_BOW_ARROW_FIRE", + 0x39 : "ITEM_BOW_ARROW_ICE", + 0x3A : "ITEM_BOW_ARROW_LIGHT", + 0x3B : "ITEM_SWORD_KOKIRI", + 0x3C : "ITEM_SWORD_MASTER", + 0x3D : "ITEM_SWORD_BGS", + 0x3E : "ITEM_SHIELD_DEKU", + 0x3F : "ITEM_SHIELD_HYLIAN", + 0x40 : "ITEM_SHIELD_MIRROR", + 0x41 : "ITEM_TUNIC_KOKIRI", + 0x42 : "ITEM_TUNIC_GORON", + 0x43 : "ITEM_TUNIC_ZORA", + 0x44 : "ITEM_BOOTS_KOKIRI", + 0x45 : "ITEM_BOOTS_IRON", + 0x46 : "ITEM_BOOTS_HOVER", + 0x47 : "ITEM_BULLET_BAG_30", + 0x48 : "ITEM_BULLET_BAG_40", + 0x49 : "ITEM_BULLET_BAG_50", + 0x4A : "ITEM_QUIVER_30", + 0x4B : "ITEM_QUIVER_40", + 0x4C : "ITEM_QUIVER_50", + 0x4D : "ITEM_BOMB_BAG_20", + 0x4E : "ITEM_BOMB_BAG_30", + 0x4F : "ITEM_BOMB_BAG_40", + 0x50 : "ITEM_BRACELET", + 0x51 : "ITEM_GAUNTLETS_SILVER", + 0x52 : "ITEM_GAUNTLETS_GOLD", + 0x53 : "ITEM_SCALE_SILVER", + 0x54 : "ITEM_SCALE_GOLDEN", + 0x55 : "ITEM_SWORD_KNIFE", + 0x56 : "ITEM_WALLET_ADULT", + 0x57 : "ITEM_WALLET_GIANT", + 0x58 : "ITEM_SEEDS", + 0x59 : "ITEM_FISHING_POLE", + 0x5A : "ITEM_SONG_MINUET", + 0x5B : "ITEM_SONG_BOLERO", + 0x5C : "ITEM_SONG_SERENADE", + 0x5D : "ITEM_SONG_REQUIEM", + 0x5E : "ITEM_SONG_NOCTURNE", + 0x5F : "ITEM_SONG_PRELUDE", + 0x60 : "ITEM_SONG_LULLABY", + 0x61 : "ITEM_SONG_EPONA", + 0x62 : "ITEM_SONG_SARIA", + 0x63 : "ITEM_SONG_SUN", + 0x64 : "ITEM_SONG_TIME", + 0x65 : "ITEM_SONG_STORMS", + 0x66 : "ITEM_MEDALLION_FOREST", + 0x67 : "ITEM_MEDALLION_FIRE", + 0x68 : "ITEM_MEDALLION_WATER", + 0x69 : "ITEM_MEDALLION_SPIRIT", + 0x6A : "ITEM_MEDALLION_SHADOW", + 0x6B : "ITEM_MEDALLION_LIGHT", + 0x6C : "ITEM_KOKIRI_EMERALD", + 0x6D : "ITEM_GORON_RUBY", + 0x6E : "ITEM_ZORA_SAPPHIRE", + 0x6F : "ITEM_STONE_OF_AGONY", + 0x70 : "ITEM_GERUDO_CARD", + 0x71 : "ITEM_SKULL_TOKEN", + 0x72 : "ITEM_HEART_CONTAINER", + 0x73 : "ITEM_HEART_PIECE", + 0x74 : "ITEM_KEY_BOSS", + 0x75 : "ITEM_COMPASS", + 0x76 : "ITEM_DUNGEON_MAP", + 0x77 : "ITEM_KEY_SMALL", + 0x78 : "ITEM_MAGIC_SMALL", + 0x79 : "ITEM_MAGIC_LARGE", + 0x7A : "ITEM_HEART_PIECE_2", + 0x7B : "ITEM_INVALID_1", + 0x7C : "ITEM_INVALID_2", + 0x7D : "ITEM_INVALID_3", + 0x7E : "ITEM_INVALID_4", + 0x7F : "ITEM_INVALID_5", + 0x80 : "ITEM_INVALID_6", + 0x81 : "ITEM_INVALID_7", + 0x82 : "ITEM_MILK", + 0x83 : "ITEM_HEART", + 0x84 : "ITEM_RUPEE_GREEN", + 0x85 : "ITEM_RUPEE_BLUE", + 0x86 : "ITEM_RUPEE_RED", + 0x87 : "ITEM_RUPEE_PURPLE", + 0x88 : "ITEM_RUPEE_GOLD", + 0x89 : "ITEM_INVALID_8", + 0x8A : "ITEM_STICKS_5", + 0x8B : "ITEM_STICKS_10", + 0x8C : "ITEM_NUTS_5", + 0x8D : "ITEM_NUTS_10", + 0x8E : "ITEM_BOMBS_5", + 0x8F : "ITEM_BOMBS_10", + 0x90 : "ITEM_BOMBS_20", + 0x91 : "ITEM_BOMBS_30", + 0x92 : "ITEM_ARROWS_SMALL", + 0x93 : "ITEM_ARROWS_MEDIUM", + 0x94 : "ITEM_ARROWS_LARGE", + 0x95 : "ITEM_SEEDS_30", + 0x96 : "ITEM_BOMBCHUS_5", + 0x97 : "ITEM_BOMBCHUS_20", + 0x98 : "ITEM_STICK_UPGRADE_20", + 0x99 : "ITEM_STICK_UPGRADE_30", + 0x9A : "ITEM_NUT_UPGRADE_30", + 0x9B : "ITEM_NUT_UPGRADE_40", + 0xFC : "ITEM_LAST_USED", + 0xFE : "ITEM_NONE_FE", + 0xFF : "ITEM_NONE", +} + +def disas_elfmsgs(start): + baserom = None + with open("baserom.z64", "rb") as infile: + baserom = bytearray(infile.read()) + + branches = [] + pos = start + + while (True): + print(f"/* {pos - start:04X} {((pos - start) // 4):3} */ ", end="") + + b0, b1, b2, b3 = struct.unpack(">BBBB", baserom[pos:pos+4]) + + elf_message_types = { + 0x00: "CHECK", + 0x20: "UNK_1", + 0x40: "UNK_2", + 0x60: "SKIP", + 0xE0: "END", + } + + cont = True + branch_to = None + + # Get Type + + elf_message_type = b0 & 0xE0 + ARG_0 = elf_message_types[elf_message_type] + + if elf_message_type in [0, 0x20, 0x40, 0xE0]: + if elf_message_type == 0xE0: + cont = False + ARG_1 = f"0x{(b2 & 0xFF):04X}" + elif elf_message_type == 0x60: + branch_to = 4 * (b2 & 0xFF) + ARG_1 = (b2 & 0xFF) + else: + assert False , "Encountered unknown type" + + ARG_2 = f"{bool(b0 & 1)}".lower() + + # Get condition + condition_type = b0 & 0x1E + + if condition_type == 0: + if elf_message_type == 0xE0 and b1 == 0 and not (b0 & 1): + print(f"ELF_MSG_END({ARG_1}),") + else: + print(f"ELF_MSG_FLAG({ARG_0}, {ARG_1}, {ARG_2}, 0x{b1:02X}), /* eventChkInf[{(b1 >> 4) & 0xF}] & 0x{1 << (b1 & 0xF):X} */") + assert b3 == 0 + elif condition_type == 2: + print(f"ELF_MSG_DUNGEON_ITEM({ARG_0}, {ARG_1}, {ARG_2}, {item_ids[b1]}),") + assert b3 == 0 + elif condition_type == 4: + print(f"ELF_MSG_ITEM({ARG_0}, {ARG_1}, {ARG_2}, {item_ids[b1]}, {item_ids[b3]}),") + elif condition_type == 6: + condition_other_type = b1 & 0xF0 + + if condition_other_type == 0: + print(f"ELF_MSG_STRENGTH_UPG({ARG_0}, {ARG_1}, {ARG_2}, {b1 & 0xF}),") + assert b3 == 0 + elif condition_other_type == 0x10: + print(f"ELF_MSG_BOOTS({ARG_0}, {ARG_1}, {ARG_2}, {item_ids[b3]}),") + assert (b1 & 0xF) == 0 + elif condition_other_type == 0x20: + print(f"ELF_MSG_SONG({ARG_0}, {ARG_1}, {ARG_2}, {item_ids[b3]}),") + assert (b1 & 0xF) == 0 + elif condition_other_type == 0x30: + print(f"ELF_MSG_MEDALLION({ARG_0}, {ARG_1}, {ARG_2}, {item_ids[b3]}),") + assert (b1 & 0xF) == 0 + elif condition_other_type == 0x40: + print(f"ELF_MSG_MAGIC({ARG_0}, {ARG_1}, {ARG_2}),") + assert (b1 & 0xF) == 0 + assert b3 == 0 + else: + assert False , "Encountered unknown condition (other) type" + else: + assert False , "Encountered unknown condition type" + + # Control flow + + if branch_to is not None: + branches.append(branch_to) + pos += 4 + if not cont: + print("") + if not cont and all([dst < pos - start for dst in branches]): + break + +disas_elfmsgs(int(sys.argv[1],16)) |
