mirror of
https://github.com/pret/pokemon-reverse-engineering-tools.git
synced 2026-03-21 17:24:42 -05:00
Rewrite redsfxdisasm.py
This commit is contained in:
parent
37b9310dcb
commit
92496615f0
|
|
@ -92,7 +92,7 @@ music_commands = {
|
|||
0xea: { "name": "vibrato", "params": [ "byte", "nibbles" ] },
|
||||
0xeb: { "name": "pitch_slide", "params": [ "byte_off_by_one", "nibbles_octave_note" ] },
|
||||
0xec: { "name": "duty_cycle", "params": [ "byte" ] },
|
||||
0xed: { "name": "tempo", "params": [ "word" ] },
|
||||
0xed: { "name": "tempo", "params": [ "word_big_endian" ] },
|
||||
0xee: { "name": "stereo_panning", "params": [ "nibbles_binary" ] },
|
||||
0xf0: { "name": "volume", "params": [ "nibbles" ] },
|
||||
0xf8: { "name": "execute_music", "params": [] },
|
||||
|
|
@ -115,7 +115,7 @@ param_lengths = {
|
|||
"nibbles_octave_note": 1,
|
||||
"byte": 1,
|
||||
"byte_off_by_one": 1,
|
||||
"word": 2,
|
||||
"word_big_endian": 2,
|
||||
"label": 2,
|
||||
}
|
||||
|
||||
|
|
@ -267,14 +267,14 @@ def dump_channel(start_address, end_address, song_name, channel, labels):
|
|||
elif param_type == "nibbles_binary":
|
||||
output += " %{:b}, %{:b}".format(param >> 4, param & 0b1111)
|
||||
elif param_type == "nibbles_unsigned_signed":
|
||||
output += " {}, {}".format(param >> 4, (param & 0b0111) * (-1 if param & 0b1000 else 1))
|
||||
output += " {}, {}".format(param >> 4, param & 0b1111 if param & 0b1111 <= 8 else (param & 0b0111) * -1)
|
||||
elif param_type == "nibbles_octave_note":
|
||||
output += " {}, {}".format(8 - (param >> 4), music_notes[param & 0b1111])
|
||||
elif param_type == "byte":
|
||||
output += " {}".format(param)
|
||||
elif param_type == "byte_off_by_one":
|
||||
output += " {}".format(param + 1)
|
||||
elif param_type == "word":
|
||||
elif param_type == "word_big_endian":
|
||||
output += " {}".format(param * 0x100 + rom[address + 1])
|
||||
elif param_type == "label":
|
||||
param = get_pointer(address)
|
||||
|
|
|
|||
|
|
@ -1,27 +1,125 @@
|
|||
import configuration
|
||||
config = configuration.Config()
|
||||
rom = bytearray(open(config.rom_path, "r").read())
|
||||
#!/usr/bin/env python
|
||||
|
||||
sfx_names = [
|
||||
"Snare1_2",
|
||||
"Snare2_2",
|
||||
"Snare3_2",
|
||||
"Snare4_2",
|
||||
"Snare5_2",
|
||||
"Triangle1_2",
|
||||
"Triangle2_2",
|
||||
"Snare6_2",
|
||||
"Snare7_2",
|
||||
"Snare8_2",
|
||||
"Snare9_2",
|
||||
"Cymbal1_2",
|
||||
"Cymbal2_2",
|
||||
"Cymbal3_2",
|
||||
"Muted_Snare1_2",
|
||||
"Triangle3_2",
|
||||
"Muted_Snare2_2",
|
||||
"Muted_Snare3_2",
|
||||
"Muted_Snare4_2",
|
||||
rom = bytearray(open("baserom.gbc", "rb").read())
|
||||
|
||||
sfx_names_1 = [
|
||||
"Noise_Instrument01_1",
|
||||
"Noise_Instrument02_1",
|
||||
"Noise_Instrument03_1",
|
||||
"Noise_Instrument04_1",
|
||||
"Noise_Instrument05_1",
|
||||
"Noise_Instrument06_1",
|
||||
"Noise_Instrument07_1",
|
||||
"Noise_Instrument08_1",
|
||||
"Noise_Instrument09_1",
|
||||
"Noise_Instrument10_1",
|
||||
"Noise_Instrument11_1",
|
||||
"Noise_Instrument12_1",
|
||||
"Noise_Instrument13_1",
|
||||
"Noise_Instrument14_1",
|
||||
"Noise_Instrument15_1",
|
||||
"Noise_Instrument16_1",
|
||||
"Noise_Instrument17_1",
|
||||
"Noise_Instrument18_1",
|
||||
"Noise_Instrument19_1",
|
||||
"Cry00_1",
|
||||
"Cry01_1",
|
||||
"Cry02_1",
|
||||
"Cry03_1",
|
||||
"Cry04_1",
|
||||
"Cry05_1",
|
||||
"Cry06_1",
|
||||
"Cry07_1",
|
||||
"Cry08_1",
|
||||
"Cry09_1",
|
||||
"Cry0A_1",
|
||||
"Cry0B_1",
|
||||
"Cry0C_1",
|
||||
"Cry0D_1",
|
||||
"Cry0E_1",
|
||||
"Cry0F_1",
|
||||
"Cry10_1",
|
||||
"Cry11_1",
|
||||
"Cry12_1",
|
||||
"Cry13_1",
|
||||
"Cry14_1",
|
||||
"Cry15_1",
|
||||
"Cry16_1",
|
||||
"Cry17_1",
|
||||
"Cry18_1",
|
||||
"Cry19_1",
|
||||
"Cry1A_1",
|
||||
"Cry1B_1",
|
||||
"Cry1C_1",
|
||||
"Cry1D_1",
|
||||
"Cry1E_1",
|
||||
"Cry1F_1",
|
||||
"Cry20_1",
|
||||
"Cry21_1",
|
||||
"Cry22_1",
|
||||
"Cry23_1",
|
||||
"Cry24_1",
|
||||
"Cry25_1",
|
||||
"Get_Item1_1",
|
||||
"Get_Item2_1",
|
||||
"Tink_1",
|
||||
"Heal_HP_1",
|
||||
"Heal_Ailment_1",
|
||||
"Start_Menu_1",
|
||||
"Press_AB_1",
|
||||
"Pokedex_Rating_1",
|
||||
"Get_Key_Item_1",
|
||||
"Poisoned_1",
|
||||
"Trade_Machine_1",
|
||||
"Turn_On_PC_1",
|
||||
"Turn_Off_PC_1",
|
||||
"Enter_PC_1",
|
||||
"Shrink_1",
|
||||
"Switch_1",
|
||||
"Healing_Machine_1",
|
||||
"Teleport_Exit1_1",
|
||||
"Teleport_Enter1_1",
|
||||
"Teleport_Exit2_1",
|
||||
"Ledge_1",
|
||||
"Teleport_Enter2_1",
|
||||
"Fly_1",
|
||||
"Denied_1",
|
||||
"Arrow_Tiles_1",
|
||||
"Push_Boulder_1",
|
||||
"SS_Anne_Horn_1",
|
||||
"Withdraw_Deposit_1",
|
||||
"Cut_1",
|
||||
"Go_Inside_1",
|
||||
"Swap_1",
|
||||
"59_1",
|
||||
"Purchase_1",
|
||||
"Collision_1",
|
||||
"Go_Outside_1",
|
||||
"Save_1",
|
||||
"Pokeflute",
|
||||
"Safari_Zone_PA",
|
||||
]
|
||||
|
||||
sfx_names_2 = [
|
||||
"Noise_Instrument01_2",
|
||||
"Noise_Instrument02_2",
|
||||
"Noise_Instrument03_2",
|
||||
"Noise_Instrument04_2",
|
||||
"Noise_Instrument05_2",
|
||||
"Noise_Instrument06_2",
|
||||
"Noise_Instrument07_2",
|
||||
"Noise_Instrument08_2",
|
||||
"Noise_Instrument09_2",
|
||||
"Noise_Instrument10_2",
|
||||
"Noise_Instrument11_2",
|
||||
"Noise_Instrument12_2",
|
||||
"Noise_Instrument13_2",
|
||||
"Noise_Instrument14_2",
|
||||
"Noise_Instrument15_2",
|
||||
"Noise_Instrument16_2",
|
||||
"Noise_Instrument17_2",
|
||||
"Noise_Instrument18_2",
|
||||
"Noise_Instrument19_2",
|
||||
"Cry00_2",
|
||||
"Cry01_2",
|
||||
"Cry02_2",
|
||||
|
|
@ -122,120 +220,28 @@ sfx_names = [
|
|||
"Battle_35",
|
||||
"Battle_36",
|
||||
"Silph_Scope",
|
||||
"Snare1_1",
|
||||
"Snare2_1",
|
||||
"Snare3_1",
|
||||
"Snare4_1",
|
||||
"Snare5_1",
|
||||
"Triangle1_1",
|
||||
"Triangle2_1",
|
||||
"Snare6_1",
|
||||
"Snare7_1",
|
||||
"Snare8_1",
|
||||
"Snare9_1",
|
||||
"Cymbal1_1",
|
||||
"Cymbal2_1",
|
||||
"Cymbal3_1",
|
||||
"Muted_Snare1_1",
|
||||
"Triangle3_1",
|
||||
"Muted_Snare2_1",
|
||||
"Muted_Snare3_1",
|
||||
"Muted_Snare4_1",
|
||||
"Cry00_1",
|
||||
"Cry01_1",
|
||||
"Cry02_1",
|
||||
"Cry03_1",
|
||||
"Cry04_1",
|
||||
"Cry05_1",
|
||||
"Cry06_1",
|
||||
"Cry07_1",
|
||||
"Cry08_1",
|
||||
"Cry09_1",
|
||||
"Cry0A_1",
|
||||
"Cry0B_1",
|
||||
"Cry0C_1",
|
||||
"Cry0D_1",
|
||||
"Cry0E_1",
|
||||
"Cry0F_1",
|
||||
"Cry10_1",
|
||||
"Cry11_1",
|
||||
"Cry12_1",
|
||||
"Cry13_1",
|
||||
"Cry14_1",
|
||||
"Cry15_1",
|
||||
"Cry16_1",
|
||||
"Cry17_1",
|
||||
"Cry18_1",
|
||||
"Cry19_1",
|
||||
"Cry1A_1",
|
||||
"Cry1B_1",
|
||||
"Cry1C_1",
|
||||
"Cry1D_1",
|
||||
"Cry1E_1",
|
||||
"Cry1F_1",
|
||||
"Cry20_1",
|
||||
"Cry21_1",
|
||||
"Cry22_1",
|
||||
"Cry23_1",
|
||||
"Cry24_1",
|
||||
"Cry25_1",
|
||||
"Get_Item1_1",
|
||||
"Get_Item2_1",
|
||||
"Tink_1",
|
||||
"Heal_HP_1",
|
||||
"Heal_Ailment_1",
|
||||
"Start_Menu_1",
|
||||
"Press_AB_1",
|
||||
"Pokedex_Rating_1",
|
||||
"Get_Key_Item_1",
|
||||
"Poisoned_1",
|
||||
"Trade_Machine_1",
|
||||
"Turn_On_PC_1",
|
||||
"Turn_Off_PC_1",
|
||||
"Enter_PC_1",
|
||||
"Shrink_1",
|
||||
"Switch_1",
|
||||
"Healing_Machine_1",
|
||||
"Teleport_Exit1_1",
|
||||
"Teleport_Enter1_1",
|
||||
"Teleport_Exit2_1",
|
||||
"Ledge_1",
|
||||
"Teleport_Enter2_1",
|
||||
"Fly_1",
|
||||
"Denied_1",
|
||||
"Arrow_Tiles_1",
|
||||
"Push_Boulder_1",
|
||||
"SS_Anne_Horn_1",
|
||||
"Withdraw_Deposit_1",
|
||||
"Cut_1",
|
||||
"Go_Inside_1",
|
||||
"Swap_1",
|
||||
"59_1",
|
||||
"Purchase_1",
|
||||
"Collision_1",
|
||||
"Go_Outside_1",
|
||||
"Save_1",
|
||||
"Pokeflute",
|
||||
"Safari_Zone_PA",
|
||||
"Snare1_3",
|
||||
"Snare2_3",
|
||||
"Snare3_3",
|
||||
"Snare4_3",
|
||||
"Snare5_3",
|
||||
"Triangle1_3",
|
||||
"Triangle2_3",
|
||||
"Snare6_3",
|
||||
"Snare7_3",
|
||||
"Snare8_3",
|
||||
"Snare9_3",
|
||||
"Cymbal1_3",
|
||||
"Cymbal2_3",
|
||||
"Cymbal3_3",
|
||||
"Muted_Snare1_3",
|
||||
"Triangle3_3",
|
||||
"Muted_Snare2_3",
|
||||
"Muted_Snare3_3",
|
||||
"Muted_Snare4_3",
|
||||
]
|
||||
|
||||
sfx_names_3 = [
|
||||
"Noise_Instrument01_3",
|
||||
"Noise_Instrument02_3",
|
||||
"Noise_Instrument03_3",
|
||||
"Noise_Instrument04_3",
|
||||
"Noise_Instrument05_3",
|
||||
"Noise_Instrument06_3",
|
||||
"Noise_Instrument07_3",
|
||||
"Noise_Instrument08_3",
|
||||
"Noise_Instrument09_3",
|
||||
"Noise_Instrument10_3",
|
||||
"Noise_Instrument11_3",
|
||||
"Noise_Instrument12_3",
|
||||
"Noise_Instrument13_3",
|
||||
"Noise_Instrument14_3",
|
||||
"Noise_Instrument15_3",
|
||||
"Noise_Instrument16_3",
|
||||
"Noise_Instrument17_3",
|
||||
"Noise_Instrument18_3",
|
||||
"Noise_Instrument19_3",
|
||||
"Cry00_3",
|
||||
"Cry01_3",
|
||||
"Cry02_3",
|
||||
|
|
@ -320,35 +326,58 @@ sfx_names = [
|
|||
"Slots_Reward",
|
||||
"Slots_New_Spin",
|
||||
"Shooting_Star",
|
||||
]
|
||||
]
|
||||
|
||||
banks = {
|
||||
0x02: 0x60,
|
||||
0x08: 0x78,
|
||||
0x1f: 0x68,
|
||||
}
|
||||
sfx_groups = {
|
||||
0x02: sfx_names_1,
|
||||
0x08: sfx_names_2,
|
||||
0x1f: sfx_names_3,
|
||||
}
|
||||
|
||||
# music command names and parameter lists
|
||||
music_commands = {
|
||||
0xd0: ["notetype", {"type": "nibble"}, 2],
|
||||
0xe0: ["octave", 1],
|
||||
0xe8: ["toggleperfectpitch", 1],
|
||||
0xea: ["vibrato", {"type": "byte"}, {"type": "nibble"}, 3],
|
||||
0xec: ["duty", {"type": "byte"}, 2],
|
||||
0xed: ["tempo", {"type": "word"}, 3],
|
||||
0xf0: ["volume", {"type": "nibble"}, 2],
|
||||
0xf8: ["executemusic", 1],
|
||||
0xfc: ["dutycycle", {"type": "byte"}, 2],
|
||||
0xfe: ["loopchannel", {"type": "byte"}, {"type": "label"}, 4],
|
||||
0xff: ["endchannel", 1],
|
||||
}
|
||||
0x00: { "name": "note", "params": [ "note", "lower_nibble_off_by_one" ] },
|
||||
0x10: { "name": "pitch_sweep", "params": [ "nibbles_unsigned_signed" ] },
|
||||
0x20: { "name": "square_note", "params": [ "lower_nibble", "nibbles_unsigned_signed", "word" ] },
|
||||
0x21: { "name": "noise_note", "params": [ "lower_nibble", "nibbles_unsigned_signed", "byte" ] },
|
||||
0xb0: { "name": "dnote", "params": [ "byte", "lower_nibble_off_by_one" ] },
|
||||
0xc0: { "name": "rest", "params": [ "lower_nibble_off_by_one" ] },
|
||||
0xd0: { "name": "note_type", "params": [ "lower_nibble", "nibbles_unsigned_signed" ] },
|
||||
0xd1: { "name": "dspeed", "params": [ "lower_nibble" ] },
|
||||
0xe0: { "name": "octave", "params": [ "octave" ] },
|
||||
0xe8: { "name": "toggle_perfect_pitch", "params": [] },
|
||||
0xea: { "name": "vibrato", "params": [ "byte", "nibbles" ] },
|
||||
0xeb: { "name": "pitch_slide", "params": [ "byte_off_by_one", "nibbles_octave_note" ] },
|
||||
0xec: { "name": "duty_cycle", "params": [ "byte" ] },
|
||||
0xed: { "name": "tempo", "params": [ "word_big_endian" ] },
|
||||
0xee: { "name": "stereo_panning", "params": [ "nibbles_binary" ] },
|
||||
0xf0: { "name": "volume", "params": [ "nibbles" ] },
|
||||
0xf8: { "name": "execute_music", "params": [] },
|
||||
0xfc: { "name": "duty_cycle_pattern", "params": [ "crumbs" ] },
|
||||
0xfd: { "name": "sound_call", "params": [ "label" ] },
|
||||
0xfe: { "name": "sound_loop", "params": [ "byte", "label" ] },
|
||||
0xff: { "name": "sound_ret", "params": [] },
|
||||
}
|
||||
|
||||
# length in bytes of each type of parameter
|
||||
param_lengths = {
|
||||
"nibble": 1,
|
||||
"byte": 1,
|
||||
"word": 2,
|
||||
"label": 2,
|
||||
}
|
||||
"note": 0,
|
||||
"lower_nibble": 0,
|
||||
"lower_nibble_off_by_one": 0,
|
||||
"octave": 0,
|
||||
"crumbs": 1,
|
||||
"nibbles": 1,
|
||||
"nibbles_binary": 1,
|
||||
"nibbles_unsigned_signed": 1,
|
||||
"nibbles_octave_note": 1,
|
||||
"byte": 1,
|
||||
"byte_off_by_one": 1,
|
||||
"word": 2,
|
||||
"word_big_endian": 2,
|
||||
"label": 2,
|
||||
}
|
||||
|
||||
# constants used for note commands
|
||||
music_notes = {
|
||||
0x0: "C_",
|
||||
0x1: "C#",
|
||||
|
|
@ -362,114 +391,140 @@ music_notes = {
|
|||
0x9: "A_",
|
||||
0xa: "A#",
|
||||
0xb: "B_",
|
||||
}
|
||||
}
|
||||
|
||||
sfxnum = 0
|
||||
# get length in bytes of a music command by ID
|
||||
# returns 1 (command ID) + length of all params
|
||||
def get_command_length(command_id):
|
||||
length = 1
|
||||
for param in music_commands[command_id]["params"]:
|
||||
length += param_lengths[param]
|
||||
return length
|
||||
|
||||
for bank in banks:
|
||||
header = bank * 0x4000 + 3
|
||||
for sfx in range(1,banks[bank]):
|
||||
sfxname = sfx_names[sfxnum]
|
||||
sfxfile = open("music/sfx/" + sfx_names[sfxnum].lower() + ".asm", 'w')
|
||||
sfxname = "SFX_" + sfxname
|
||||
startingaddress = rom[header + 2] * 0x100 + rom[header + 1] + (0x4000 * (bank - 1))
|
||||
end = 0
|
||||
curchannel = 1
|
||||
lastchannel = (rom[header] >> 6) + 1
|
||||
channelnumber = rom[header] % 0x10
|
||||
output = ''
|
||||
while 1:
|
||||
address = startingaddress
|
||||
if curchannel != lastchannel:
|
||||
end = rom[header + 5] * 0x100 + rom[header + 4] + (0x4000 * (bank - 1))
|
||||
byte = rom[address]
|
||||
if byte == 0xf8 or (bank == 2 and sfx == 0x5e): executemusic = True
|
||||
else: executemusic = False
|
||||
output += "{}_Ch{}:\n".format(sfxname, channelnumber)
|
||||
while 1:
|
||||
if address == 0x2062a or address == 0x2063d or address == 0x20930:
|
||||
output += "\n{}_branch_{:02x}:\n".format(sfxname, address)
|
||||
if byte == 0x10 and not executemusic:
|
||||
param = rom[address + 1]
|
||||
if param % 0x10 > 7:
|
||||
output += "\tpitchenvelope {}, {}".format(param >> 4, (param & 0b0111) * -1)
|
||||
else:
|
||||
output += "\tpitchenvelope {}, {}".format(param >> 4, param % 0x10)
|
||||
command_length = 2
|
||||
elif byte < 0x30 and not executemusic:
|
||||
if channelnumber == 7:
|
||||
param = rom[address + 1]
|
||||
if param & 0b111 == 0:
|
||||
if param % 0x10 > 7:
|
||||
output += "\tnoisenote {}, {}, {}, {}".format(byte % 0x10, param >> 4, 8, rom[address + 2])
|
||||
else:
|
||||
output += "\tnoisenote {}, {}, {}, {}".format(byte % 0x10, param >> 4, 0, rom[address + 2])
|
||||
elif param % 0x10 > 7:
|
||||
output += "\tnoisenote {}, {}, {}, {}".format(byte % 0x10, param >> 4, (param & 0b0111) * -1, rom[address + 2])
|
||||
else:
|
||||
output += "\tnoisenote {}, {}, {}, {}".format(byte % 0x10, param >> 4, param % 0x10, rom[address + 2])
|
||||
command_length = 3
|
||||
else:
|
||||
param = rom[address + 1]
|
||||
if param & 0b111 == 0:
|
||||
if param % 0x10 > 7:
|
||||
output += "\tsquarenote {}, {}, {}, {}".format(byte % 0x10, param >> 4, 8, rom[address + 3] * 0x100 + rom[address + 2])
|
||||
else:
|
||||
output += "\tsquarenote {}, {}, {}, {}".format(byte % 0x10, param >> 4, 0, rom[address + 3] * 0x100 + rom[address + 2])
|
||||
elif param % 0x10 > 7:
|
||||
output += "\tsquarenote {}, {}, {}, {}".format(byte % 0x10, param >> 4, (param & 0b0111) * -1, rom[address + 3] * 0x100 + rom[address + 2])
|
||||
else:
|
||||
output += "\tsquarenote {}, {}, {}, {}".format(byte % 0x10, param >> 4, param % 0x10, rom[address + 3] * 0x100 + rom[address + 2])
|
||||
command_length = 4
|
||||
elif byte < 0xc0:
|
||||
output += "\t{} {}".format(music_notes[byte >> 4], byte % 0x10 + 1)
|
||||
command_length = 1
|
||||
elif byte < 0xd0:
|
||||
output += "\trest {}".format(byte % 0x10 + 1)
|
||||
command_length = 1
|
||||
def get_base_command_id(command_id, channel, execute_music):
|
||||
# pitch_sweep
|
||||
if command_id == 0x10 and not execute_music:
|
||||
return 0x10
|
||||
# noise_note
|
||||
elif command_id < 0x30 and not execute_music and channel == 8:
|
||||
return 0x21
|
||||
# square_note
|
||||
elif command_id < 0x30 and not execute_music:
|
||||
return 0x20
|
||||
# dnote
|
||||
elif command_id < 0xc0 and channel == 4:
|
||||
return 0xb0
|
||||
# dspeed
|
||||
elif command_id >= 0xd0 and command_id < 0xe0 and channel == 4:
|
||||
return 0xd1
|
||||
# note
|
||||
elif command_id < 0xc0:
|
||||
return 0x00
|
||||
# rest
|
||||
elif command_id < 0xd0:
|
||||
return 0xc0
|
||||
# notetype
|
||||
elif command_id < 0xe0:
|
||||
return 0xd0
|
||||
# octave
|
||||
elif command_id < 0xe8:
|
||||
return 0xe0
|
||||
else:
|
||||
return command_id
|
||||
|
||||
# get absolute pointer stored at an address in the rom
|
||||
# assumes the pointer refers to the same bank as the bank it is located in
|
||||
def get_pointer(address):
|
||||
bank = int(address / 0x4000)
|
||||
return (rom[address + 1] * 0x100 + rom[address]) % 0x4000 + bank * 0x4000
|
||||
|
||||
def dump_sfx_channel(start_address, sfx_name, sfx, channel, final_channel, channel_number, header, bank):
|
||||
address = start_address
|
||||
end_address = 0
|
||||
if channel != final_channel:
|
||||
end_address = get_pointer(header + 4)
|
||||
execute_music = False
|
||||
if rom[address] == 0xf8 or sfx_name == "Pokeflute":
|
||||
execute_music = True
|
||||
output = "SFX_{}_Ch{}:\n".format(sfx_name, channel_number)
|
||||
while 1:
|
||||
if address == 0x2062a or address == 0x2063d or address == 0x20930:
|
||||
output += "\nSFX_{}_branch_{:02x}:\n".format(sfx_name, address)
|
||||
command_id = rom[address]
|
||||
command = music_commands[get_base_command_id(command_id, channel_number, execute_music)]
|
||||
output += "\t{}".format(command["name"])
|
||||
address += 1
|
||||
# print all params for current command
|
||||
for i in range(len(command["params"])):
|
||||
param = rom[address]
|
||||
param_type = command["params"][i]
|
||||
param_length = param_lengths[param_type]
|
||||
if param_type == "note":
|
||||
output += " {}".format(music_notes[command_id >> 4])
|
||||
elif param_type == "lower_nibble":
|
||||
output += " {}".format(command_id & 0b1111)
|
||||
elif param_type == "lower_nibble_off_by_one":
|
||||
output += " {}".format((command_id & 0b1111) + 1)
|
||||
elif param_type == "octave":
|
||||
output += " {}".format(8 - (command_id & 0b1111))
|
||||
elif param_type == "crumbs":
|
||||
output += " {}, {}, {}, {}".format((param >> 6) & 0b11, (param >> 4) & 0b11, (param >> 2) & 0b11, (param >> 0) & 0b11)
|
||||
elif param_type == "nibbles":
|
||||
output += " {}, {}".format(param >> 4, param & 0b1111)
|
||||
elif param_type == "nibbles_binary":
|
||||
output += " %{:b}, %{:b}".format(param >> 4, param & 0b1111)
|
||||
elif param_type == "nibbles_unsigned_signed":
|
||||
output += " {}, {}".format(param >> 4, param & 0b1111 if param & 0b1111 <= 8 else (param & 0b0111) * -1)
|
||||
elif param_type == "nibbles_octave_note":
|
||||
output += " {}, {}".format(8 - (param >> 4), music_notes[param & 0b1111])
|
||||
elif param_type == "byte":
|
||||
output += " {}".format(param)
|
||||
elif param_type == "byte_off_by_one":
|
||||
output += " {}".format(param + 1)
|
||||
elif param_type == "word":
|
||||
output += " {}".format(param + rom[address + 1] * 0x100)
|
||||
elif param_type == "word_big_endian":
|
||||
output += " {}".format(param * 0x100 + rom[address + 1])
|
||||
elif param_type == "label":
|
||||
param = get_pointer(address)
|
||||
if param == start_address:
|
||||
output += " SFX_{}_Ch{}".format(sfx_name, channel_number)
|
||||
else:
|
||||
if byte < 0xe0:
|
||||
command = music_commands[0xd0]
|
||||
output += "\t{} {},".format(command[0], byte % 0x10)
|
||||
byte = 0xd0
|
||||
elif byte < 0xe8:
|
||||
command = music_commands[0xe0]
|
||||
output += "\t{} {}".format(command[0], 0xe8 - byte)
|
||||
byte = 0xe0
|
||||
else:
|
||||
command = music_commands[byte]
|
||||
output += "\t{}".format(command[0])
|
||||
command_length = 1
|
||||
params = 1
|
||||
# print all params for current command
|
||||
while params != len(music_commands[byte]) - 1:
|
||||
param_type = music_commands[byte][params]["type"]
|
||||
address += command_length
|
||||
command_length = param_lengths[param_type]
|
||||
param = rom[address]
|
||||
if param_type == "nibble":
|
||||
output += " {}, {}".format(param >> 4, param % 0x10)
|
||||
elif param_type == "byte":
|
||||
output += " {}".format(param)
|
||||
elif param_type == "word":
|
||||
output += " {}".format(param * 0x100 + rom[address + 1])
|
||||
else:
|
||||
param += rom[address + 1] * 0x100 - 0x4000 + (bank * 0x4000)
|
||||
if param == startingaddress: output += " {}_Ch{}".format(sfxname, channelnumber)
|
||||
else: output += " {}_branch_{:02x}".format(sfxname, param)
|
||||
params += 1
|
||||
if params != len(music_commands[byte]) - 1: output += ","
|
||||
output += "\n"
|
||||
address += command_length
|
||||
if byte == 0xff or address == end: break
|
||||
byte = rom[address]
|
||||
output += " SFX_{}_branch_{:x}".format(sfx_name, param)
|
||||
address += param_length
|
||||
if i < len(command["params"]) - 1:
|
||||
output += ","
|
||||
output += "\n"
|
||||
if command_id == 0xff or address == end_address:
|
||||
break
|
||||
return output, address
|
||||
|
||||
def dump_all_sfx_in_bank(bank, sfx_names, path):
|
||||
header = bank * 0x4000 + 3
|
||||
for sfx in range(0, len(sfx_names)):
|
||||
sfx_name = sfx_names[sfx]
|
||||
final_channel = (rom[header] >> 6) + 1
|
||||
channel_number = rom[header] % 0x10 + 1
|
||||
start_address = get_pointer(header + 1)
|
||||
cur_channel = 1
|
||||
output = ""
|
||||
while 1:
|
||||
channel_output, end_address = dump_sfx_channel(start_address, sfx_name, sfx, cur_channel, final_channel, channel_number, header, bank)
|
||||
output += channel_output
|
||||
header += 3
|
||||
channelnumber = rom[header]
|
||||
if curchannel == lastchannel:
|
||||
# output += "; {}".format(hex(address))
|
||||
sfxfile.write(output)
|
||||
if cur_channel == final_channel:
|
||||
break
|
||||
cur_channel += 1
|
||||
channel_number = rom[header] + 1
|
||||
output += "\n\n"
|
||||
startingaddress = address
|
||||
curchannel += 1
|
||||
sfxnum += 1
|
||||
start_address = end_address
|
||||
sfx_file = open(path + sfx_name.lower() + ".asm", "w")
|
||||
sfx_file.write(output)
|
||||
sfx_file.close()
|
||||
|
||||
def dump_all_sfx(path):
|
||||
for bank in sfx_groups:
|
||||
dump_all_sfx_in_bank(bank, sfx_groups[bank], path)
|
||||
|
||||
if __name__ == "__main__":
|
||||
dump_all_sfx("audio/sfx/")
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user