diff --git a/src/30450.c b/src/30450.c index 21d8b04778..12e5b678b5 100644 --- a/src/30450.c +++ b/src/30450.c @@ -517,6 +517,8 @@ s32* func_80055EB4(s32 arg0) { return ret; } +static const f32 padding[] = {0.0f}; + s32 func_80055F58(s32 arg0, u32 arg1, u32 arg2) { s32* subroutine_arg4; s32* subroutine_arg5; diff --git a/src/9D650.c b/src/9D650.c new file mode 100644 index 0000000000..49a2a0759b --- /dev/null +++ b/src/9D650.c @@ -0,0 +1,13 @@ +#include "common.h" + +Gfx D_801041A0[] = { + gsSPEndDisplayList(), +}; + +#include "ui/stat_heart.png.inc.c" + +Gfx D_801045A8[] = { + gsSPEndDisplayList(), +}; + +#include "ui/stat_flower.png.inc.c" diff --git a/src/world/area_mac/machi/7E73A0.c b/src/world/area_mac/machi/7E73A0.c index 5aa7189b2a..ab0adb1f40 100644 --- a/src/world/area_mac/machi/7E73A0.c +++ b/src/world/area_mac/machi/7E73A0.c @@ -1,5 +1,70 @@ #include "machi.h" +static char* STR01 = "GSW MAP"; +static char* STR02 = "GSW DOKAN"; +static char* STR03 = "GSW FBTL"; +static char* STR04 = "GSW BTL"; +static char* STR05 = "GSW NPC"; +static char* STR06 = "GSW BAT"; +static char* STR07 = "GSW OSR"; +static char* STR08 = "GSW END"; +static char* STR09 = "GSW KPA"; +static char* STR10 = "GSW PRA"; +static char* STR11 = "GSW SAM"; +static char* STR12 = "GSW FLO"; +static char* STR13 = "GSW KZN"; +static char* STR14 = "GSW JAN"; +static char* STR15 = "GSW OMO"; +static char* STR16 = "GSW DGB"; +static char* STR17 = "GSW ARN"; +static char* STR18 = "GSW OBK"; +static char* STR19 = "GSW MIM"; +static char* STR20 = "GSW ISK"; +static char* STR21 = "GSW SBK"; +static char* STR22 = "GSW DRO"; +static char* STR23 = "GSW IWA"; +static char* STR24 = "GSW TRD"; +static char* STR25 = "GSW NOK"; +static char* STR26 = "GSW HOS"; +static char* STR27 = "GSW KKJ"; +static char* STR28 = "GSW KGR"; +static char* STR29 = "GSW TIK"; +static char* STR30 = "GSW MAC"; +static char* STR31 = "GSW KMR"; +static char* STR32 = "GSW EVT"; +static char* STR33 = "GSWF MAP"; +static char* STR34 = "GSWF DOKAN"; +static char* STR35 = "GSWF FBTL"; +static char* STR36 = "GSWF BTL"; +static char* STR37 = "GSWF NPC"; +static char* STR38 = "GSWF BAT"; +static char* STR39 = "GSWF OSR"; +static char* STR40 = "GSWF END"; +static char* STR41 = "GSWF KPA"; +static char* STR42 = "GSWF PRA"; +static char* STR43 = "GSWF SAM"; +static char* STR44 = "GSWF FLO"; +static char* STR45 = "GSWF KZN"; +static char* STR46 = "GSWF JAN"; +static char* STR47 = "GSWF OMO"; +static char* STR48 = "GSWF DGB"; +static char* STR49 = "GSWF ARN"; +static char* STR50 = "GSWF OBK"; +static char* STR51 = "GSWF MIM"; +static char* STR52 = "GSWF ISK"; +static char* STR53 = "GSWF SBK"; +static char* STR54 = "GSWF DRO"; +static char* STR55 = "GSWF IWA"; +static char* STR56 = "GSWF TRD"; +static char* STR57 = "GSWF NOK"; +static char* STR58 = "GSWF HOS"; +static char* STR59 = "GSWF KKJ"; +static char* STR60 = "GSWF KGR"; +static char* STR61 = "GSWF TIK"; +static char* STR62 = "GSWF MAC"; +static char* STR63 = "GSWF KMR"; +static char* STR64 = "GSWF EVT"; + static char* N(exit_str_0) = "kmr_09"; static char* N(exit_str_1) = "nok_10"; static char* N(exit_str_2) = "iwa_00"; diff --git a/tools/splat/.github/workflows/mypy.yml b/tools/splat/.github/workflows/mypy.yml index b842ebd82f..3cfd2018cf 100644 --- a/tools/splat/.github/workflows/mypy.yml +++ b/tools/splat/.github/workflows/mypy.yml @@ -10,6 +10,18 @@ jobs: mypy: runs-on: ubuntu-latest + name: mypy steps: - - uses: actions/checkout@v2 - - uses: jpetrucciani/mypy-check@master + - uses: actions/checkout@v1 + - name: Set up Python 3.9 + uses: actions/setup-python@v1 + with: + python-version: 3.9 + - name: Install Dependencies + run: | + pip install mypy + pip install -r requirements.txt + pip install types-PyYAML + - name: mypy + run: | + mypy --show-column-numbers --hide-error-context . \ No newline at end of file diff --git a/tools/splat/.gitrepo b/tools/splat/.gitrepo index ec856cf9c2..c5e8b472c7 100644 --- a/tools/splat/.gitrepo +++ b/tools/splat/.gitrepo @@ -6,7 +6,7 @@ [subrepo] remote = https://github.com/ethteck/splat.git branch = master - commit = 5d7a6c0813c5045876718d0c61a153e90bf16d2b - parent = 015151cbfbe09820d5f71aeae7a255ede7cbe4c6 + commit = 7eb5744b2a3a5e2a4253996f587b7666db597c57 + parent = 31629ad772cbb4cda8df2a96ce9d91b74883f752 method = merge cmdver = 0.4.3 diff --git a/tools/splat/CHANGELOG.md b/tools/splat/CHANGELOG.md index ce2d50e293..17c7a2562c 100644 --- a/tools/splat/CHANGELOG.md +++ b/tools/splat/CHANGELOG.md @@ -1,5 +1,18 @@ # splat Release Notes +### 0.7.9 +* Finally removed the dumb linker section alignment hack +* Added version number to output on execution + +### 0.7.8 + +* Fixed a bug relating to a linker section alignment hack (thanks Wiseguy!) +* Fixed a bug in linker_entry.py's clean_up_path that should make this function more versatile (thanks Wiseguy!) + +### 0.7.7 + +* Disassembly now reads the `size` property of a function in symbol_addrs.txt to disassemble `size / 4` number of instructions. Feel free to specify the size of your functions in your symbol_addrs file if splat's disassembly is chopping a function too short or making a function too long. + ### 0.7.6 * Fixed a bug involving detection of defined functions in c files for GLOBAL_ASM-using projects diff --git a/tools/splat/segtypes/linker_entry.py b/tools/splat/segtypes/linker_entry.py index 78980da3f9..60172ced38 100644 --- a/tools/splat/segtypes/linker_entry.py +++ b/tools/splat/segtypes/linker_entry.py @@ -2,11 +2,27 @@ from typing import Union, List from pathlib import Path from util import options from segtypes.segment import Segment +import os import re # clean 'foo/../bar' to 'bar' def clean_up_path(path: Path) -> Path: - return path.resolve().relative_to(options.get_base_path().resolve()) + path_resolved = path.resolve() + base_resolved = options.get_base_path().resolve() + try: + return path_resolved.relative_to(base_resolved) + except ValueError: + pass + + # If the path wasn't relative to the splat file, use the working directory instead + cwd = Path(os.getcwd()) + try: + return path_resolved.relative_to(cwd) + except ValueError: + pass + + # If it wasn't relative to that too, then just return the path as-is + return path def path_to_object_path(path: Path) -> Path: path = clean_up_path(path) @@ -70,7 +86,6 @@ class LinkerWriter(): self._write_symbol(f"{seg_name}_TEXT_START", ".") - do_next = False text_ended = False data_started = False data_ended = False @@ -107,17 +122,6 @@ class LinkerWriter(): bss_started = True self._write_symbol(f"{seg_name}_BSS_START", ".") - start = entry.segment.rom_start - if isinstance(start, int): - # Create new sections for non-0x10 alignment (hack) - if start % 0x10 != 0 and i != 0 or do_next: - self._end_block() - self._begin_segment(entry.segment, mid_segment=True) - do_next = False - - if start % 0x10 != 0 and i != 0: - do_next = True - if entry.object_path and cur_section == ".data": path_cname = re.sub(r"[^0-9a-zA-Z_]", "_", str(entry.segment.dir / entry.segment.name) + ".".join(entry.object_path.suffixes[:-1])) self._write_symbol(path_cname, ".") diff --git a/tools/splat/segtypes/n64/c.py b/tools/splat/segtypes/n64/c.py index d08be146bf..0a1f63525f 100644 --- a/tools/splat/segtypes/n64/c.py +++ b/tools/splat/segtypes/n64/c.py @@ -5,7 +5,7 @@ import os import re from pathlib import Path -from util import options +from util import log, options class N64SegC(N64SegCodeSubsegment): @@ -175,4 +175,4 @@ class N64SegC(N64SegCodeSubsegment): Path(c_path).parent.mkdir(parents=True, exist_ok=True) with open(c_path, "w") as f: f.write("\n".join(c_lines)) - print(f"Wrote {self.name} to {c_path}") + log.write(f"Wrote {self.name} to {c_path}") diff --git a/tools/splat/segtypes/n64/codesubsegment.py b/tools/splat/segtypes/n64/codesubsegment.py index 22af28063a..5b02129b3a 100644 --- a/tools/splat/segtypes/n64/codesubsegment.py +++ b/tools/splat/segtypes/n64/codesubsegment.py @@ -77,6 +77,12 @@ class N64SegCodeSubsegment(Segment): op_str = insn.op_str func_addr = insn.address if len(func) == 0 else func[0][0].address + # If this is non-zero, disasm size insns + hard_size = 0 + func_sym = self.parent.get_symbol(func_addr, type="func") + if func_sym and func_sym.size > 4: + hard_size = func_sym.size / 4 + if mnemonic == "move": # Let's get the actual instruction out opcode = insn.bytes[3] & 0b00111111 @@ -116,6 +122,8 @@ class N64SegCodeSubsegment(Segment): func.append((insn, mnemonic, op_str, rom_addr)) rom_addr += 4 + size_remaining = hard_size - len(func) if hard_size > 0 else 0 + if mnemonic == "jr": # Record potential jtbl jumps if op_str != "$ra": @@ -126,10 +134,14 @@ class N64SegCodeSubsegment(Segment): if (label[0] > insn.address and label[1] <= insn.address) or (label[0] <= insn.address and label[1] > insn.address): keep_going = True break - if not keep_going: + if not keep_going and not size_remaining: end_func = True continue + # Stop here if a size was specified and we have disassembled up to the size + if hard_size > 0 and size_remaining == 0: + end_func = True + if i < len(insns) - 1 and self.parent.get_symbol(insns[i + 1].address, local_only=True, type="func", dead=False): end_func = True diff --git a/tools/splat/segtypes/n64/group.py b/tools/splat/segtypes/n64/group.py index dc4bf9f6da..759fefe089 100644 --- a/tools/splat/segtypes/n64/group.py +++ b/tools/splat/segtypes/n64/group.py @@ -157,8 +157,7 @@ class N64SegGroup(N64Segment): end = self.get_next_seg_start(i, segment_yaml["subsegments"]) if isinstance(start, int) and isinstance(prev_start, int) and start < prev_start: - print(f"Error: Code segment {self.name} contains subsegments which are out of ascending rom order (0x{prev_start:X} followed by 0x{start:X})") - sys.exit(1) + log.error(f"Error: Code segment {self.name} contains subsegments which are out of ascending rom order (0x{prev_start:X} followed by 0x{start:X})") vram = None if start != "auto": diff --git a/tools/splat/segtypes/segment.py b/tools/splat/segtypes/segment.py index e05a4782d6..2a9d05770b 100644 --- a/tools/splat/segtypes/segment.py +++ b/tools/splat/segtypes/segment.py @@ -139,8 +139,7 @@ class Segment: if isinstance(self.rom_start, int) and isinstance(self.rom_end, int): if self.rom_start > self.rom_end: - print(f"Error: segments out of order - ({self.name} starts at 0x{self.rom_start:X}, but next segment starts at 0x{self.rom_end:X})") - sys.exit(1) + log.error(f"Error: segments out of order - ({self.name} starts at 0x{self.rom_start:X}, but next segment starts at 0x{self.rom_end:X})") @staticmethod def from_yaml(cls: Type["Segment"], yaml: Union[dict, list], rom_start: RomAddr, rom_end: RomAddr, vram=None): diff --git a/tools/splat/split.py b/tools/splat/split.py index 9f291038da..d4689b9a23 100755 --- a/tools/splat/split.py +++ b/tools/splat/split.py @@ -14,6 +14,8 @@ from util import options from util import symbols from util import palettes +VERSION = "0.7.9" + parser = argparse.ArgumentParser(description="Split a rom given a rom, a config, and output directory") parser.add_argument("config", help="path to a compatible config .yaml file") parser.add_argument("--target", help="path to a file to split (.z64 rom)") @@ -110,6 +112,8 @@ def do_statistics(seg_sizes, rom_bytes, seg_split, seg_cached): def main(config_path, base_dir, target_path, modes, verbose, use_cache=True): global config + log.write(f"splat {VERSION}") + # Load config with open(config_path) as f: config = yaml.load(f.read(), Loader=yaml.SafeLoader) diff --git a/tools/splat/util/n64/Yay0decompress.py b/tools/splat/util/n64/Yay0decompress.py index 4024f99ecb..309c0686a9 100644 --- a/tools/splat/util/n64/Yay0decompress.py +++ b/tools/splat/util/n64/Yay0decompress.py @@ -20,7 +20,7 @@ def setup_lib(): lib = cdll.LoadLibrary(os.path.dirname(os.path.realpath(__file__)) + "/Yay0decompress") return True except Exception: - print(f"Failed to load Yay0decompress, falling back to python method") + print(f"Failed to load C library; falling back to python method") tried_loading = True return False diff --git a/ver/us/asm/data/9D650.data.s b/ver/us/asm/data/9D650.data.s deleted file mode 100644 index a15ebd355b..0000000000 --- a/ver/us/asm/data/9D650.data.s +++ /dev/null @@ -1,6 +0,0 @@ -.include "macro.inc" - -.section .data - -glabel D_801041A0 -.word 0xDF000000, 0x00000000 diff --git a/ver/us/asm/data/9DA58.data.s b/ver/us/asm/data/9DA58.data.s deleted file mode 100644 index fe9f39865b..0000000000 --- a/ver/us/asm/data/9DA58.data.s +++ /dev/null @@ -1,6 +0,0 @@ -.include "macro.inc" - -.section .data - -glabel D_801045A8 -.word 0xDF000000, 0x00000000 diff --git a/ver/us/splat.yaml b/ver/us/splat.yaml index 8e9b65a0c8..eb33be902e 100644 --- a/ver/us/splat.yaml +++ b/ver/us/splat.yaml @@ -682,10 +682,14 @@ segments: - [0x9D410, ci4, ui/orb_red, 32, 32] - [0x9D610, palette, ui/orb_red] - [0x9D630, palette, ui/orb_red.disabled] - - [0x9D650, data] - - [0x9D658, rgba32, ui/stat_heart, 16, 16] - - [0x9DA58, data] - - [0x9DA60, rgba32, ui/stat_flower, 16, 16] + - start: 0x9D650 # TODO: The images before this (just above) should probably be with these in c + type: .data + name: 9D650 + subsegments: + - [0x9D650, .data, 9D650] + - [0x9D658, rgba32, ui/stat_heart, 16, 16] + - [0x9DA58] + - [0x9DA60, rgba32, ui/stat_flower, 16, 16] - [0x9DE60, data] - [0xA5100] # bss at 8010C920 - type: code @@ -5021,8 +5025,7 @@ segments: - [0x7E7A30, data] - [0x7E8470, data] - [0x7EA340, data] - - [0x7EAA50, data] - - [0x7EACD8, .rodata, 7E73A0] + - [0x7EAA50, .rodata, 7E73A0] - [0x7EAD00, .rodata, 7E7850] - name: mac_00 dir: world/area_mac/mac_00