mirror of
https://github.com/zeldaret/oot.git
synced 2025-07-03 06:24:30 +00:00
Big actor cleanup (fixed) (#69)
* Started doing cleanup * did more work * did more migration * migrated more rodata and worked on some structs * did more work * Removal of ROOM field from initvars, some rodata migration, some string decompilation * General update * Decompiled vt strings * Tool work * Tool improvements * 270 overlay rodata files remaining * better float handling * floats * Many more floats * migrated boss_mo * assorted fixes * Migrated 10 * tool improvements * migrated 10 * 10 more * 1 more * did a few more * fixes * 10 more * more floats * Did some more, updated migrate-rodata.py to 'modify' the C file after processing in order to make to compiler process it as if it was changed. * removed changes made to script by accident * migrated largest rodata - ovl_fishing * Did some more * 114 remaining * 99 left ! * almost done migrating rodata * did some more, done for tonight * almost done, tried add support to the script for z_player * All possible rodata migrated in actor overlays * update * removed static from all overlays, ran format.sh * Removed unknown actor structs * converted a few floats * Added new lines to header files that were missing them. Removed unused asm files * Removed unused asm files * Formatting newlines Further formatting spacing .float spacing More space formatting More spacing formatting Removing .balign 4 after floats Co-authored-by: Ethan Roseman <ethteck@gmail.com>
This commit is contained in:
parent
5aef81071e
commit
045a92d7c3
10327 changed files with 33390 additions and 45661 deletions
172
tools/decompile_data.py
Normal file → Executable file
172
tools/decompile_data.py
Normal file → Executable file
|
@ -3,12 +3,128 @@
|
|||
import os
|
||||
import re
|
||||
import sys
|
||||
import struct
|
||||
|
||||
script_dir = os.path.dirname(os.path.realpath(__file__))
|
||||
root_dir = script_dir + "/../"
|
||||
data_dir = root_dir + "data/"
|
||||
asm_dir = root_dir + "asm/"
|
||||
|
||||
|
||||
floats = {}
|
||||
floats["0x3F800000"] = "1.0"
|
||||
floats["0x46EC7A00"] = "30269.0"
|
||||
floats["0x46ECC600"] = "30307.0"
|
||||
floats["0x46ECE600"] = "30323.0"
|
||||
floats["0x3B23D70A"] = "0.0025"
|
||||
floats["0x3D4CCCCD"] = "0.05"
|
||||
floats["0x3DCCCCCD"] = "0.1"
|
||||
floats["0x451C4000"] = "2500.0"
|
||||
floats["0x453B8000"] = "3000.0"
|
||||
floats["0x44BB8000"] = "1500.0"
|
||||
floats["0x3FCCCCCD"] = "1.6"
|
||||
floats["0x3E99999A"] = "0.3"
|
||||
floats["0x40C90FDB"] = "6.28318548203"
|
||||
floats["0x3DA3D70A"] = "0.08"
|
||||
floats["0x3F333333"] = "0.7"
|
||||
floats["0x3F19999A"] = "0.6"
|
||||
floats["0x40133333"] = "2.3"
|
||||
floats["0x40933333"] = "4.6"
|
||||
floats["0x44758000"] = "982.0"
|
||||
floats["0x409FFFEB"] = "4.99998998642"
|
||||
floats["0x40FFFFEB"] = "7.99998998642"
|
||||
floats["0x3F3AE148"] = "0.73"
|
||||
floats["0x3A83126F"] = "0.001"
|
||||
floats["0x494EA400"] = "846400.0"
|
||||
floats["0x3DE147AE"] = "0.11"
|
||||
floats["0x3C23D70B"] = "0.0100000007078"
|
||||
floats["0x3E16872B"] = "0.147"
|
||||
floats["0x3B03126F"] = "0.002"
|
||||
floats["0x40490FDB"] = "3.14159274101"
|
||||
floats["0xC49C4000"] = "-1250.0"
|
||||
floats["0x3FC90FDB"] = "1.57079637051"
|
||||
floats["0x44278000"] = "670.0"
|
||||
floats["0x3CA3D70A"] = "0.02"
|
||||
floats["0x3F7851EC"] = "0.97"
|
||||
floats["0x3E999999"] = "0.299999982119"
|
||||
floats["0x3E4CCCCD"] = "0.2"
|
||||
floats["0x3B83126E"] = "0.00399999972433"
|
||||
floats["0x3F59999A"] = "0.85"
|
||||
floats["0x38C90FDB"] = "9.58738019108e-05"
|
||||
floats["0x3D23D70A"] = "0.04"
|
||||
floats["0xC4548000"] = "-850.0"
|
||||
floats["0x45034000"] = "2100.0"
|
||||
floats["0xBC23D70A"] = "-0.01"
|
||||
floats["0x3C23D70A"] = "0.01"
|
||||
floats["0x3CCCCCCD"] = "0.025"
|
||||
floats["0xBCF5C28F"] = "-0.03"
|
||||
floats["0x3FE1307A"] = "1.75929188728"
|
||||
floats["0x3FA4DEEC"] = "1.28805303574"
|
||||
floats["0xBF20D97B"] = "-0.628318488598"
|
||||
floats["0x3EF1463A"] = "0.471238911152"
|
||||
floats["0x3F333334"] = "0.700000047684"
|
||||
floats["0x407FEF9E"] = "3.99900007248"
|
||||
floats["0x3FF33333"] = "1.9"
|
||||
floats["0x3F666666"] = "0.9"
|
||||
floats["0x44A8C000"] = "1350.0"
|
||||
floats["0x44898000"] = "1100.0"
|
||||
floats["0x40C8F5C3"] = "6.28"
|
||||
floats["0x48742400"] = "250000.0"
|
||||
floats["0xBF060A92"] = "-0.523598790169"
|
||||
floats["0x3C888889"] = "0.0166666675359"
|
||||
floats["0x3F4CCCCD"] = "0.8"
|
||||
floats["0x3FFFDF3B"] = "1.99899995327"
|
||||
floats["0x3A031270"] = "0.000500000081956"
|
||||
floats["0x3F99999A"] = "1.2"
|
||||
floats["0x471C4000"] = "40000.0"
|
||||
floats["0x45992000"] = "4900.0"
|
||||
floats["0x461C4000"] = "10000.0"
|
||||
floats["0x3E19999A"] = "0.15"
|
||||
floats["0x448FC000"] = "1150.0"
|
||||
floats["0x3727C5AC"] = "9.99999974738e-06"
|
||||
floats["0x358637BD"] = "9.99999997475e-07"
|
||||
floats["0xBF99999A"] = "-1.2"
|
||||
floats["0x3F8CCCCD"] = "1.1"
|
||||
floats["0x40066666"] = "2.1"
|
||||
floats["0x3ECCCCCD"] = "0.4"
|
||||
floats["0x44A28000"] = "1300.0"
|
||||
floats["0x3CF5C28F"] = "0.03"
|
||||
floats["0x43A6AAAB"] = "333.333343506"
|
||||
floats["0x3BA3D70A"] = "0.005"
|
||||
floats["0x3C03126F"] = "0.008"
|
||||
floats["0x459C4000"] = "5000.0"
|
||||
floats["0x3FAAAAA8"] = "1.33333301544"
|
||||
floats["0x3FD9999A"] = "1.7"
|
||||
floats["0x45DAC000"] = "7000.0"
|
||||
floats["0x4016CBE4"] = "2.35619449615"
|
||||
floats["0x49095440"] = "562500.0"
|
||||
floats["0x45BB8000"] = "6000.0"
|
||||
floats["0x3FB33333"] = "1.4"
|
||||
floats["0x3C134ACB"] = "0.00899"
|
||||
floats["0x458CA000"] = "4500.0"
|
||||
floats["0x3FA66666"] = "1.3"
|
||||
floats["0xBF4CCCCD"] = "-0.8"
|
||||
floats["0xBF666666"] = "-0.9"
|
||||
floats["0xBF59999A"] = "-0.85"
|
||||
floats["0x3FFEB852"] = "1.99000000954"
|
||||
floats["0x404CCCCD"] = "3.2"
|
||||
floats["0xBB449BA6"] = "-0.003"
|
||||
floats["0x3D99999A"] = "0.075"
|
||||
floats["0x3D0F5C29"] = "0.035"
|
||||
floats["0xBFC90FDB"] = "-1.57079637051"
|
||||
floats["0xB8D1B717"] = "-9.99999974738e-05"
|
||||
floats["0x3B59E83E"] = "0.003325"
|
||||
floats["0x3B9BA5E3"] = "0.00475"
|
||||
floats["0x3AC49BA6"] = "0.0015"
|
||||
floats["0x3CA3D70B"] = "0.0200000014156"
|
||||
floats["0x4316199A"] = "150.1"
|
||||
floats["0x3FD5DCA8"] = "1.67079639435"
|
||||
floats["0xB8C90FDB"] = "-9.58738019108e-05"
|
||||
floats["0x3B6BEDFA"] = "0.0036"
|
||||
floats["0x3DF5C28F"] = "0.12"
|
||||
floats["0x3B30F27C"] = "0.0027"
|
||||
floats["0xC3E28000"] = "-453.0"
|
||||
floats["0xC4DC2000"] = "-1761.0"
|
||||
floats["0x449FC000"] = "1278.0"
|
||||
def try_text(text_bytes):
|
||||
bad_bytes = 0
|
||||
for byte in text_bytes:
|
||||
|
@ -16,8 +132,8 @@ def try_text(text_bytes):
|
|||
bad_bytes += 1
|
||||
|
||||
# Arbitrary string detection heuristic
|
||||
if bad_bytes / len(text_bytes) >= 0.3:
|
||||
return None
|
||||
#if bad_bytes / len(text_bytes) >= 0.3:
|
||||
# return None
|
||||
|
||||
try:
|
||||
text = text_bytes.decode("EUC-JP")
|
||||
|
@ -29,10 +145,32 @@ def try_text(text_bytes):
|
|||
text = text.replace("\\x00", "")
|
||||
text = text.replace("\n", "\\n")
|
||||
text = text.replace("\"", "\\\"")
|
||||
ret = "\n .asciz \"" + text + "\"\n .balign 4\n"
|
||||
return ret
|
||||
return text
|
||||
|
||||
|
||||
def is_zeros(stuff):
|
||||
for piece in stuff:
|
||||
if piece.strip() != "0x00000000":
|
||||
return False
|
||||
return True
|
||||
|
||||
|
||||
def try_float(word):
|
||||
if (word in floats):
|
||||
return floats[word]
|
||||
if (word[:3] == "0x3") or (word[:3] == "0x4") or \
|
||||
(word[:3] == "0xB") or (word[:3] == "0xC"):
|
||||
return struct.unpack('!f', bytes.fromhex(word[2:10]))[0]
|
||||
|
||||
|
||||
def quick_convert(words_string):
|
||||
words = words_string.split(",")
|
||||
byte_array = b""
|
||||
for word in words:
|
||||
data = word.strip()[2:]
|
||||
byte_array += bytearray.fromhex(data)
|
||||
return byte_array.decode("EUC-JP")
|
||||
|
||||
def word_convert(byte_string):
|
||||
try:
|
||||
words = byte_string.split(",")
|
||||
|
@ -43,10 +181,18 @@ def word_convert(byte_string):
|
|||
except ValueError:
|
||||
return byte_string
|
||||
|
||||
if len(words) > 1:
|
||||
if byte_array[0] == 63 and byte_array[-1] == 45:
|
||||
return byte_string
|
||||
if data == '0A0A0000':
|
||||
return "\\n\\n"
|
||||
if len(words) > 1 and not is_zeros(words[1:]):
|
||||
res = try_text(byte_array)
|
||||
if res is not None:
|
||||
return res
|
||||
return " .asciz \"" + res + "\"\n .balign 4\n"
|
||||
if len(words) == 1 or is_zeros(words[1:]):
|
||||
res = str(try_float(words[0].strip()))
|
||||
if res is not None:
|
||||
return " .float " + res + "\n"
|
||||
|
||||
return byte_string
|
||||
|
||||
|
@ -73,18 +219,16 @@ def process_data_file(file_path):
|
|||
|
||||
|
||||
def main():
|
||||
skip_list = ['z_en_kanban.rodata.s', 'z_demo_tre_lgt.rodata.s', 'z_en_light.rodata.s']
|
||||
|
||||
i = 0
|
||||
for root, dirs, files in os.walk(data_dir):
|
||||
for root, dirs, files in os.walk(asm_dir):
|
||||
for file in files:
|
||||
if i == 10:
|
||||
return
|
||||
if file.endswith(".rodata.s") and file not in skip_list:
|
||||
#if i == 10:
|
||||
# return
|
||||
if file.endswith(".s"):
|
||||
path = os.path.join(root, file)
|
||||
if process_data_file(path):
|
||||
print("Processed " + path)
|
||||
i += 1
|
||||
|
||||
|
||||
main()
|
||||
#main()
|
||||
|
|
86
tools/format_s_files.py
Normal file
86
tools/format_s_files.py
Normal file
|
@ -0,0 +1,86 @@
|
|||
#!/usr/bin/python3
|
||||
|
||||
import os
|
||||
import sys
|
||||
import re
|
||||
from disassemble import get_z_name
|
||||
|
||||
script_dir = os.path.dirname(os.path.realpath(__file__))
|
||||
root_dir = script_dir + "/../"
|
||||
src_dir = root_dir + "src/overlays/"
|
||||
asm_dir = root_dir + "asm/non_matchings/overlays/"
|
||||
|
||||
|
||||
def remove_empty_lines_after_glabel(file_text):
|
||||
file_lines = file_text.splitlines()
|
||||
last_glabel = False
|
||||
to_remove = []
|
||||
for i, line in enumerate(file_lines):
|
||||
if "glabel" in line:
|
||||
last_glabel = True
|
||||
continue
|
||||
if last_glabel and not line.strip():
|
||||
to_remove.append(i)
|
||||
last_glabel = False
|
||||
if len(to_remove) > 0:
|
||||
for line_num in reversed(to_remove):
|
||||
del file_lines[line_num]
|
||||
file_text = "\n".join(file_lines)
|
||||
return file_text
|
||||
|
||||
def remove_balign_after_float(file_text):
|
||||
file_lines = file_text.splitlines()
|
||||
last_float = False
|
||||
to_remove = []
|
||||
for i, line in enumerate(file_lines):
|
||||
if ".float" in line:
|
||||
last_float = True
|
||||
continue
|
||||
if last_float and line == " .balign 4":
|
||||
to_remove.append(i)
|
||||
last_float = False
|
||||
if len(to_remove) > 0:
|
||||
for line_num in reversed(to_remove):
|
||||
del file_lines[line_num]
|
||||
file_text = "\n".join(file_lines)
|
||||
return file_text
|
||||
|
||||
|
||||
def format_file(file_path):
|
||||
with open(file_path) as f:
|
||||
orig_file_text = f.read()
|
||||
|
||||
file_text = orig_file_text
|
||||
|
||||
# Condense 2+ empty lines to 1
|
||||
file_text = file_text.replace("\n\n\n+", "\n\n")
|
||||
|
||||
# Remove empty lines after section declarations
|
||||
file_text = file_text.replace(".rdata\n\n", ".rdata\n")
|
||||
file_text = file_text.replace(".late_rodata\n\n", ".late_rodata\n")
|
||||
file_text = file_text.replace(".text\n\n", ".text\n")
|
||||
|
||||
# Remove dumb empty lines after glabel
|
||||
file_text = remove_empty_lines_after_glabel(file_text)
|
||||
|
||||
# Remove dumb balign 4 lines after float
|
||||
file_text = remove_balign_after_float(file_text)
|
||||
|
||||
# Make sure there's only one empty line at the end
|
||||
file_text = file_text.rstrip("\n") + "\n"
|
||||
|
||||
if file_text != orig_file_text:
|
||||
with open(file_path, "w", newline="\n") as f:
|
||||
f.write(file_text)
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
def main():
|
||||
for root, dirs, files in os.walk(asm_dir):
|
||||
for f in files:
|
||||
if f.endswith(".s"):
|
||||
format_file(os.path.join(root, f))
|
||||
|
||||
|
||||
main()
|
304
tools/migrate-rodata.py
Normal file
304
tools/migrate-rodata.py
Normal file
|
@ -0,0 +1,304 @@
|
|||
"""
|
||||
Given a code file name (excluding the file extension, e.g. z_view) this script
|
||||
will attempt to build rodata and late_rodata sections for all of its functions.
|
||||
|
||||
This supports overlays to an extent but before running it for any check to
|
||||
ensure the rodata file is formatted correctly (see files in code for examples
|
||||
of properly formatted rodata sections)
|
||||
|
||||
This supports automatically commenting or deleting the rodata file from the
|
||||
spec and automatic deletion of the rodata file itself (only use if you are sure
|
||||
it will build afterwards)
|
||||
|
||||
Place this in the root of your project (same folder as the makefile) and run.
|
||||
|
||||
Not sure if this works well with .incbin if that can even be found in rodata
|
||||
"""
|
||||
|
||||
import re
|
||||
import os
|
||||
from os import system, listdir, remove, walk
|
||||
from os.path import exists, isdir, sep
|
||||
|
||||
# FUNCTIONS -----------------------------------------------------------------
|
||||
|
||||
"""
|
||||
Extracts rodata symbols from asm
|
||||
"""
|
||||
def asm_syms(asm):
|
||||
split = re.split("jtbl_|D_",asm)
|
||||
return [s.partition(")")[0] for s in split[1:len(split)]]
|
||||
|
||||
"""
|
||||
Extracts rodata symbols from rodata
|
||||
"""
|
||||
def rodata_syms(rodata):
|
||||
split = re.split("glabel jtbl_|glabel D_",rodata)
|
||||
return [s.partition("\n")[0] for s in split[1:len(split)]]
|
||||
|
||||
"""
|
||||
Extracts the symbol from a single rodata block
|
||||
"""
|
||||
def rodata_sym(rodata_block):
|
||||
return (re.split("glabel jtbl_|glabel D_",rodata_block)[1]).split("\n")[0]
|
||||
|
||||
"""
|
||||
Splits rodata into blocks
|
||||
"""
|
||||
def rodata_blocks(rodata):
|
||||
split = rodata.split("glabel")
|
||||
return ["glabel" + b for b in split[1:len(split)]]
|
||||
|
||||
"""
|
||||
Gets the block size
|
||||
"""
|
||||
def rodata_block_size(rodata):
|
||||
split = rodata.split(" .")
|
||||
elements = split[1:len(split)]
|
||||
size = 0
|
||||
for e in elements:
|
||||
element_type = e.split(" ")[0]
|
||||
if element_type == "double":
|
||||
size += 8
|
||||
if element_type == "float":
|
||||
size += 4
|
||||
if element_type == "word":
|
||||
size += 4
|
||||
if element_type == "incbin":
|
||||
size += int(e.rpartition(", ")[2].split("\n")[0],16)
|
||||
if element_type == "ascii":
|
||||
size += len(e.split("\"")[1].split("\"")[0])
|
||||
if element_type == "asciz":
|
||||
size += len(e.split("\"")[1].split("\"")[0])
|
||||
if element_type == "balign":
|
||||
size += size % int(e.split(" ")[1])
|
||||
return size
|
||||
|
||||
"""
|
||||
Gets the text size
|
||||
"""
|
||||
def text_size(asm):
|
||||
instructions = [l for l in asm.split("\n") if l.startswith("/* ")]
|
||||
return 4*(len(instructions)-1)
|
||||
|
||||
"""
|
||||
Gets the rodata-to-text
|
||||
"""
|
||||
def late_rodata_ratio(asm,late_rodata_blocks):
|
||||
total_rodata_size = 0
|
||||
for b in late_rodata_blocks:
|
||||
total_rodata_size += rodata_block_size(b)
|
||||
return total_rodata_size/text_size(asm)
|
||||
|
||||
"""
|
||||
Accepts a single block of rodata and extracts the type
|
||||
"""
|
||||
def rodata_type(rodata_block):
|
||||
first_split = re.split("\s+\.", rodata_block)
|
||||
return first_split[1].split(" ")[0]
|
||||
|
||||
"""
|
||||
Checks if a block should go in .rdata or .late_rodata
|
||||
"""
|
||||
def is_rodata(r):
|
||||
if rodata_type(r)=="asciz" or rodata_type=="ascii":
|
||||
return True
|
||||
if rodata_type(r)=="incbin":
|
||||
return True
|
||||
return False
|
||||
|
||||
"""
|
||||
For given asm and rodata files, build a rodata section for the asm file
|
||||
"""
|
||||
def build_rodata(asm, rodata):
|
||||
contained_syms = [s for s in asm_syms(asm) if s in rodata_syms(rodata)]
|
||||
contained_blocks = [b for b in rodata_blocks(rodata) if rodata_sym(b) in contained_syms]
|
||||
# TODO include arrays in rodata_list
|
||||
rodata_list = [r for r in contained_blocks if is_rodata(r)]
|
||||
return_str = ""
|
||||
if (len(rodata_list)!=0):
|
||||
return_str += ".rdata\n"
|
||||
for r in rodata_list:
|
||||
return_str += r
|
||||
late_rodata_list = [r for r in contained_blocks if r not in rodata_list]
|
||||
if (len(late_rodata_list)!=0):
|
||||
if late_rodata_ratio(asm,late_rodata_list) > (1/3):
|
||||
top_sym = rodata_sym(late_rodata_list[0])
|
||||
if top_sym.endswith("0") or top_sym.endswith("8"):
|
||||
return_str += ".late_rodata\n.late_rodata_alignment 8\n"
|
||||
elif top_sym.endswith("4") or top_sym.endswith("C"):
|
||||
return_str += ".late_rodata\n.late_rodata_alignment 4\n"
|
||||
else:
|
||||
return_str += ".late_rodata\n"
|
||||
for r in late_rodata_list:
|
||||
return_str += r
|
||||
return None if return_str=="" else return_str + ("" if return_str.endswith("\n\n") else "\n") + ".text\n"
|
||||
|
||||
"""
|
||||
Gets all file paths contained in a given folder, does not enter subfolders
|
||||
"""
|
||||
def get_file_paths(folder_path):
|
||||
return next(walk(folder_path),(None,None,[]))[2]
|
||||
|
||||
"""
|
||||
Given a path, reads the asm .s file into a single string
|
||||
"""
|
||||
def file_read(path):
|
||||
with open(path, 'r', encoding="utf-8") as infile:
|
||||
return infile.read()
|
||||
|
||||
"""
|
||||
Writes the rodata section to the start of the file specified by path
|
||||
"""
|
||||
def rodata_write(path, section):
|
||||
with open(path, 'r+', encoding="utf-8", newline="\n") as outfile:
|
||||
original = outfile.read()
|
||||
outfile.seek(0,0)
|
||||
outfile.write(str(section) + original)
|
||||
|
||||
"""
|
||||
Comments out the line in spec associated with the given filenames
|
||||
"""
|
||||
def modify_spec(filenames, identifier, delete):
|
||||
lines = ""
|
||||
with open("spec", 'r+', encoding="utf-8", newline="\n") as spec:
|
||||
lines = spec.read().split("\n")
|
||||
changed = False
|
||||
files = filenames.split(",")
|
||||
for filename in files:
|
||||
if identifier == "code" and " include \"build/data/" + filename + ".rodata.o\"" in lines:
|
||||
e = lines.index(" include \"build/data/" + filename + ".rodata.o\"")
|
||||
if delete:
|
||||
del lines[e]
|
||||
else:
|
||||
lines[e] = " //include \"build/data/" + filename + ".rodata.o\""
|
||||
changed = True
|
||||
elif " include \"build/data/overlays/" + identifier + "/z_" + filename.lower() + ".rodata.o\"" in lines:
|
||||
e = lines.index(" include \"build/data/overlays/" + identifier + "/z_" + filename.lower() + ".rodata.o\"")
|
||||
if delete:
|
||||
del lines[e]
|
||||
else:
|
||||
lines[e] = " //include \"build/data/overlays/" + identifier + "/z_" + filename.lower() + ".rodata.o\""
|
||||
changed = True
|
||||
if changed:
|
||||
modified = "\n".join(lines)
|
||||
with open("spec", 'w', encoding="utf-8", newline="\n") as spec:
|
||||
#spec.seek(0,0)
|
||||
spec.write(modified)
|
||||
|
||||
"""
|
||||
Processes each individual file
|
||||
asm\non_matchings\overlays\<identifier>
|
||||
data\overlays\<identifier>
|
||||
asm\non_matchings\code\
|
||||
data\code\
|
||||
"""
|
||||
def process_file(filename, identifier, delete_rodata):
|
||||
folder_path = "asm" + sep + "non_matchings" + sep + ("code" + sep if identifier=="code" else "overlays" + sep + identifier.lower() + sep + "ovl_") + filename + sep
|
||||
rodata_path = "data" + sep + (sep if identifier=="code" else "overlays" + sep + identifier.lower() + sep + "z_") + filename.lower() + ".rodata.s"
|
||||
if filename == "player":
|
||||
folder_path = "asm" + sep + "non_matchings" + sep + "overlays" + sep + "actors" + sep + "ovl_player_actor" + sep
|
||||
print("ASM at: " + folder_path)
|
||||
print("Data at: " + rodata_path)
|
||||
if not exists(folder_path):
|
||||
print("Aborting: ASM does not exist")
|
||||
return
|
||||
if not exists(rodata_path):
|
||||
print("Aborting: Data does not exist")
|
||||
return
|
||||
files = [folder_path + f for f in get_file_paths(folder_path)]
|
||||
for asm_file in files:
|
||||
asm = file_read(asm_file)
|
||||
print("Found asm file " + asm_file)
|
||||
if ".rdata" in asm:
|
||||
print("Skipping: it already has a rodata section")
|
||||
continue
|
||||
print("Processing asm file " + asm_file)
|
||||
section = build_rodata(asm, file_read(rodata_path))
|
||||
if section is not None:
|
||||
print("Writing asm file " + asm_file)
|
||||
rodata_write(asm_file, section)
|
||||
else: print("Skipping: no rodata to write")
|
||||
print("Built rodata sections for " + identifier + " file " + filename)
|
||||
if delete_rodata:
|
||||
remove(rodata_path)
|
||||
print("Deleted rodata at " + rodata_path)
|
||||
|
||||
"""
|
||||
Allows files to be provided as comma-separated filenames for batch migration
|
||||
"""
|
||||
def process_files(filenames, identifier, spechandle, delete_rodata):
|
||||
if "," in filenames:
|
||||
files = filenames.split(",")
|
||||
for f in files:
|
||||
process_file(f, identifier, delete_rodata)
|
||||
else:
|
||||
process_file(filenames, identifier, delete_rodata)
|
||||
if spechandle.lower() == "delete":
|
||||
modify_spec(filenames, identifier, True)
|
||||
print("Deleted rodata for files in spec")
|
||||
elif spechandle.lower() == "comment":
|
||||
result = modify_spec(filenames, identifier, False)
|
||||
if result:
|
||||
print("Commented out rodata for files in spec")
|
||||
|
||||
"""
|
||||
Asks what to do about spec and rodata, converts 'all' to comma-separated filenames
|
||||
"""
|
||||
def check_spec_rodata(filenames, identifier):
|
||||
spechandle = input("Delete, Comment or Leave spec? ")
|
||||
delete_rodata = input("Delete rodata file(s)? (Y/N) ")
|
||||
if filenames == "all" or "all|" in filenames:
|
||||
to_remove_list = []
|
||||
if "all|" in filenames:
|
||||
print("all| in filenames")
|
||||
to_remove_list = filenames.split("|")[1]
|
||||
basedir = "asm" + sep + "non_matchings" + sep + ("code" if identifier=="code" else "overlays" + sep + identifier.lower()) + sep
|
||||
folder_names = [name.replace("ovl_","") for name in listdir(basedir) if isdir(basedir + name) and name not in to_remove_list]
|
||||
filenames = ",".join(map(str, folder_names))
|
||||
print(filenames)
|
||||
process_files(filenames, identifier, spechandle, delete_rodata == "Y")
|
||||
|
||||
"""
|
||||
Main execution
|
||||
"""
|
||||
def run(show_help):
|
||||
if(show_help):
|
||||
print("""Usage: Enter 'Code' or 'Overlay' and follow the instructions.
|
||||
Batch migrate files by entering comma-separated filenames instead of a single filename.
|
||||
Migrate all files by entering 'all' for filenames. Exclude files from all with all| followed by comma-separated filenames Use at your own risk.
|
||||
Enter 'q' to the code or overlay question to quit.""")
|
||||
code_or_overlay = input("Code or Overlay? ")
|
||||
if(code_or_overlay == "q"):
|
||||
return
|
||||
if(code_or_overlay == "Code"):
|
||||
filename = input("Enter the code file name(s) (excluding .c) or all: ")
|
||||
check_spec_rodata(filename, "code")
|
||||
elif(code_or_overlay == "Overlay"):
|
||||
overlay_type = input("Actor, Effect or Gamestate? ")
|
||||
if(overlay_type == "Actor"):
|
||||
filename = input("Enter the actor name(s) (excluding ovl_ or z_, ex. obj_bombiwa) or all: ")
|
||||
check_spec_rodata(filename, "actors")
|
||||
elif(overlay_type == "Effect"):
|
||||
filename = input("Enter the effect name(s) (excluding ovl_ or z_, ex. effect_ss_bomb) or all: ")
|
||||
check_spec_rodata(filename, "effects")
|
||||
elif(overlay_type == "Gamestate"):
|
||||
filename = input("Enter the gamestate name(s) (excluding ovl_ or z_, ex. kaleido_scope) or all: ")
|
||||
check_spec_rodata(filename, "gamestates")
|
||||
run(True)
|
||||
|
||||
# PROGRAM -------------------------------------------------------------------
|
||||
|
||||
#run(False)
|
||||
#bigs = ["Boss_Ganon", "Boss_Ganondrof","En_Wf", "Door_Warp1",]
|
||||
ovls = ["En_Elf"]
|
||||
|
||||
for i, ovl in enumerate(ovls):
|
||||
if i == 10:
|
||||
break
|
||||
process_files(ovl, "actors", "Delete", True)
|
||||
command = "echo >> src/overlays/actors/ovl_" + ovls[i] + "/z_" + ovls[i].lower() + ".c"
|
||||
if ovls[0] == "player":
|
||||
command = "echo >> src/overlays/actors/ovl_player_actor/z_player.c"
|
||||
os.system(command) # purpose of this is to "modify" each C file in order to prevent undefined symbol errors.
|
||||
# the new line will be removed by format.sh
|
Loading…
Add table
Add a link
Reference in a new issue