mirror of
https://github.com/pmret/papermario.git
synced 2024-11-18 00:42:34 +01:00
byte/flag stuff
This commit is contained in:
parent
084a0ab0b6
commit
4e6a401484
@ -1,16 +0,0 @@
|
||||
.set noat # allow manual use of $at
|
||||
.set noreorder # don't insert nops after branches
|
||||
|
||||
|
||||
glabel get_area_byte
|
||||
/* 0DBD50 80145650 3C02800E */ lui $v0, 0x800e
|
||||
/* 0DBD54 80145654 00441021 */ addu $v0, $v0, $a0
|
||||
/* 0DBD58 80145658 8042BF90 */ lb $v0, -0x4070($v0)
|
||||
/* 0DBD5C 8014565C 03E00008 */ jr $ra
|
||||
/* 0DBD60 80145660 00000000 */ nop
|
||||
|
||||
/* 0DBD64 80145664 00000000 */ nop
|
||||
/* 0DBD68 80145668 00000000 */ nop
|
||||
/* 0DBD6C 8014566C 00000000 */ nop
|
||||
|
||||
|
@ -1,26 +0,0 @@
|
||||
.set noat # allow manual use of $at
|
||||
.set noreorder # don't insert nops after branches
|
||||
|
||||
|
||||
glabel get_area_flag
|
||||
/* 0DBCF0 801455F0 0080102D */ daddu $v0, $a0, $zero
|
||||
/* 0DBCF4 801455F4 04410002 */ bgez $v0, .L80145600
|
||||
/* 0DBCF8 801455F8 0040182D */ daddu $v1, $v0, $zero
|
||||
/* 0DBCFC 801455FC 2443001F */ addiu $v1, $v0, 0x1f
|
||||
.L80145600:
|
||||
/* 0DBD00 80145600 00031943 */ sra $v1, $v1, 5
|
||||
/* 0DBD04 80145604 00032140 */ sll $a0, $v1, 5
|
||||
/* 0DBD08 80145608 00442023 */ subu $a0, $v0, $a0
|
||||
/* 0DBD0C 8014560C 00031880 */ sll $v1, $v1, 2
|
||||
/* 0DBD10 80145610 24020001 */ addiu $v0, $zero, 1
|
||||
/* 0DBD14 80145614 3C01800E */ lui $at, 0x800e
|
||||
/* 0DBD18 80145618 00230821 */ addu $at, $at, $v1
|
||||
/* 0DBD1C 8014561C 8C23BF70 */ lw $v1, -0x4090($at)
|
||||
/* 0DBD20 80145620 00821004 */ sllv $v0, $v0, $a0
|
||||
/* 0DBD24 80145624 00621024 */ and $v0, $v1, $v0
|
||||
/* 0DBD28 80145628 54400001 */ bnel $v0, $zero, .L80145630
|
||||
/* 0DBD2C 8014562C 24020001 */ addiu $v0, $zero, 1
|
||||
.L80145630:
|
||||
/* 0DBD30 80145630 03E00008 */ jr $ra
|
||||
/* 0DBD34 80145634 00000000 */ nop
|
||||
|
@ -1,11 +0,0 @@
|
||||
.set noat # allow manual use of $at
|
||||
.set noreorder # don't insert nops after branches
|
||||
|
||||
|
||||
glabel get_global_byte
|
||||
/* 0DBC38 80145538 3C02800E */ lui $v0, 0x800e
|
||||
/* 0DBC3C 8014553C 00441021 */ addu $v0, $v0, $a0
|
||||
/* 0DBC40 80145540 8042BD70 */ lb $v0, -0x4290($v0)
|
||||
/* 0DBC44 80145544 03E00008 */ jr $ra
|
||||
/* 0DBC48 80145548 00000000 */ nop
|
||||
|
@ -1,12 +0,0 @@
|
||||
.set noat # allow manual use of $at
|
||||
.set noreorder # don't insert nops after branches
|
||||
|
||||
|
||||
glabel set_area_byte
|
||||
/* 0DBD38 80145638 3C02800E */ lui $v0, 0x800e
|
||||
/* 0DBD3C 8014563C 2442ACC0 */ addiu $v0, $v0, -0x5340
|
||||
/* 0DBD40 80145640 00822021 */ addu $a0, $a0, $v0
|
||||
/* 0DBD44 80145644 808212D0 */ lb $v0, 0x12d0($a0)
|
||||
/* 0DBD48 80145648 03E00008 */ jr $ra
|
||||
/* 0DBD4C 8014564C A08512D0 */ sb $a1, 0x12d0($a0)
|
||||
|
@ -1,12 +0,0 @@
|
||||
.set noat # allow manual use of $at
|
||||
.set noreorder # don't insert nops after branches
|
||||
|
||||
|
||||
glabel set_global_byte
|
||||
/* 0DBC20 80145520 3C02800E */ lui $v0, 0x800e
|
||||
/* 0DBC24 80145524 2442ACC0 */ addiu $v0, $v0, -0x5340
|
||||
/* 0DBC28 80145528 00822021 */ addu $a0, $a0, $v0
|
||||
/* 0DBC2C 8014552C 808210B0 */ lb $v0, 0x10b0($a0)
|
||||
/* 0DBC30 80145530 03E00008 */ jr $ra
|
||||
/* 0DBC34 80145534 A08510B0 */ sb $a1, 0x10b0($a0)
|
||||
|
@ -1,41 +0,0 @@
|
||||
.set noat # allow manual use of $at
|
||||
.set noreorder # don't insert nops after branches
|
||||
|
||||
|
||||
glabel EnableModel
|
||||
/* 0EDC38 802C9288 27BDFFE0 */ addiu $sp, $sp, -0x20
|
||||
/* 0EDC3C 802C928C AFB10014 */ sw $s1, 0x14($sp)
|
||||
/* 0EDC40 802C9290 0080882D */ daddu $s1, $a0, $zero
|
||||
/* 0EDC44 802C9294 AFBF0018 */ sw $ra, 0x18($sp)
|
||||
/* 0EDC48 802C9298 AFB00010 */ sw $s0, 0x10($sp)
|
||||
/* 0EDC4C 802C929C 8E30000C */ lw $s0, 0xc($s1)
|
||||
/* 0EDC50 802C92A0 8E050000 */ lw $a1, ($s0)
|
||||
/* 0EDC54 802C92A4 0C0B1EAF */ jal get_variable
|
||||
/* 0EDC58 802C92A8 26100004 */ addiu $s0, $s0, 4
|
||||
/* 0EDC5C 802C92AC 0C046C04 */ jal get_model_list_index_from_tree_index
|
||||
/* 0EDC60 802C92B0 0040202D */ daddu $a0, $v0, $zero
|
||||
/* 0EDC64 802C92B4 0220202D */ daddu $a0, $s1, $zero
|
||||
/* 0EDC68 802C92B8 8E050000 */ lw $a1, ($s0)
|
||||
/* 0EDC6C 802C92BC 0C0B1EAF */ jal get_variable
|
||||
/* 0EDC70 802C92C0 0040802D */ daddu $s0, $v0, $zero
|
||||
/* 0EDC74 802C92C4 0200202D */ daddu $a0, $s0, $zero
|
||||
/* 0EDC78 802C92C8 0C046B4C */ jal get_model_from_list_index
|
||||
/* 0EDC7C 802C92CC 0040802D */ daddu $s0, $v0, $zero
|
||||
/* 0EDC80 802C92D0 12000004 */ beqz $s0, .L802C92E4
|
||||
/* 0EDC84 802C92D4 0040182D */ daddu $v1, $v0, $zero
|
||||
/* 0EDC88 802C92D8 94620000 */ lhu $v0, ($v1)
|
||||
/* 0EDC8C 802C92DC 080B24BB */ j .L802C92EC
|
||||
/* 0EDC90 802C92E0 3042FFFD */ andi $v0, $v0, 0xfffd
|
||||
|
||||
.L802C92E4:
|
||||
/* 0EDC94 802C92E4 94620000 */ lhu $v0, ($v1)
|
||||
/* 0EDC98 802C92E8 34420002 */ ori $v0, $v0, 2
|
||||
.L802C92EC:
|
||||
/* 0EDC9C 802C92EC A4620000 */ sh $v0, ($v1)
|
||||
/* 0EDCA0 802C92F0 8FBF0018 */ lw $ra, 0x18($sp)
|
||||
/* 0EDCA4 802C92F4 8FB10014 */ lw $s1, 0x14($sp)
|
||||
/* 0EDCA8 802C92F8 8FB00010 */ lw $s0, 0x10($sp)
|
||||
/* 0EDCAC 802C92FC 24020002 */ addiu $v0, $zero, 2
|
||||
/* 0EDCB0 802C9300 03E00008 */ jr $ra
|
||||
/* 0EDCB4 802C9304 27BD0020 */ addiu $sp, $sp, 0x20
|
||||
|
@ -1,38 +0,0 @@
|
||||
.set noat # allow manual use of $at
|
||||
.set noreorder # don't insert nops after branches
|
||||
|
||||
|
||||
glabel GetModelCenter
|
||||
/* 0ED930 802C8F80 27BDFFC0 */ addiu $sp, $sp, -0x40
|
||||
/* 0ED934 802C8F84 AFB00038 */ sw $s0, 0x38($sp)
|
||||
/* 0ED938 802C8F88 0080802D */ daddu $s0, $a0, $zero
|
||||
/* 0ED93C 802C8F8C AFBF003C */ sw $ra, 0x3c($sp)
|
||||
/* 0ED940 802C8F90 8E02000C */ lw $v0, 0xc($s0)
|
||||
/* 0ED944 802C8F94 0C0B1EAF */ jal get_variable
|
||||
/* 0ED948 802C8F98 8C450000 */ lw $a1, ($v0)
|
||||
/* 0ED94C 802C8F9C 3044FFFF */ andi $a0, $v0, 0xffff
|
||||
/* 0ED950 802C8FA0 27A50020 */ addiu $a1, $sp, 0x20
|
||||
/* 0ED954 802C8FA4 27A2002C */ addiu $v0, $sp, 0x2c
|
||||
/* 0ED958 802C8FA8 AFA20010 */ sw $v0, 0x10($sp)
|
||||
/* 0ED95C 802C8FAC 27A20030 */ addiu $v0, $sp, 0x30
|
||||
/* 0ED960 802C8FB0 AFA20014 */ sw $v0, 0x14($sp)
|
||||
/* 0ED964 802C8FB4 27A20034 */ addiu $v0, $sp, 0x34
|
||||
/* 0ED968 802C8FB8 27A60024 */ addiu $a2, $sp, 0x24
|
||||
/* 0ED96C 802C8FBC 27A70028 */ addiu $a3, $sp, 0x28
|
||||
/* 0ED970 802C8FC0 0C046C3B */ jal get_model_center_and_size
|
||||
/* 0ED974 802C8FC4 AFA20018 */ sw $v0, 0x18($sp)
|
||||
/* 0ED978 802C8FC8 C7A00020 */ lwc1 $f0, 0x20($sp)
|
||||
/* 0ED97C 802C8FCC 4600010D */ trunc.w.s $f4, $f0
|
||||
/* 0ED980 802C8FD0 E6040084 */ swc1 $f4, 0x84($s0)
|
||||
/* 0ED984 802C8FD4 C7A00024 */ lwc1 $f0, 0x24($sp)
|
||||
/* 0ED988 802C8FD8 C7A20028 */ lwc1 $f2, 0x28($sp)
|
||||
/* 0ED98C 802C8FDC 4600010D */ trunc.w.s $f4, $f0
|
||||
/* 0ED990 802C8FE0 E6040088 */ swc1 $f4, 0x88($s0)
|
||||
/* 0ED994 802C8FE4 4600110D */ trunc.w.s $f4, $f2
|
||||
/* 0ED998 802C8FE8 E604008C */ swc1 $f4, 0x8c($s0)
|
||||
/* 0ED99C 802C8FEC 8FBF003C */ lw $ra, 0x3c($sp)
|
||||
/* 0ED9A0 802C8FF0 8FB00038 */ lw $s0, 0x38($sp)
|
||||
/* 0ED9A4 802C8FF4 24020002 */ addiu $v0, $zero, 2
|
||||
/* 0ED9A8 802C8FF8 03E00008 */ jr $ra
|
||||
/* 0ED9AC 802C8FFC 27BD0040 */ addiu $sp, $sp, 0x40
|
||||
|
328
diff.py
328
diff.py
@ -1,48 +1,71 @@
|
||||
#!/usr/bin/env python3
|
||||
import sys
|
||||
import re
|
||||
import os
|
||||
import ast
|
||||
import argparse
|
||||
import subprocess
|
||||
import collections
|
||||
import difflib
|
||||
import string
|
||||
import itertools
|
||||
import threading
|
||||
import queue
|
||||
import time
|
||||
|
||||
|
||||
def fail(msg):
|
||||
print(msg, file=sys.stderr)
|
||||
sys.exit(1)
|
||||
|
||||
|
||||
MISSING_PREREQUISITES = (
|
||||
"Missing prerequisite python module {}. "
|
||||
"Run `python3 -m pip install --user colorama ansiwrap attrs watchdog python-Levenshtein cxxfilt` to install prerequisites (cxxfilt only needed with --source)."
|
||||
)
|
||||
|
||||
try:
|
||||
import attr
|
||||
from colorama import Fore, Style, Back
|
||||
import ansiwrap
|
||||
import watchdog
|
||||
except ModuleNotFoundError as e:
|
||||
fail(MISSING_PREREQUISITES.format(e.name))
|
||||
|
||||
# Prefer to use diff_settings.py from the current working directory
|
||||
sys.path.insert(0, ".")
|
||||
try:
|
||||
import diff_settings
|
||||
except ModuleNotFoundError:
|
||||
fail("Unable to find diff_settings.py in the same directory.")
|
||||
sys.path.pop(0)
|
||||
|
||||
# ==== CONFIG ====
|
||||
# ==== COMMAND-LINE ====
|
||||
|
||||
try:
|
||||
import argcomplete # type: ignore
|
||||
except ModuleNotFoundError:
|
||||
argcomplete = None
|
||||
import argparse
|
||||
|
||||
parser = argparse.ArgumentParser(description="Diff MIPS assembly.")
|
||||
parser.add_argument("start", help="Function name or address to start diffing from.")
|
||||
|
||||
start_argument = parser.add_argument("start", help="Function name or address to start diffing from.")
|
||||
if argcomplete:
|
||||
def complete_symbol(**kwargs):
|
||||
prefix = kwargs["prefix"]
|
||||
if prefix == "":
|
||||
# skip reading the map file, which would
|
||||
# result in a lot of useless completions
|
||||
return []
|
||||
parsed_args = kwargs["parsed_args"]
|
||||
config = {}
|
||||
diff_settings.apply(config, parsed_args)
|
||||
mapfile = config.get("mapfile")
|
||||
if not mapfile:
|
||||
return []
|
||||
completes = []
|
||||
with open(mapfile) as f:
|
||||
data = f.read()
|
||||
# assume symbols are prefixed by a space character
|
||||
search = f" {prefix}"
|
||||
pos = data.find(search)
|
||||
while pos != -1:
|
||||
# skip the space character in the search string
|
||||
pos += 1
|
||||
# assume symbols are suffixed by either a space
|
||||
# character or a (unix-style) line return
|
||||
spacePos = data.find(" ", pos)
|
||||
lineReturnPos = data.find("\n", pos)
|
||||
if lineReturnPos == -1:
|
||||
endPos = spacePos
|
||||
elif spacePos == -1:
|
||||
endPos = lineReturnPos
|
||||
else:
|
||||
endPos = min(spacePos, lineReturnPos)
|
||||
if endPos == -1:
|
||||
match = data[pos:]
|
||||
pos = -1
|
||||
else:
|
||||
match = data[pos:endPos]
|
||||
pos = data.find(search, endPos)
|
||||
completes.append(match)
|
||||
return completes
|
||||
start_argument.completer = complete_symbol
|
||||
|
||||
parser.add_argument("end", nargs="?", help="Address to end diff at.")
|
||||
parser.add_argument(
|
||||
"-o",
|
||||
@ -52,6 +75,7 @@ parser.add_argument(
|
||||
)
|
||||
parser.add_argument(
|
||||
"-e",
|
||||
"--elf",
|
||||
dest="diff_elf_symbol",
|
||||
help="Diff a given function in two ELFs, one being stripped and the other one non-stripped. Requires objdump from binutils 2.33+.",
|
||||
)
|
||||
@ -132,6 +156,14 @@ parser.add_argument(
|
||||
help="Automatically update when source/object files change. "
|
||||
"Recommended in combination with -m.",
|
||||
)
|
||||
parser.add_argument(
|
||||
"-3",
|
||||
"--threeway",
|
||||
dest="threeway",
|
||||
action="store_true",
|
||||
help="Show a three-way diff between target asm, current asm, and asm "
|
||||
"prior to -w rebuild. Requires -w.",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--width",
|
||||
dest="column_width",
|
||||
@ -146,7 +178,6 @@ parser.add_argument(
|
||||
choices=["levenshtein", "difflib"],
|
||||
help="Diff algorithm to use.",
|
||||
)
|
||||
|
||||
parser.add_argument(
|
||||
"--max-size",
|
||||
"--max-lines",
|
||||
@ -158,12 +189,44 @@ parser.add_argument(
|
||||
|
||||
# Project-specific flags, e.g. different versions/make arguments.
|
||||
if hasattr(diff_settings, "add_custom_arguments"):
|
||||
diff_settings.add_custom_arguments(parser)
|
||||
diff_settings.add_custom_arguments(parser) # type: ignore
|
||||
|
||||
if argcomplete:
|
||||
argcomplete.autocomplete(parser)
|
||||
|
||||
# ==== IMPORTS ====
|
||||
|
||||
import re
|
||||
import os
|
||||
import ast
|
||||
import subprocess
|
||||
import difflib
|
||||
import string
|
||||
import itertools
|
||||
import threading
|
||||
import queue
|
||||
import time
|
||||
from typing import Any, Dict, List, NamedTuple, Optional, Set, Tuple, Union
|
||||
|
||||
|
||||
MISSING_PREREQUISITES = (
|
||||
"Missing prerequisite python module {}. "
|
||||
"Run `python3 -m pip install --user colorama ansiwrap watchdog python-Levenshtein cxxfilt` to install prerequisites (cxxfilt only needed with --source)."
|
||||
)
|
||||
|
||||
try:
|
||||
from colorama import Fore, Style, Back # type: ignore
|
||||
import ansiwrap # type: ignore
|
||||
import watchdog # type: ignore
|
||||
except ModuleNotFoundError as e:
|
||||
fail(MISSING_PREREQUISITES.format(e.name))
|
||||
|
||||
# ==== CONFIG ====
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
# Set imgs, map file and make flags in a project-specific manner.
|
||||
config = {}
|
||||
config: Dict[str, Any] = {}
|
||||
diff_settings.apply(config, args)
|
||||
|
||||
arch = config.get("arch", "mips")
|
||||
@ -199,13 +262,13 @@ FS_WATCH_EXTENSIONS = [".c", ".h"]
|
||||
|
||||
if args.algorithm == "levenshtein":
|
||||
try:
|
||||
import Levenshtein
|
||||
import Levenshtein # type: ignore
|
||||
except ModuleNotFoundError as e:
|
||||
fail(MISSING_PREREQUISITES.format(e.name))
|
||||
|
||||
if args.source:
|
||||
try:
|
||||
import cxxfilt
|
||||
import cxxfilt # type: ignore
|
||||
except ModuleNotFoundError as e:
|
||||
fail(MISSING_PREREQUISITES.format(e.name))
|
||||
|
||||
@ -538,22 +601,21 @@ def process_mips_reloc(row, prev):
|
||||
return before + repl + after
|
||||
|
||||
|
||||
def cleanup_whitespace(line):
|
||||
return "".join(f"{o:<8s}" for o in line.strip().split("\t"))
|
||||
def pad_mnemonic(line):
|
||||
if "\t" not in line:
|
||||
return line
|
||||
mn, args = line.split("\t", 1)
|
||||
return f"{mn:<7s} {args}"
|
||||
|
||||
|
||||
Line = collections.namedtuple(
|
||||
"Line",
|
||||
[
|
||||
"mnemonic",
|
||||
"diff_row",
|
||||
"original",
|
||||
"line_num",
|
||||
"branch_target",
|
||||
"source_lines",
|
||||
"comment",
|
||||
],
|
||||
)
|
||||
class Line(NamedTuple):
|
||||
mnemonic: str
|
||||
diff_row: str
|
||||
original: str
|
||||
line_num: str
|
||||
branch_target: Optional[str]
|
||||
source_lines: List[str]
|
||||
comment: Optional[str]
|
||||
|
||||
|
||||
def process(lines):
|
||||
@ -565,6 +627,7 @@ def process(lines):
|
||||
lines.pop()
|
||||
|
||||
output = []
|
||||
stop_after_delay_slot = False
|
||||
for row in lines:
|
||||
if args.diff_obj and (">:" in row or not row):
|
||||
continue
|
||||
@ -634,18 +697,15 @@ def process(lines):
|
||||
source_lines = []
|
||||
|
||||
if args.stop_jrra and mnemonic == "jr" and row_parts[1].strip() == "ra":
|
||||
stop_after_delay_slot = True
|
||||
elif stop_after_delay_slot:
|
||||
break
|
||||
|
||||
# Cleanup whitespace, after relocation fixups have happened
|
||||
output = [
|
||||
line._replace(original=cleanup_whitespace(line.original)) for line in output
|
||||
]
|
||||
|
||||
return output
|
||||
|
||||
|
||||
def format_single_line_diff(line1, line2, column_width):
|
||||
return f"{ansi_ljust(line1,column_width)}{ansi_ljust(line2,column_width)}"
|
||||
return f"{ansi_ljust(line1,column_width)}{line2}"
|
||||
|
||||
|
||||
class SymbolColorer:
|
||||
@ -743,11 +803,27 @@ def diff_sequences(seq1, seq2):
|
||||
return Levenshtein.opcodes(seq1, seq2)
|
||||
|
||||
|
||||
def do_diff(basedump, mydump):
|
||||
output = []
|
||||
class OutputLine:
|
||||
base: Optional[str]
|
||||
fmt2: str
|
||||
key2: str
|
||||
|
||||
# TODO: status line?
|
||||
# output.append(sha1sum(mydump))
|
||||
def __init__(self, base: Optional[str], fmt2: str, key2: str) -> None:
|
||||
self.base = base
|
||||
self.fmt2 = fmt2
|
||||
self.key2 = key2
|
||||
|
||||
def __eq__(self, other: object) -> bool:
|
||||
if not isinstance(other, OutputLine):
|
||||
return NotImplemented
|
||||
return self.key2 == other.key2
|
||||
|
||||
def __hash__(self) -> int:
|
||||
return hash(self.key2)
|
||||
|
||||
|
||||
def do_diff(basedump: str, mydump: str) -> List[OutputLine]:
|
||||
output: List[OutputLine] = []
|
||||
|
||||
lines1 = process(basedump.split("\n"))
|
||||
lines2 = process(mydump.split("\n"))
|
||||
@ -758,8 +834,8 @@ def do_diff(basedump, mydump):
|
||||
sc4 = SymbolColorer(4)
|
||||
sc5 = SymbolColorer(0)
|
||||
sc6 = SymbolColorer(0)
|
||||
bts1 = set()
|
||||
bts2 = set()
|
||||
bts1: Set[str] = set()
|
||||
bts2: Set[str] = set()
|
||||
|
||||
if args.show_branches:
|
||||
for (lines, btset, sc) in [
|
||||
@ -856,40 +932,36 @@ def do_diff(basedump, mydump):
|
||||
out2 = line2.original
|
||||
elif line1:
|
||||
line_prefix = "<"
|
||||
line_color1 = line_color2 = sym_color = Fore.RED
|
||||
line_color1 = sym_color = Fore.RED
|
||||
out1 = line1.original
|
||||
out2 = ""
|
||||
elif line2:
|
||||
line_prefix = ">"
|
||||
line_color1 = line_color2 = sym_color = Fore.GREEN
|
||||
line_color2 = sym_color = Fore.GREEN
|
||||
out1 = ""
|
||||
out2 = line2.original
|
||||
|
||||
in_arrow1 = " "
|
||||
in_arrow2 = " "
|
||||
out_arrow1 = ""
|
||||
out_arrow2 = ""
|
||||
|
||||
if args.show_branches and line1:
|
||||
if line1.line_num in bts1:
|
||||
in_arrow1 = sc5.color_symbol(line1.line_num, "~>") + line_color1
|
||||
if line1.branch_target is not None:
|
||||
out_arrow1 = " " + sc5.color_symbol(line1.branch_target + ":", "~>")
|
||||
if args.show_branches and line2:
|
||||
if line2.line_num in bts2:
|
||||
in_arrow2 = sc6.color_symbol(line2.line_num, "~>") + line_color2
|
||||
if line2.branch_target is not None:
|
||||
out_arrow2 = " " + sc6.color_symbol(line2.branch_target + ":", "~>")
|
||||
|
||||
if args.source and line2 and line2.comment:
|
||||
out2 += f" {line2.comment}"
|
||||
|
||||
line_num1 = line1.line_num if line1 else ""
|
||||
line_num2 = line2.line_num if line2 else ""
|
||||
def format_part(out: str, line: Optional[Line], line_color: str, btset: Set[str], sc: SymbolColorer) -> Optional[str]:
|
||||
if line is None:
|
||||
return None
|
||||
in_arrow = " "
|
||||
out_arrow = ""
|
||||
if args.show_branches:
|
||||
if line.line_num in btset:
|
||||
in_arrow = sc.color_symbol(line.line_num, "~>") + line_color
|
||||
if line.branch_target is not None:
|
||||
out_arrow = " " + sc.color_symbol(line.branch_target + ":", "~>")
|
||||
out = pad_mnemonic(out)
|
||||
return f"{line_color}{line.line_num} {in_arrow} {out}{Style.RESET_ALL}{out_arrow}"
|
||||
|
||||
out1 = f"{line_color1}{line_num1} {in_arrow1} {out1}{Style.RESET_ALL}{out_arrow1}"
|
||||
out2 = f"{line_color2}{line_num2} {in_arrow2} {out2}{Style.RESET_ALL}{out_arrow2}"
|
||||
mid = f"{sym_color}{line_prefix} "
|
||||
part1 = format_part(out1, line1, line_color1, bts1, sc5)
|
||||
part2 = format_part(out2, line2, line_color2, bts2, sc6)
|
||||
key2 = line2.original if line2 else ""
|
||||
|
||||
mid = f"{sym_color}{line_prefix}"
|
||||
|
||||
if line2:
|
||||
for source_line in line2.source_lines:
|
||||
@ -907,22 +979,82 @@ def do_diff(basedump, mydump):
|
||||
)
|
||||
except:
|
||||
pass
|
||||
output.append(
|
||||
format_single_line_diff(
|
||||
"",
|
||||
f" {color}{source_line}{Style.RESET_ALL}",
|
||||
args.column_width,
|
||||
)
|
||||
)
|
||||
output.append(OutputLine(None, f" {color}{source_line}{Style.RESET_ALL}", source_line))
|
||||
|
||||
output.append(format_single_line_diff(out1, mid + out2, args.column_width))
|
||||
fmt2 = mid + " " + (part2 or "")
|
||||
output.append(OutputLine(part1, fmt2, key2))
|
||||
|
||||
return output[args.skip_lines :]
|
||||
return output
|
||||
|
||||
|
||||
def chunk_diff(diff: List[OutputLine]) -> List[Union[List[OutputLine], OutputLine]]:
|
||||
cur_right: List[OutputLine] = []
|
||||
chunks: List[Union[List[OutputLine], OutputLine]] = []
|
||||
for output_line in diff:
|
||||
if output_line.base is not None:
|
||||
chunks.append(cur_right)
|
||||
chunks.append(output_line)
|
||||
cur_right = []
|
||||
else:
|
||||
cur_right.append(output_line)
|
||||
chunks.append(cur_right)
|
||||
return chunks
|
||||
|
||||
|
||||
def format_diff(old_diff: List[OutputLine], new_diff: List[OutputLine]) -> Tuple[str, List[str]]:
|
||||
old_chunks = chunk_diff(old_diff)
|
||||
new_chunks = chunk_diff(new_diff)
|
||||
output: List[Tuple[str, OutputLine, OutputLine]] = []
|
||||
assert len(old_chunks) == len(new_chunks), "same target"
|
||||
empty = OutputLine("", "", "")
|
||||
for old_chunk, new_chunk in zip(old_chunks, new_chunks):
|
||||
if isinstance(old_chunk, list):
|
||||
assert isinstance(new_chunk, list)
|
||||
if not old_chunk and not new_chunk:
|
||||
# Most of the time lines sync up without insertions/deletions,
|
||||
# and there's no interdiffing to be done.
|
||||
continue
|
||||
differ = difflib.SequenceMatcher(a=old_chunk, b=new_chunk, autojunk=False)
|
||||
for (tag, i1, i2, j1, j2) in differ.get_opcodes():
|
||||
if tag in ["equal", "replace"]:
|
||||
for i, j in zip(range(i1, i2), range(j1, j2)):
|
||||
output.append(("", old_chunk[i], new_chunk[j]))
|
||||
elif tag == "insert":
|
||||
for j in range(j1, j2):
|
||||
output.append(("", empty, new_chunk[j]))
|
||||
else:
|
||||
for i in range(i1, i2):
|
||||
output.append(("", old_chunk[i], empty))
|
||||
else:
|
||||
assert isinstance(new_chunk, OutputLine)
|
||||
# old_chunk.base and new_chunk.base have the same text since
|
||||
# both diffs are based on the same target, but they might
|
||||
# differ in color. Use the new version.
|
||||
output.append((new_chunk.base or "", old_chunk, new_chunk))
|
||||
|
||||
# TODO: status line, with e.g. approximate permuter score?
|
||||
width = args.column_width
|
||||
if args.threeway:
|
||||
header_line = "TARGET".ljust(width) + " CURRENT".ljust(width) + " PREVIOUS"
|
||||
diff_lines = [
|
||||
ansi_ljust(base, width)
|
||||
+ ansi_ljust(new.fmt2, width)
|
||||
+ (old.fmt2 or "-" if old != new else "")
|
||||
for (base, old, new) in output
|
||||
]
|
||||
else:
|
||||
header_line = ""
|
||||
diff_lines = [
|
||||
ansi_ljust(base, width) + new.fmt2
|
||||
for (base, old, new) in output
|
||||
if base or new.key2
|
||||
]
|
||||
return header_line, diff_lines
|
||||
|
||||
|
||||
def debounced_fs_watch(targets, outq, debounce_delay):
|
||||
import watchdog.events
|
||||
import watchdog.observers
|
||||
import watchdog.events # type: ignore
|
||||
import watchdog.observers # type: ignore
|
||||
|
||||
class WatchEventHandler(watchdog.events.FileSystemEventHandler):
|
||||
def __init__(self, queue, file_targets):
|
||||
@ -993,12 +1125,18 @@ class Display:
|
||||
self.basedump = basedump
|
||||
self.mydump = mydump
|
||||
self.emsg = None
|
||||
self.last_diff_output = None
|
||||
|
||||
def run_less(self):
|
||||
if self.emsg is not None:
|
||||
output = self.emsg
|
||||
else:
|
||||
output = "\n".join(do_diff(self.basedump, self.mydump))
|
||||
diff_output = do_diff(self.basedump, self.mydump)
|
||||
last_diff_output = self.last_diff_output or diff_output
|
||||
self.last_diff_output = diff_output
|
||||
header, diff_lines = format_diff(last_diff_output, diff_output)
|
||||
header_lines = [header] if header else []
|
||||
output = "\n".join(header_lines + diff_lines[args.skip_lines :])
|
||||
|
||||
# Pipe the output through 'tail' and only then to less, to ensure the
|
||||
# write call doesn't block. ('tail' has to buffer all its input before
|
||||
|
@ -1429,4 +1429,33 @@ typedef struct EncounterStatus {
|
||||
/* 0x98 */ s32 unk_98;
|
||||
} EncounterStatus; // size = 0x9C
|
||||
|
||||
typedef struct SaveData {
|
||||
/* 0x0000 */ char magicString[16]; /* "Mario Story 006" string */
|
||||
/* 0x0010 */ s8 pad[32]; /* always zero */
|
||||
/* 0x0030 */ s32 crc1;
|
||||
/* 0x0034 */ s32 crc2;
|
||||
/* 0x0038 */ s32 saveSlot;
|
||||
/* 0x003C */ s32 saveCount;
|
||||
/* 0x0040 */ struct PlayerData player;
|
||||
/* 0x0380 */ char unk_380[0xE0];
|
||||
/* 0x0460 */ s32 starPoints;
|
||||
/* 0x0464 */ char unk_464[4];
|
||||
/* 0x0468 */ s16 areaID;
|
||||
/* 0x046A */ s16 mapID;
|
||||
/* 0x046C */ s16 entryID;
|
||||
/* 0x046E */ char unk_46E[2];
|
||||
/* 0x0470 */ s32 enemyDefeatFlags[720];
|
||||
/* 0x0FB0 */ s8 globalFlags[256];
|
||||
/* 0x10B0 */ s8 globalBytes[512];
|
||||
/* 0x12B0 */ s32 areaFlags[8];
|
||||
/* 0x12D0 */ s8 areaBytes[16];
|
||||
/* 0x12E0 */ char unk_12E0[6];
|
||||
/* 0x12E6 */ s16 savePos[3];
|
||||
/* 0x12EC */ s32 unk_12EC;
|
||||
/* 0x12F0 */ s8 unk_12F0[12]; /* player name starts at 4th char */
|
||||
/* 0x12FC */ s32 unk_12FC;
|
||||
/* 0x1300 */ s32 unk_1300;
|
||||
/* 0x1304 */ char unk_1304[0x7C];
|
||||
} SaveData; // size = 0x1380
|
||||
|
||||
#endif
|
||||
|
@ -10,8 +10,14 @@ void osCleanupThread(void);
|
||||
s32 heap_malloc(s32 size);
|
||||
HeapNode* _heap_create(void* addr, s32 size);
|
||||
|
||||
s8 get_global_byte(s32 index);
|
||||
s32 get_global_flag(s32 index);
|
||||
s8 get_area_byte(s32 index);
|
||||
s32 get_area_flag(s32 index);
|
||||
|
||||
void clone_model(u16 srcModelID, u16 newModelID);
|
||||
Model* get_model_from_list_index(s32 listIndex);
|
||||
void get_model_center_and_size(s32 modelID, f32* centerX, f32* centerY, f32* centerZ, f32* sizeX, f32* sizeY, f32* sizeZ);
|
||||
|
||||
void update_collider_transform(s16 colliderID);
|
||||
void get_collider_center(s32 colliderID, f32* x, f32* y, f32* z);
|
||||
|
@ -92,4 +92,9 @@ extern UNK_TYPE D_80108558;
|
||||
extern UNK_TYPE D_8010F250; // play_sound state struct?
|
||||
extern s8 D_8010EBB0;
|
||||
|
||||
extern SaveData gCurrentSaveFile;
|
||||
|
||||
extern u32* gMapFlags;
|
||||
extern u32* gMapVars;
|
||||
|
||||
#endif
|
||||
|
@ -191,7 +191,7 @@ INCLUDE_ASM("code_a5dd0_len_114e0", get_model_list_index_from_tree_index);
|
||||
|
||||
INCLUDE_ASM("code_a5dd0_len_114e0", func_8011B090);
|
||||
|
||||
INCLUDE_ASM("code_a5dd0_len_114e0", get_model_center_and_size);
|
||||
void INCLUDE_ASM("code_a5dd0_len_114e0", get_model_center_and_size, s32 modelID, f32* centerX, f32* centerY, f32* centerZ, f32* sizeX, f32* sizeY, f32* sizeZ);
|
||||
|
||||
INCLUDE_ASM("code_a5dd0_len_114e0", func_8011B1C0);
|
||||
|
||||
|
@ -7,19 +7,104 @@ INCLUDE_ASM("code_dba20_len_350", clear_area_flags);
|
||||
INCLUDE_ASM("code_dba20_len_350", clear_global_flag);
|
||||
|
||||
INCLUDE_ASM("code_dba20_len_350", set_global_flag);
|
||||
/*s32 set_global_flag(s32 index) {
|
||||
//SaveData* saveFile = &gCurrentSaveFile;
|
||||
s32 flag;
|
||||
|
||||
INCLUDE_ASM("code_dba20_len_350", get_global_flag);
|
||||
if (index <= -120000000) {
|
||||
index += 130000000;
|
||||
}
|
||||
|
||||
INCLUDE_ASM("code_dba20_len_350", set_global_byte);
|
||||
flag = gCurrentSaveFile->globalFlags[index / 32] & (1 << (index % 32));
|
||||
|
||||
INCLUDE_ASM("code_dba20_len_350", get_global_byte);
|
||||
if (flag) {
|
||||
flag = 1;
|
||||
}
|
||||
|
||||
gCurrentSaveFile->globalFlags[index / 32] |= (1 << (index % 32));
|
||||
return flag;
|
||||
}*/
|
||||
|
||||
s32 INCLUDE_ASM("code_dba20_len_350", get_global_flag, s32 index);
|
||||
/*s32 get_global_flag(s32 index) {
|
||||
s32 bitIdx;
|
||||
s32 wordIdx;
|
||||
s32 bit;
|
||||
s32 phi_return;
|
||||
|
||||
if (index <= -120000000) {
|
||||
index += 130000000;
|
||||
}
|
||||
wordIdx = index / 32;
|
||||
bitIdx = index % 32;
|
||||
bit = gCurrentSaveFile->globalFlags[wordIdx] & (1 << bitIdx);
|
||||
|
||||
if (bit != 0) {
|
||||
bit = 1;
|
||||
}
|
||||
return bit;
|
||||
//return (bit != 0) ? 1 : bit; // ??? surely this is `bit != 0`
|
||||
}*/
|
||||
|
||||
s8 set_global_byte(s32 index, s8 value) {
|
||||
SaveData* saveFile = &gCurrentSaveFile;
|
||||
s32 ret = saveFile->globalBytes[index];
|
||||
|
||||
saveFile->globalBytes[index] = value;
|
||||
return ret;
|
||||
}
|
||||
|
||||
s8 get_global_byte(s32 index) {
|
||||
return gCurrentSaveFile.globalBytes[index];
|
||||
}
|
||||
|
||||
INCLUDE_ASM("code_dba20_len_350", clear_area_flag);
|
||||
|
||||
INCLUDE_ASM("code_dba20_len_350", set_area_flag);
|
||||
/*s32 set_area_flag(s32 index) {
|
||||
SaveData* saveFile = &gCurrentSaveFile;
|
||||
s32 flag;
|
||||
s32 flagIdx;
|
||||
s32 flagShift;
|
||||
|
||||
INCLUDE_ASM("code_dba20_len_350", get_area_flag);
|
||||
flagIdx = index / 32;
|
||||
flagShift = index % 32;
|
||||
|
||||
INCLUDE_ASM("code_dba20_len_350", set_area_byte);
|
||||
flag = saveFile->areaFlags[flagIdx] & (1 << flagShift);
|
||||
|
||||
INCLUDE_ASM("code_dba20_len_350", get_area_byte);
|
||||
if (flag != 0) {
|
||||
flag = 1;
|
||||
}
|
||||
|
||||
saveFile->areaFlags[flagIdx] |= (1 << flagShift);
|
||||
|
||||
return flag;
|
||||
}*/
|
||||
|
||||
s32 get_area_flag(s32 index) {
|
||||
s32 flag;
|
||||
s32 flagIdx;
|
||||
s32 flagShift;
|
||||
|
||||
flagIdx = index / 32;
|
||||
flagShift = index % 32;
|
||||
|
||||
flag = gCurrentSaveFile.areaFlags[flagIdx] & (1 << flagShift);
|
||||
|
||||
if (flag != 0) {
|
||||
flag = 1;
|
||||
}
|
||||
return flag;
|
||||
}
|
||||
|
||||
s8 set_area_byte(s32 index, s8 value) {
|
||||
SaveData* saveFile = &gCurrentSaveFile;
|
||||
s32 ret = saveFile->areaBytes[index];
|
||||
|
||||
saveFile->areaBytes[index] = value;
|
||||
return ret;
|
||||
}
|
||||
|
||||
s8 get_area_byte(s32 index) {
|
||||
return gCurrentSaveFile.areaBytes[index];
|
||||
}
|
||||
|
@ -719,6 +719,57 @@ s32 func_802C73B8(ScriptInstance* script) {
|
||||
INCLUDE_ASM("code_e92d0_len_5da0", si_execute_next_command);
|
||||
|
||||
s32 INCLUDE_ASM("code_e92d0_len_5da0", get_variable, ScriptInstance* script, Bytecode var);
|
||||
// TODO: consider renaming to si_get_variable
|
||||
/*s32 get_variable(ScriptInstance* script, Bytecode var) {
|
||||
s32 abs_value;
|
||||
s32 word_index;
|
||||
s32 bit_index;
|
||||
|
||||
if (var <= -270000000) {
|
||||
return var;
|
||||
} else if (var <= -250000000) {
|
||||
return var;
|
||||
} else if (var <= -220000000) {
|
||||
return (s32) fixed_var_to_float(var);
|
||||
} else if (var <= -200000000) {
|
||||
var += 210000000;
|
||||
word_index = var / 32;
|
||||
bit_index = var % 32;
|
||||
return (script->flagArray[word_index] & (1 << bit_index)) != 0;
|
||||
} else if (var <= -180000000) {
|
||||
var += 190000000;
|
||||
var = script->array[var];
|
||||
return (var > -270000000 && var < -220000000) ? (s32) fixed_var_to_float(var) : var;
|
||||
} else if (var <= -160000000) {
|
||||
return get_global_byte(var + 170000000);
|
||||
} else if (var <= -140000000) {
|
||||
return get_area_byte(var + 150000000);
|
||||
} else if (var <= -120000000) {
|
||||
return get_global_flag(var + 130000000);
|
||||
} else if (var <= -100000000) {
|
||||
return get_area_flag(var + 110000000);
|
||||
} else if (var <= -80000000) {
|
||||
s32 avar = var + 90000000;
|
||||
word_index = avar / 32;
|
||||
bit_index = avar % 32;
|
||||
return (gMapFlags[word_index] & (1 << bit_index)) != 0;
|
||||
} else if (var <= -60000000) {
|
||||
var += 70000000;
|
||||
word_index = var / 32;
|
||||
bit_index = var % 32;
|
||||
return (script->varFlags[word_index] & (1 << bit_index)) != 0;
|
||||
} else if (var <= -40000000) {
|
||||
var += 50000000;
|
||||
var = gMapVars[var];
|
||||
return (var > -270000000 && var < -220000000) ? (s32) fixed_var_to_float(var) : var;
|
||||
} else if (var <= -20000000) {
|
||||
var += 30000000;
|
||||
var = script->varTable[var];
|
||||
return (var > -270000000 && var < -220000000) ? (s32) fixed_var_to_float(var) : var;
|
||||
} else {
|
||||
return var;
|
||||
}
|
||||
}*/
|
||||
|
||||
INCLUDE_ASM("code_e92d0_len_5da0", get_variable_index);
|
||||
|
||||
@ -848,7 +899,21 @@ ApiStatus CloneModel(ScriptInstance* script, s32 isInitialCall) {
|
||||
return ApiStatus_DONE2;
|
||||
}
|
||||
|
||||
INCLUDE_API_ASM("code_e92d0_len_5da0", GetModelCenter);
|
||||
ApiStatus GetModelCenter(ScriptInstance* script, s32 isInitialCall) {
|
||||
Bytecode* thisPos = script->ptrReadPos;
|
||||
f32 centerX;
|
||||
f32 centerY;
|
||||
f32 centerZ;
|
||||
f32 sizeX;
|
||||
f32 sizeY;
|
||||
f32 sizeZ;
|
||||
|
||||
get_model_center_and_size(get_variable(script, *thisPos++) & 0xFFFF, ¢erX, ¢erY, ¢erZ, &sizeX, &sizeY, &sizeZ);
|
||||
script->varTable[0] = centerX;
|
||||
script->varTable[1] = centerY;
|
||||
script->varTable[2] = centerZ;
|
||||
return ApiStatus_DONE2;
|
||||
}
|
||||
|
||||
INCLUDE_API_ASM("code_e92d0_len_5da0", SetTexPanner);
|
||||
|
||||
@ -856,7 +921,20 @@ INCLUDE_API_ASM("code_e92d0_len_5da0", SetModelFlag10);
|
||||
|
||||
INCLUDE_API_ASM("code_e92d0_len_5da0", EnableTexPanning);
|
||||
|
||||
INCLUDE_API_ASM("code_e92d0_len_5da0", EnableModel);
|
||||
ApiStatus EnableModel(ScriptInstance* script, s32 isInitialCall) {
|
||||
Bytecode* thisPos = script->ptrReadPos;
|
||||
Bytecode treeIndex = get_variable(script, *thisPos++);
|
||||
s32 listIndex = get_model_list_index_from_tree_index(treeIndex);
|
||||
Bytecode flag = get_variable(script, *thisPos++);
|
||||
Model* model = get_model_from_list_index(listIndex);
|
||||
|
||||
if (flag != 0) {
|
||||
model->flags &= ~0x2;
|
||||
} else {
|
||||
model->flags |= 0x2;
|
||||
}
|
||||
return ApiStatus_DONE2;
|
||||
}
|
||||
|
||||
ApiStatus SetGroupEnabled(ScriptInstance* script, s32 isInitialCall) {
|
||||
Bytecode* thisPos = script->ptrReadPos;
|
||||
|
@ -112,6 +112,11 @@ gScriptIdList = 0x802D1898;
|
||||
gScriptIndexList = 0x802DAA98;
|
||||
gScriptListCount = 0x802DAC98;
|
||||
|
||||
gCurrentSaveFile = 0x800DACC0;
|
||||
|
||||
gMapFlags = 0x802DA480;
|
||||
gMapVars = 0x802DA484;
|
||||
|
||||
func_802A91F8 = 0x802A91F8;
|
||||
func_802A9208 = 0x802A9208;
|
||||
func_802A9228 = 0x802A9228;
|
||||
|
Loading…
Reference in New Issue
Block a user