papermario/tools/old/substitute.py
Ethan Roseman 8837fbdf65
Player sprites & more (#1055)
* WIP work on sprites (sprite_stuff.py)

* cleanup of various stuff

* separate compiler installation into separate script

* wipz

* more

* renames, bugfixes

* more

* very grood

* cleanin

* goods and services

* oopth

* oopth2

* Parse palette data from xml

* more work

* more wipperz

* more

* it working

* git subrepo pull --force tools/splat

subrepo:
  subdir:   "tools/splat"
  merged:   "e72a868f9f"
upstream:
  origin:   "https://github.com/ethteck/splat.git"
  branch:   "master"
  commit:   "e72a868f9f"
git-subrepo:
  version:  "0.4.5"
  origin:   "https://github.com/ingydotnet/git-subrepo"
  commit:   "aa416e4"

* fix symbol_addrs for new splat

* upd8s

* Use generated header, other versions, fixes

* fixes & formatting

* wip fusing npc + player extraction & cleanup

* remove npc_files

* buildin

* fix some bugs

* Cleanup, yay0s separately

* cleen

* cleanup

* Respect stack during build

* jp spritz

* dun

* fix c files

---------

Co-authored-by: pixel-stuck <mathmcclintic@gmail.com>
2023-06-26 19:27:37 +09:00

94 lines
3.0 KiB
Python
Executable File

#!/usr/bin/env python3
import argparse
import os
import re
from pathlib import Path
from unicodedata import name
script_dir = os.path.dirname(os.path.realpath(__file__))
root_dir = script_dir + "/../"
src_dir = root_dir + "src/"
asm_dir = root_dir + "ver/current/asm/"
parser = argparse.ArgumentParser(description="Replace many functions with one")
parser.add_argument("from_list", help="path to line-separated file of functions to be replaced. first line is the string to replace them with")
args = parser.parse_args()
from_funcs = []
with open(args.from_list) as f:
from_text = f.readlines()
to_line = """
extern s32 N(ItemChoice_HasSelectedItem);
extern s32 N(ItemChoice_SelectedItemID);
ApiStatus N(ItemChoice_SaveSelected)(Evt* script, s32 isInitialCall) {
Bytecode* args = script->ptrReadPos;
N(ItemChoice_SelectedItemID) = evt_get_variable(script, *args++);
N(ItemChoice_HasSelectedItem) = TRUE;
return ApiStatus_DONE2;
}
"""
func_name = "ItemChoice_SaveSelected"
for from_line in from_text:
if len(from_line.strip()) > 0:
from_funcs.append(from_line.rstrip().split(" ")[-1])
for root, dirs, files in os.walk(src_dir):
for f_name in files:
if f_name.endswith(".c"):
f_path = os.path.join(root, f_name)
with open(f_path) as f:
f_text_orig = f.read()
f_text = f_text_orig
for func in from_funcs:
search_pattern = re.compile("\n.*" + func + "\).*\n")
f_text = re.sub(search_pattern, to_line, f_text)
if f_text != f_text_orig:
with open(f_path, "w", newline="\n") as f:
f.write(f_text)
# # Rename symbols in from_funcs to namespace equivalents
# for root, dirs, files in os.walk
to_replace = []
for root, dirs, files in os.walk(asm_dir):
for f_name in files:
if f_name.endswith(".s"):
f_path = os.path.join(root, f_name)
with open(f_path) as f:
f_text_orig = f.read()
f_text = f_text_orig
namespace = Path(f_path).parent.name
non_matching = "nonmatchings" in str(Path(f_path))
if non_matching:
namespace = Path(f_path).parent.name
if "world" not in str(Path(f_path)):
namespace = Path(f_path).parent.name
namespace = "dead_" + namespace
for func in from_funcs:
f_text = f_text.replace(func, namespace + "_" + func_name)
if f_text != f_text_orig:
if non_matching:
syms = sorted(set(re.findall(r"D_[0-9A-F]{8}_[0-9A-F]{6}", f_text)))
to_replace.append(syms[0] + " " + namespace + "_ItemChoice_HasSelectedItem\n")
to_replace.append(syms[1] + " " + namespace + "_ItemChoice_SelectedItemID\n")
with open(f_path, "w", newline="\n") as f:
f.write(f_text)
with open("to_rename.txt", "w") as f:
f.writelines(to_replace)