saving for later

This commit is contained in:
Ethan Roseman 2020-10-02 02:07:54 -04:00
parent 750312a87c
commit 926df66474
19 changed files with 437 additions and 281 deletions

View File

@ -1,64 +0,0 @@
.set noat # allow manual use of $at
.set noreorder # don't insert nops after branches
glabel is_point_within_region
/* 243D4 80048FD4 44856000 */ mtc1 $a1, $f12
/* 243D8 80048FD8 27BDFFC8 */ addiu $sp, $sp, -0x38
/* 243DC 80048FDC F7B60020 */ sdc1 $f22, 0x20($sp)
/* 243E0 80048FE0 4486B000 */ mtc1 $a2, $f22
/* 243E4 80048FE4 44870000 */ mtc1 $a3, $f0
/* 243E8 80048FE8 F7B80028 */ sdc1 $f24, 0x28($sp)
/* 243EC 80048FEC C7B80048 */ lwc1 $f24, 0x48($sp)
/* 243F0 80048FF0 F7BA0030 */ sdc1 $f26, 0x30($sp)
/* 243F4 80048FF4 C7BA004C */ lwc1 $f26, 0x4c($sp)
/* 243F8 80048FF8 AFBF0010 */ sw $ra, 0x10($sp)
/* 243FC 80048FFC F7B40018 */ sdc1 $f20, 0x18($sp)
/* 24400 80049000 10800005 */ beqz $a0, .L80049018
/* 24404 80049004 24020001 */ addiu $v0, $zero, 1
/* 24408 80049008 1082000D */ beq $a0, $v0, .L80049040
/* 2440C 8004900C 0000102D */ daddu $v0, $zero, $zero
/* 24410 80049010 08012426 */ j .L80049098
/* 24414 80049014 00000000 */ nop
.L80049018:
/* 24418 80049018 44060000 */ mfc1 $a2, $f0
/* 2441C 8004901C 4407C000 */ mfc1 $a3, $f24
/* 24420 80049020 0C00A7B5 */ jal dist2D
/* 24424 80049024 4600B386 */ mov.s $f14, $f22
/* 24428 80049028 4600D03C */ c.lt.s $f26, $f0
/* 2442C 8004902C 00000000 */ nop
/* 24430 80049030 45010019 */ bc1t .L80049098
/* 24434 80049034 24020001 */ addiu $v0, $zero, 1
/* 24438 80049038 08012426 */ j .L80049098
/* 2443C 8004903C 0000102D */ daddu $v0, $zero, $zero
.L80049040:
/* 24440 80049040 4480A000 */ mtc1 $zero, $f20
/* 24444 80049044 44060000 */ mfc1 $a2, $f0
/* 24448 80049048 4407A000 */ mfc1 $a3, $f20
/* 2444C 8004904C 0C00A7B5 */ jal dist2D
/* 24450 80049050 4600A386 */ mov.s $f14, $f20
/* 24454 80049054 4600A306 */ mov.s $f12, $f20
/* 24458 80049058 4600B386 */ mov.s $f14, $f22
/* 2445C 8004905C 44066000 */ mfc1 $a2, $f12
/* 24460 80049060 4407C000 */ mfc1 $a3, $f24
/* 24464 80049064 0C00A7B5 */ jal dist2D
/* 24468 80049068 46000506 */ mov.s $f20, $f0
/* 2446C 8004906C 0000102D */ daddu $v0, $zero, $zero
/* 24470 80049070 4614D03C */ c.lt.s $f26, $f20
/* 24474 80049074 00000000 */ nop
/* 24478 80049078 45010006 */ bc1t .L80049094
/* 2447C 8004907C 46000086 */ mov.s $f2, $f0
/* 24480 80049080 C7A00050 */ lwc1 $f0, 0x50($sp)
/* 24484 80049084 4602003C */ c.lt.s $f0, $f2
/* 24488 80049088 00000000 */ nop
/* 2448C 8004908C 45000002 */ bc1f .L80049098
/* 24490 80049090 00000000 */ nop
.L80049094:
/* 24494 80049094 24020001 */ addiu $v0, $zero, 1
.L80049098:
/* 24498 80049098 8FBF0010 */ lw $ra, 0x10($sp)
/* 2449C 8004909C D7BA0030 */ ldc1 $f26, 0x30($sp)
/* 244A0 800490A0 D7B80028 */ ldc1 $f24, 0x28($sp)
/* 244A4 800490A4 D7B60020 */ ldc1 $f22, 0x20($sp)
/* 244A8 800490A8 D7B40018 */ ldc1 $f20, 0x18($sp)
/* 244AC 800490AC 03E00008 */ jr $ra
/* 244B0 800490B0 27BD0038 */ addiu $sp, $sp, 0x38

View File

@ -1,27 +0,0 @@
.set noat # allow manual use of $at
.set noreorder # don't insert nops after branches
glabel clear_area_flags
/* DBA90 80145390 3C028007 */ lui $v0, %hi(gGameStatusPtr)
/* DBA94 80145394 8C42419C */ lw $v0, %lo(gGameStatusPtr)($v0)
/* DBA98 80145398 8442008A */ lh $v0, 0x8a($v0)
/* DBA9C 8014539C 3C04800E */ lui $a0, %hi(gCurrentSaveFile)
/* DBAA0 801453A0 2484ACC0 */ addiu $a0, $a0, %lo(gCurrentSaveFile)
/* DBAA4 801453A4 1040000C */ beqz $v0, .L801453D8
/* DBAA8 801453A8 24020007 */ addiu $v0, $zero, 7
/* DBAAC 801453AC 2483001C */ addiu $v1, $a0, 0x1c
.L801453B0:
/* DBAB0 801453B0 AC6012B0 */ sw $zero, 0x12b0($v1)
/* DBAB4 801453B4 2442FFFF */ addiu $v0, $v0, -1
/* DBAB8 801453B8 0441FFFD */ bgez $v0, .L801453B0
/* DBABC 801453BC 2463FFFC */ addiu $v1, $v1, -4
/* DBAC0 801453C0 2402000F */ addiu $v0, $zero, 0xf
/* DBAC4 801453C4 00821821 */ addu $v1, $a0, $v0
.L801453C8:
/* DBAC8 801453C8 A06012D0 */ sb $zero, 0x12d0($v1)
/* DBACC 801453CC 2442FFFF */ addiu $v0, $v0, -1
/* DBAD0 801453D0 0441FFFD */ bgez $v0, .L801453C8
/* DBAD4 801453D4 2463FFFF */ addiu $v1, $v1, -1
.L801453D8:
/* DBAD8 801453D8 03E00008 */ jr $ra
/* DBADC 801453DC 00000000 */ nop

View File

@ -1,36 +0,0 @@
.set noat # allow manual use of $at
.set noreorder # don't insert nops after branches
glabel clear_saved_variables
/* DBA20 80145320 2402003F */ addiu $v0, $zero, 0x3f
/* DBA24 80145324 3C04800E */ lui $a0, %hi(gCurrentSaveFile)
/* DBA28 80145328 2484ACC0 */ addiu $a0, $a0, %lo(gCurrentSaveFile)
/* DBA2C 8014532C 248300FC */ addiu $v1, $a0, 0xfc
.L80145330:
/* DBA30 80145330 AC600FB0 */ sw $zero, 0xfb0($v1)
/* DBA34 80145334 2442FFFF */ addiu $v0, $v0, -1
/* DBA38 80145338 0441FFFD */ bgez $v0, .L80145330
/* DBA3C 8014533C 2463FFFC */ addiu $v1, $v1, -4
/* DBA40 80145340 240201FF */ addiu $v0, $zero, 0x1ff
/* DBA44 80145344 00821821 */ addu $v1, $a0, $v0
.L80145348:
/* DBA48 80145348 A06010B0 */ sb $zero, 0x10b0($v1)
/* DBA4C 8014534C 2442FFFF */ addiu $v0, $v0, -1
/* DBA50 80145350 0441FFFD */ bgez $v0, .L80145348
/* DBA54 80145354 2463FFFF */ addiu $v1, $v1, -1
/* DBA58 80145358 24020007 */ addiu $v0, $zero, 7
/* DBA5C 8014535C 2483001C */ addiu $v1, $a0, 0x1c
.L80145360:
/* DBA60 80145360 AC6012B0 */ sw $zero, 0x12b0($v1)
/* DBA64 80145364 2442FFFF */ addiu $v0, $v0, -1
/* DBA68 80145368 0441FFFD */ bgez $v0, .L80145360
/* DBA6C 8014536C 2463FFFC */ addiu $v1, $v1, -4
/* DBA70 80145370 2402000F */ addiu $v0, $zero, 0xf
/* DBA74 80145374 00821821 */ addu $v1, $a0, $v0
.L80145378:
/* DBA78 80145378 A06012D0 */ sb $zero, 0x12d0($v1)
/* DBA7C 8014537C 2442FFFF */ addiu $v0, $v0, -1
/* DBA80 80145380 0441FFFD */ bgez $v0, .L80145378
/* DBA84 80145384 2463FFFF */ addiu $v1, $v1, -1
/* DBA88 80145388 03E00008 */ jr $ra
/* DBA8C 8014538C 00000000 */ nop

View File

@ -1,39 +0,0 @@
.set noat # allow manual use of $at
.set noreorder # don't insert nops after branches
glabel si_handle_call
/* EAD98 802C63E8 27BDFFE0 */ addiu $sp, $sp, -0x20
/* EAD9C 802C63EC AFB10014 */ sw $s1, 0x14($sp)
/* EADA0 802C63F0 0080882D */ daddu $s1, $a0, $zero
/* EADA4 802C63F4 AFBF0018 */ sw $ra, 0x18($sp)
/* EADA8 802C63F8 AFB00010 */ sw $s0, 0x10($sp)
/* EADAC 802C63FC 82220005 */ lb $v0, 5($s1)
/* EADB0 802C6400 8E30000C */ lw $s0, 0xc($s1)
/* EADB4 802C6404 10400004 */ beqz $v0, .L802C6418
/* EADB8 802C6408 0000282D */ daddu $a1, $zero, $zero
/* EADBC 802C640C 8E260080 */ lw $a2, 0x80($s1)
/* EADC0 802C6410 080B1914 */ j .L802C6450
/* EADC4 802C6414 00000000 */ nop
.L802C6418:
/* EADC8 802C6418 8E050000 */ lw $a1, ($s0)
/* EADCC 802C641C 26100004 */ addiu $s0, $s0, 4
/* EADD0 802C6420 0C0B1EAF */ jal get_variable
/* EADD4 802C6424 0220202D */ daddu $a0, $s1, $zero
/* EADD8 802C6428 0220202D */ daddu $a0, $s1, $zero
/* EADDC 802C642C AC820080 */ sw $v0, 0x80($a0)
/* EADE0 802C6430 0040302D */ daddu $a2, $v0, $zero
/* EADE4 802C6434 24050001 */ addiu $a1, $zero, 1
/* EADE8 802C6438 90820001 */ lbu $v0, 1($a0)
/* EADEC 802C643C 00A0182D */ daddu $v1, $a1, $zero
/* EADF0 802C6440 AC90000C */ sw $s0, 0xc($a0)
/* EADF4 802C6444 A0830005 */ sb $v1, 5($a0)
/* EADF8 802C6448 2442FFFF */ addiu $v0, $v0, -1
/* EADFC 802C644C A0820001 */ sb $v0, 1($a0)
.L802C6450:
/* EAE00 802C6450 00C0F809 */ jalr $a2
/* EAE04 802C6454 00000000 */ nop
/* EAE08 802C6458 8FBF0018 */ lw $ra, 0x18($sp)
/* EAE0C 802C645C 8FB10014 */ lw $s1, 0x14($sp)
/* EAE10 802C6460 8FB00010 */ lw $s0, 0x10($sp)
/* EAE14 802C6464 03E00008 */ jr $ra
/* EAE18 802C6468 27BD0020 */ addiu $sp, $sp, 0x20

View File

@ -1,40 +0,0 @@
.set noat # allow manual use of $at
.set noreorder # don't insert nops after branches
glabel si_handle_end_case_group
/* EA00C 802C565C 27BDFFE8 */ addiu $sp, $sp, -0x18
/* EA010 802C5660 AFB00010 */ sw $s0, 0x10($sp)
/* EA014 802C5664 0080802D */ daddu $s0, $a0, $zero
/* EA018 802C5668 AFBF0014 */ sw $ra, 0x14($sp)
/* EA01C 802C566C 82020007 */ lb $v0, 7($s0)
/* EA020 802C5670 04410003 */ bgez $v0, .L802C5680
/* EA024 802C5674 02021821 */ addu $v1, $s0, $v0
.L802C5678:
/* EA028 802C5678 080B159E */ j .L802C5678
/* EA02C 802C567C 00000000 */ nop
.L802C5680:
/* EA030 802C5680 80640110 */ lb $a0, 0x110($v1)
/* EA034 802C5684 14800003 */ bnez $a0, .L802C5694
/* EA038 802C5688 2402FFFF */ addiu $v0, $zero, -1
/* EA03C 802C568C 080B15AD */ j .L802C56B4
/* EA040 802C5690 0200202D */ daddu $a0, $s0, $zero
.L802C5694:
/* EA044 802C5694 10820006 */ beq $a0, $v0, .L802C56B0
/* EA048 802C5698 0200202D */ daddu $a0, $s0, $zero
/* EA04C 802C569C 24020001 */ addiu $v0, $zero, 1
/* EA050 802C56A0 0C0B2298 */ jal si_goto_next_case
/* EA054 802C56A4 A0620110 */ sb $v0, 0x110($v1)
/* EA058 802C56A8 080B15B0 */ j .L802C56C0
/* EA05C 802C56AC AE020008 */ sw $v0, 8($s0)
.L802C56B0:
/* EA060 802C56B0 A0600110 */ sb $zero, 0x110($v1)
.L802C56B4:
/* EA064 802C56B4 0C0B2279 */ jal si_goto_end_case
/* EA068 802C56B8 00000000 */ nop
/* EA06C 802C56BC AE020008 */ sw $v0, 8($s0)
.L802C56C0:
/* EA070 802C56C0 24020002 */ addiu $v0, $zero, 2
/* EA074 802C56C4 8FBF0014 */ lw $ra, 0x14($sp)
/* EA078 802C56C8 8FB00010 */ lw $s0, 0x10($sp)
/* EA07C 802C56CC 03E00008 */ jr $ra
/* EA080 802C56D0 27BD0018 */ addiu $sp, $sp, 0x18

89
diff.py
View File

@ -64,7 +64,7 @@ if argcomplete:
pos = data.find(search, endPos)
completes.append(match)
return completes
start_argument.completer = complete_symbol
setattr(start_argument, "completer", complete_symbol)
parser.add_argument("end", nargs="?", help="Address to end diff at.")
parser.add_argument(
@ -130,6 +130,12 @@ parser.add_argument(
action="store_true",
help="Pretend all large enough immediates are the same.",
)
parser.add_argument(
"-I",
"--ignore-addr-diffs",
action="store_true",
help="Ignore address differences. Currently only affects AArch64.",
)
parser.add_argument(
"-B",
"--no-show-branches",
@ -612,13 +618,82 @@ class Line(NamedTuple):
mnemonic: str
diff_row: str
original: str
normalized_original: str
line_num: str
branch_target: Optional[str]
source_lines: List[str]
comment: Optional[str]
class DifferenceNormalizer:
def normalize(self, mnemonic: str, row: str) -> str:
"""This should be called exactly once for each line."""
row = self._normalize_arch_specific(mnemonic, row)
if args.ignore_large_imms:
row = re.sub(re_large_imm, "<imm>", row)
return row
def _normalize_arch_specific(self, mnemonic: str, row: str) -> str:
return row
class DifferenceNormalizerAArch64(DifferenceNormalizer):
def __init__(self) -> None:
super().__init__()
self._adrp_pair_registers: Set[str] = set()
def _normalize_arch_specific(self, mnemonic: str, row: str) -> str:
if args.ignore_addr_diffs:
row = self._normalize_adrp_differences(mnemonic, row)
row = self._normalize_bl(mnemonic, row)
return row
def _normalize_bl(self, mnemonic: str, row: str) -> str:
if mnemonic != "bl":
return row
row, _ = split_off_branch(row)
return row
def _normalize_adrp_differences(self, mnemonic: str, row: str) -> str:
"""Identifies ADRP + LDR/ADD pairs that are used to access the GOT and
suppresses any immediate differences.
Whenever an ADRP is seen, the destination register is added to the set of registers
that are part of an ADRP + LDR/ADD pair. Registers are removed from the set as soon
as they are used for an LDR or ADD instruction which completes the pair.
This method is somewhat crude but should manage to detect most such pairs.
"""
row_parts = row.split("\t", 1)
if mnemonic == "adrp":
self._adrp_pair_registers.add(row_parts[1].strip().split(",")[0])
row, _ = split_off_branch(row)
elif mnemonic == "ldr":
for reg in self._adrp_pair_registers:
# ldr xxx, [reg]
# ldr xxx, [reg, <imm>]
if f", [{reg}" in row_parts[1]:
self._adrp_pair_registers.remove(reg)
return normalize_imms(row)
elif mnemonic == "add":
for reg in self._adrp_pair_registers:
# add reg, reg, <imm>
if row_parts[1].startswith(f"{reg}, {reg}, "):
self._adrp_pair_registers.remove(reg)
return normalize_imms(row)
return row
def make_difference_normalizer() -> DifferenceNormalizer:
if arch == "aarch64":
return DifferenceNormalizerAArch64()
return DifferenceNormalizer()
def process(lines):
normalizer = make_difference_normalizer()
skip_next = False
source_lines = []
if not args.diff_obj:
@ -660,6 +735,7 @@ def process(lines):
if mnemonic not in instructions_with_address_immediates:
row = re.sub(re_int, lambda s: hexify_int(row, s), row)
original = row
normalized_original = normalizer.normalize(mnemonic, original)
if skip_next:
skip_next = False
row = "<delay-slot>"
@ -688,6 +764,7 @@ def process(lines):
mnemonic=mnemonic,
diff_row=row,
original=original,
normalized_original=normalized_original,
line_num=line_num,
branch_target=branch_target,
source_lines=source_lines,
@ -724,12 +801,6 @@ class SymbolColorer:
return f"{color}{t}{Fore.RESET}"
def maybe_normalize_large_imms(row):
if args.ignore_large_imms:
row = re.sub(re_large_imm, "<imm>", row)
return row
def normalize_imms(row):
return re.sub(re_imm, "<imm>", row)
@ -865,9 +936,7 @@ def do_diff(basedump: str, mydump: str) -> List[OutputLine]:
line_color1 = line_color2 = sym_color = Fore.RESET
line_prefix = " "
if line1 and line2 and line1.diff_row == line2.diff_row:
if maybe_normalize_large_imms(
line1.original
) == maybe_normalize_large_imms(line2.original):
if line1.normalized_original == line2.normalized_original:
out1 = line1.original
out2 = line2.original
elif line1.diff_row == "<delay-slot>":

View File

@ -38,7 +38,7 @@
#define RAMROM_BUF_SIZE (4096)
#define RAMROM_MSG_SIZE (RAMROM_BUF_SIZE*6)
#define RAMROM_MSG_ADDR (RAMROM_SIZE - RAMROM_MSG_SIZE)
#define RAMROM_MSG_HDR_SIZE (3*sizeof(long))
#define RAMROM_MSG_HDR_SIZE (3*4) // TODO: Used to be (3*sizeof(long))
#define RAMROM_USER_DATA_SIZE (RAMROM_MSG_SIZE-RAMROM_MSG_HDR_SIZE)
#define RAMROM_APP_READ_ADDR (RAMROM_MSG_ADDR + (0*RAMROM_BUF_SIZE))

View File

@ -11,6 +11,12 @@ typedef struct Vec3f {
/* 0x08 */ f32 z;
} Vec3f; // size = 0x0C
typedef struct Vec3s {
/* 0x00 */ s16 x;
/* 0x02 */ s16 y;
/* 0x04 */ s16 z;
} Vec3s; // size = 0x06
typedef struct Matrix4f {
/* 0x00 */ f32 mtx[4][4];
} Matrix4f; // size = 0x40
@ -206,7 +212,7 @@ typedef struct Enemy {
/* 0xC8 */ s32 unk_C8;
/* 0xCC */ UNK_PTR animList;
/* 0xD0 */ UNK_PTR territoryData;
/* 0xD4 */ UNK_PTR dropTables;
/* 0xD4 */ s16* dropTables;
/* 0xD8 */ u32 tattleString;
/* 0xDC */ char unk_DC[20];
} Enemy; // size = 0xF0
@ -227,25 +233,32 @@ typedef struct StaticNpcSettings {
/* 0x2A */ s16 unkFlags;
} StaticNpcSettings; // size = 0x2C
typedef union {
struct {
/* 0x000 */ u8 state;
/* 0x001 */ u8 currentArgc;
/* 0x002 */ u8 currentOpcode;
/* 0x003 */ u8 priority;
} bytes;
s32 flags;
} ScriptFlags;
typedef struct ScriptInstance {
/* 0x000 */ u8 state;
/* 0x001 */ u8 currentArgc;
/* 0x002 */ u8 currentOpcode;
/* 0x003 */ u8 priority;
/* 0x000 */ ScriptFlags flags;
/* 0x004 */ u8 groupFlags;
/* 0x005 */ s8 blocked; /* 1 = blocking */
/* 0x006 */ s8 loopDepth; /* how many nested loops we are in, >= 8 hangs forever */
/* 0x007 */ s8 switchDepth; /* how many nested switches we are in, max = 8 */
/* 0x008 */ Bytecode* ptrNextLine;
/* 0x00C */ Bytecode* ptrReadPos;
/* 0x010 */ u8 labelIndices[16];
/* 0x010 */ s32 labelIndices[4];
/* 0x020 */ UNK_PTR labelPositions[16];
/* 0x060 */ s32 deleted; /* set to zero in KillScript when malloc'd */
/* 0x064 */ struct ScriptInstance* blockingParent; /* parent? */
/* 0x068 */ struct ScriptInstance* childScript;
/* 0x06C */ struct ScriptInstance* parentScript; /* brother? */
/* 0x070 */ s32 functionTemp[4];
/* 0x080 */ API_FUN(callFunction);
/* 0x080 */ ApiFunc callFunction;
/* 0x084 */ s32 varTable[16];
/* 0x0C4 */ s32 varFlags[3];
/* 0x0D0 */ s32 loopStartTable[8];
@ -282,9 +295,9 @@ typedef struct Entity {
/* 0x3C */ char unk_3C[4];
/* 0x40 */ struct Trigger* trigger;
/* 0x44 */ s32* vertexData;
/* 0x48 */ f32 position[3];
/* 0x54 */ f32 scale[3];
/* 0x60 */ f32 rotation[3];
/* 0x48 */ Vec3f position;
/* 0x54 */ Vec3f scale;
/* 0x60 */ Vec3f rotation;
/* 0x6C */ char unk_6C[4];
/* 0x70 */ struct Matrix4f* inverseTransformMatrix; /* world-to-local */
/* 0x74 */ char unk_74[60];
@ -845,10 +858,8 @@ typedef struct GameStatus {
/* 0x044 */ u8 stickY; /* with deadzone */
/* 0x045 */ u8 altStickY; /* input used for batte when flag 80000 set */
/* 0x046 */ char unk_46[2];
/* 0x048 */ s16 unk_48;
/* 0x04A */ char unk_4A[6];
/* 0x050 */ s16 unk_50;
/* 0x052 */ char unk_52[6];
/* 0x048 */ s16 unk_48[4];
/* 0x050 */ s16 unk_50[4];
/* 0x058 */ s16 unk_58;
/* 0x05A */ char unk_5A[6];
/* 0x060 */ s16 unk_60;
@ -861,11 +872,14 @@ typedef struct GameStatus {
/* 0x071 */ s8 demoState; /* (0 = not demo, 1 = map demo, 2 = demo map changing) */
/* 0x072 */ u8 nextDemoScene; /* which part of the demo to play next */
/* 0x073 */ u8 contBitPattern;
/* 0x074 */ char unk_74[4];
/* 0x074 */ char unk_74[2];
/* 0x076 */ s8 unk_76;
/* 0x077 */ char unk_77;
/* 0x078 */ s8 disableScripts;
/* 0x079 */ char unk_79;
/* 0x07A */ s8 musicEnabled;
/* 0x07B */ char unk_7B[3];
/* 0x07B */ char unk_7B[2];
/* 0x07D */ s8 unk_7D;
/* 0x07E */ u8 peachFlags; /* (1 = isPeach, 2 = isTransformed, 4 = hasUmbrella) */
/* 0x07F */ u8 peachDisguise; /* (1 = koopatrol, 2 = hammer bros, 3 = clubba) */
/* 0x080 */ char unk_80[6];
@ -878,7 +892,10 @@ typedef struct GameStatus {
/* 0x094 */ f32 exitAngle;
/* 0x098 */ struct Vec3f playerPos;
/* 0x0A4 */ f32 playerYaw;
/* 0x0A8 */ char unk_A8[4];
/* 0x0A8 */ s8 unk_A8;
/* 0x0A9 */ s8 unk_A9;
/* 0x0AA */ s8 unk_AA;
/* 0x0AB */ s8 unk_AB;
/* 0x0AC */ s8 loadMenuState;
/* 0x0AD */ u8 menuCounter;
/* 0x0AE */ char unk_AE[8];
@ -1414,7 +1431,7 @@ typedef struct EncounterStatus {
/* 0x07 */ char unk_07[2];
/* 0x09 */ s8 battleOutcome; /* 0 = won, 1 = lost */
/* 0x0A */ char unk_0A;
/* 0x0B */ u8 merleeCoinBonus; /* triple coins when != 0 */
/* 0x0B */ s8 merleeCoinBonus; /* triple coins when != 0 */
/* 0x0C */ u8 damageTaken; /* valid after battle */
/* 0x0D */ char unk_0D;
/* 0x0E */ s16 coinsEarned; /* valid after battle */

View File

@ -4,6 +4,7 @@
#include "ultra64.h"
#include "types.h"
#include "macros.h"
#include "common_structs.h"
#define SI_VAR_0 0xFE363C80
@ -20,6 +21,8 @@ typedef s32 ApiStatus;
#define ApiStatus_REPEAT 3 /* Call again immediately */
#define ApiStatus_FINISH 255 /* Corresponds to SI_FINISH */
#define API_FUN(NAME) ApiStatus (*NAME)(struct ScriptInstance* script, s32 isInitialCall)
struct ScriptInstance;
typedef ApiStatus (*ApiFunc)(struct ScriptInstance* script, s32 isInitialCall);
#endif

View File

@ -103,6 +103,7 @@ extern s32 D_8009BAA0; // curtain draw callback
extern s16 gCurrentDoorSoundsSet;
extern s32 D_800D9620;
extern UNK_TYPE D_800E92D8;
extern UNK_TYPE D_80147474;
extern UNK_TYPE D_80147574;

View File

@ -2,6 +2,7 @@
void func_80035DF0(s16 arg0) {
s16* tempPtr = &D_800A0942;
*tempPtr = arg0;
}
@ -14,7 +15,7 @@ INCLUDE_ASM(s32, "code_111f0_len_860", func_80035E54);
INCLUDE_ASM(s32, "code_111f0_len_860", func_80035EEC);
void func_800360FC(void) {
GameStatus* gameStatus = *gGameStatusPtr;
GameStatus* gameStatus = GAME_STATUS;
if (gameStatus->loadMenuState == 2) {
draw_status_ui();
@ -22,7 +23,7 @@ void func_800360FC(void) {
}
void func_80036130(void) {
GameStatus* gameStatus = *gGameStatusPtr;
GameStatus* gameStatus = GAME_STATUS;
gMapTransitionAlpha = 0x00;
D_800A0942 = 0x14;
@ -38,13 +39,10 @@ void func_80036130(void) {
INCLUDE_ASM(s32, "code_111f0_len_860", func_8003617C);
s32 func_800363FC(void) {
s32 phi_return;
if ((D_800A0944 == 4) || (phi_return = 4, (D_800A0944 == 0))) {
phi_return = draw_status_ui();
void func_800363FC(void) {
if (D_800A0944 == 4 || D_800A0944 == 0) {
draw_status_ui();
}
return phi_return;
}
s32 func_80036430(void) {

View File

@ -100,13 +100,83 @@ INCLUDE_ASM(s32, "code_20ec0_len_5040", func_8004824C);
INCLUDE_ASM(s32, "code_20ec0_len_5040", spawn_drops);
INCLUDE_ASM(s32, "code_20ec0_len_5040", get_coin_drop_amount);
//INCLUDE_ASM(s32, "code_20ec0_len_5040", get_coin_drop_amount);
s32 get_coin_drop_amount(Enemy* enemy) {
EncounterStatus* currentEncounter;
s32 amt;
s32 diff;
s32 a;
s32 max;
s32 min;
currentEncounter = &gCurrentEncounter;
min = enemy->dropTables[89];
max = enemy->dropTables[90];
a = min;
if (max < min) {
min = max;
max = a;
}
diff = max - min;
amt = min;
if ((min < 0) || (diff != 0)) {
amt = rand_int(diff) + min;
}
if (amt < 0) {
amt = 0;
}
if (is_ability_active(Ability_PAY_OFF)) {
amt += currentEncounter->damageTaken / 2;
}
if (currentEncounter->merleeCoinBonus != 0) {
amt *= 3;
}
if (is_ability_active(Ability_MONEY_MONEY) ) {
amt *= 2;
}
amt += currentEncounter->coinsEarned;
if (enemy->flags & 0x840000) {
amt = 0;
}
if (amt > 20) {
amt = 20;
}
return amt;
}
INCLUDE_ASM(s32, "code_20ec0_len_5040", func_80048E34);
INCLUDE_ASM(s32, "code_20ec0_len_5040", func_80048F0C);
INCLUDE_ASM(s32, "code_20ec0_len_5040", is_point_within_region);
s32 is_point_within_region(s32 shape, f32 pointX, f32 pointY, f32 centerX, f32 centerY, f32 sizeX, f32 sizeZ) {
f32 dist1;
f32 dist2;
switch (shape) {
case 0:
dist1 = dist2D(pointX, pointY, centerX, centerY);
return (sizeX < dist1);
case 1:
dist1 = dist2D(pointX, 0, centerX, 0);
dist2 = dist2D(0, pointY, 0, centerY);
return ((sizeX < dist1) || (sizeZ < dist2));
default:
return FALSE;
}
}
INCLUDE_ASM(s32, "code_20ec0_len_5040", func_800490B4);

View File

@ -17,8 +17,8 @@ void func_800287F0(void) {
{
GameStatus* gameStatus = *gGameStatusPtr;
gameStatus->prevButtons = 0;
gameStatus->unk_50 = 4;
gameStatus->unk_48 = 15;
gameStatus->unk_50[0] = 4;
gameStatus->unk_48[0] = 15;
gameStatus->unk_60 = 0;
gameStatus->unk_58 = 0;
}

View File

@ -1,48 +1,40 @@
#include "common.h"
#ifdef NON_MATCHING
void clear_saved_variables(void) {
SaveData* saveFile = &gCurrentSaveFile;
s32 i;
for (i = ARRAY_COUNT(saveFile->globalFlags) - 1; i >= 0; i--) {
for (i = 0; i < ARRAY_COUNT(saveFile->globalFlags); i++) {
saveFile->globalFlags[i] = 0;
}
for (i = ARRAY_COUNT(saveFile->globalBytes) - 1; i >= 0; i--) {
for (i = 0; i < ARRAY_COUNT(saveFile->globalBytes); i++) {
saveFile->globalBytes[i] = 0;
}
for (i = ARRAY_COUNT(saveFile->areaFlags) - 1; i >= 0; i--) {
for (i = 0; i < ARRAY_COUNT(saveFile->areaFlags); i++) {
saveFile->areaFlags[i] = 0;
}
for (i = ARRAY_COUNT(saveFile->areaBytes) - 1; i >= 0; i--) {
for (i = 0; i < ARRAY_COUNT(saveFile->areaBytes); i++) {
saveFile->areaBytes[i] = 0;
}
}
#else
INCLUDE_ASM(s32, "code_dba20_len_350", clear_saved_variables);
#endif
#ifdef NON_MATCHING
void clear_area_flags(void) {
SaveData* saveFile = &gCurrentSaveFile;
s32 i;
if (GAME_STATUS->changedArea) {
for (i = ARRAY_COUNT(saveFile->areaFlags) - 1; i >= 0; i--) {
for (i = 0; i < ARRAY_COUNT(saveFile->areaFlags); i++) {
saveFile->areaFlags[i] = 0;
}
for (i = ARRAY_COUNT(saveFile->areaBytes) - 1; i >= 0; i--) {
for (i = 0; i < ARRAY_COUNT(saveFile->areaBytes); i++) {
saveFile->areaBytes[i] = 0;
}
}
}
#else
INCLUDE_ASM(s32, "code_dba20_len_350", clear_area_flags);
#endif
s32 clear_global_flag(s32 index) {
s32 wordIdx;
@ -60,7 +52,7 @@ s32 clear_global_flag(s32 index) {
saveFile = &gCurrentSaveFile;
flag = saveFile->globalFlags[wordIdx] & (1 << bitIdx);
if (flag) {
if (flag != 0) {
flag = 1;
}
@ -84,7 +76,7 @@ s32 set_global_flag(s32 index) {
saveFile = &gCurrentSaveFile;
flag = saveFile->globalFlags[wordIdx] & (1 << bitIdx);
if (flag) {
if (flag != 0) {
flag = 1;
}

View File

@ -27,7 +27,7 @@ ScriptInstance* restart_script(ScriptInstance* script) {
script->loopDepth = -1;
script->switchDepth = -1;
script->frameCounter = 0;
script->currentOpcode = 0;
script->flags.bytes.currentOpcode = 0;
script->frameCounter = 0;
script->unk_158 = 0;
@ -99,7 +99,7 @@ s32 does_script_exist_by_ref(ScriptInstance* script) {
}
void set_script_priority(ScriptInstance* script, s8 priority) {
script->priority = priority;
script->flags.bytes.priority = priority;
}
void set_script_timescale(ScriptInstance* script, f32 timescale) {
@ -170,7 +170,7 @@ void suspend_group_script(ScriptInstance* script, s32 groupFlags) {
}
if ((script->groupFlags & groupFlags) != 0) {
script->state |= 0x2;
script->flags.bytes.state |= 0x2;
}
}
@ -191,7 +191,7 @@ void resume_group_script(ScriptInstance* script, s32 groupFlags) {
}
if ((script->groupFlags & groupFlags) != 0) {
script->state &= 0xFD;
script->flags.bytes.state &= ~0x2;
}
}
@ -315,7 +315,7 @@ void set_script_flags(ScriptInstance* script, s32 flags) {
ScriptInstance* scriptContextPtr;
ScriptInstance* childScript = script->childScript;
script->state |= flags;
script->flags.bytes.state |= flags;
if (childScript != NULL) {
set_script_flags(childScript, flags);
}
@ -334,7 +334,7 @@ void clear_script_flags(ScriptInstance* script, s32 flags) {
ScriptInstance* scriptContextPtr;
ScriptInstance* childScript = script->childScript;
script->state &= ~flags;
script->flags.bytes.state &= ~flags;
if (childScript != NULL) {
clear_script_flags(childScript, flags);
}

View File

@ -5,6 +5,7 @@ s32 si_skip_if(ScriptInstance* script);
s32 si_skip_else(ScriptInstance* script);
s32 si_goto_end_loop(ScriptInstance* script);
s32 si_goto_end_case(ScriptInstance* script);
s32 si_goto_next_case(ScriptInstance* script);
f32 fixed_var_to_float(s32 scriptVar) {
if (scriptVar <= -220000000) {
@ -235,13 +236,52 @@ ApiStatus si_handle_case_default(ScriptInstance* script) {
do {} while (0); // Necessary to match
}
#ifdef NON_MATCHING
ApiStatus si_handle_case_AND(ScriptInstance* script) {
Bytecode *args = script->ptrReadPos;
s32 a0;
s32 switchBlockValue;
ASSERT(script->switchDepth >= 0);
switchBlockValue = script->switchBlockValue[script->switchDepth];
a0 = *args;
if (script->switchBlockState[script->switchDepth] <= 0) {
script->ptrNextLine = si_goto_end_case(script);
} else if ((a0 & switchBlockValue) != 0) {
script->switchBlockState[script->switchDepth] = 0;
} else {
script->ptrNextLine = si_goto_next_case(script);
}
return ApiStatus_DONE2;
do {} while (0); // Necessary to match
}
#else
INCLUDE_ASM(s32, "code_e92d0_len_5da0", si_handle_case_AND);
#endif
INCLUDE_ASM(s32, "code_e92d0_len_5da0", si_handle_case_equal_OR);
INCLUDE_ASM(s32, "code_e92d0_len_5da0", si_handle_case_equal_AND);
INCLUDE_ASM(s32, "code_e92d0_len_5da0", si_handle_end_case_group);
ApiStatus si_handle_end_case_group(ScriptInstance* script) {
ASSERT(script->switchDepth >= 0);
if (script->switchBlockState[script->switchDepth] == 0) {
script->ptrNextLine = si_goto_end_case(script);
} else if (script->switchBlockState[script->switchDepth] != -1) {
script->switchBlockState[script->switchDepth] = 1;
script->ptrNextLine = si_goto_next_case(script);
} else {
script->switchBlockState[script->switchDepth] = 0;
script->ptrNextLine = si_goto_end_case(script);
}
return ApiStatus_DONE2;
do {} while (0); // Necessary to match
}
ApiStatus si_handle_break_case(ScriptInstance* script) {
ASSERT(script->switchDepth >= 0);
@ -610,7 +650,28 @@ ApiStatus si_handle_OR_const(ScriptInstance* script) {
return ApiStatus_DONE2;
}
INCLUDE_ASM(s32, "code_e92d0_len_5da0", si_handle_call);
ApiStatus si_handle_call(ScriptInstance* script) {
Bytecode* args = script->ptrReadPos;
s32 isInitialCall;
ApiFunc func;
ScriptInstance* newScript; // todo fake match
if (script->blocked) {
isInitialCall = FALSE;
func = script->callFunction;
newScript = script; // todo fake match
} else {
script->callFunction = get_variable(script, *args++);
newScript = script; // todo fake match
script->ptrReadPos = args;
script->flags.bytes.currentArgc--;
script->blocked = TRUE;
isInitialCall = TRUE;
func = script->callFunction;
}
return func(newScript, isInitialCall); // todo fake match
}
INCLUDE_ASM(s32, "code_e92d0_len_5da0", si_handle_exec1);
@ -618,8 +679,8 @@ INCLUDE_ASM(s32, "code_e92d0_len_5da0", si_handle_exec2);
ApiStatus si_handle_exec_wait(ScriptInstance* script) {
start_child_script(script, get_variable(script, *script->ptrReadPos), 0);
script->currentOpcode = 0;
return 0xFF;
script->flags.bytes.currentOpcode = 0;
return ApiStatus_FINISH;
}
ApiStatus si_handle_jump(ScriptInstance* script) {
@ -702,6 +763,31 @@ ApiStatus si_handle_does_script_exist(ScriptInstance* script) {
}
INCLUDE_ASM(s32, "code_e92d0_len_5da0", func_802C6AD0);
//ApiStatus func_802C6AD0(ScriptInstance* script);
/*ApiStatus func_802C6AD0(ScriptInstance* script) {
ScriptInstance* newScript;
s32 scriptExists;
s32 ret;
s32 a;
if (script->labelIndices[1] == 0) {
newScript = start_script(script->labelIndices[0], script->labelIndices[2], 0x20);
script->labelIndices[1] = newScript;
script->labelPositions[5] = newScript->uniqueID;
newScript->varTable[0] = script->labelIndices[3];
newScript->varTable[1] = script->labelPositions[0];
newScript->varTable[2] = script->labelPositions[1];
newScript->ownerID = script;
}
ret = scriptExists = does_script_exist(script->labelPositions[5]);
if (!scriptExists) {
script->labelIndices[1] = NULL;
script->flags.flags &= ~0x2;
ret = script->flags.flags;
}
return ret;
}*/
INCLUDE_ASM(s32, "code_e92d0_len_5da0", si_handle_bind_lock, ScriptInstance* script, s32 isInitialCall);
@ -1178,6 +1264,40 @@ ApiStatus UpdateColliderTransform(ScriptInstance* script, s32 isInitialCall) {
INCLUDE_ASM(s32, "code_e92d0_len_5da0", set_zone_enabled);
INCLUDE_ASM(s32, "code_e92d0_len_5da0", SetZoneEnabled);
/*ApiStatus SetZoneEnabled(ScriptInstance* script, s32 isInitialCall) {
Bytecode* args = script->ptrReadPos;
s16 temp_a0;
s32 temp_a1;
s32 temp_s0_2;
s32 temp_v0;
void *temp_s1;
s32 phi_v0;
temp_s0_2 = get_variable(script, *args++);
temp_v0 = get_variable(script, *args++);
temp_s1 = *(void *)0x800D91D4 + (temp_s0_2 * 0x1C);
temp_a0 = temp_s1->unk6;
if ((s32) temp_a0 >= 0) {
set_zone_enabled(temp_a0, temp_v0);
}
if (temp_v0 != 0) {
if (temp_v0 != 1) {
} else {
phi_v0 = temp_s1->unk0 & ~0x10000;
block_7:
temp_s1->unk0 = phi_v0;
}
} else {
phi_v0 = temp_s1->unk0 | 0x10000;
goto block_7;
}
return 2;
}*/
INCLUDE_ASM(s32, "code_e92d0_len_5da0", goto_map);

View File

@ -1,11 +1,89 @@
#include "common.h"
void begin_state_init(void) {
D_8009A650[0] |= 8;
D_8009A650[0] |= 0x8;
GAME_STATUS->loadMenuState = 3;
}
#ifdef NON_MATCHING
void step_init_state(void) {
GameStatus* gameStatus = GAME_STATUS;
s32 i;
if (gameStatus->loadMenuState != 0) {
gameStatus->loadMenuState--;
return;
}
D_8009A650[0] = 0;
gameStatus->areaID = 0;
gameStatus->isBattle = 0;
gameStatus->prevArea = -1;
gameStatus->mapID = 0;
gameStatus->entryID = 0;
(*gGameStatusPtr)->unk_76 = 0;
(*gGameStatusPtr)->disableScripts = 0;
(*gGameStatusPtr)->unk_7D = 0;
(*gGameStatusPtr)->unk_A8 = -1;
(*gGameStatusPtr)->unk_AA = 0;
(*gGameStatusPtr)->unk_A9 = -1;
(*gGameStatusPtr)->demoState = 0;
general_heap_create();
func_8011D890();
clear_dynamic_entity_list();
clear_script_list();
create_cameras_a();
func_802DD8F8(0);
clear_virtual_models();
func_8011E224();
clear_model_data();
func_80148040();
func_80145DF8();
func_801452E8(0, 0);
func_80141100();
clear_trigger_data();
clear_printers();
clear_entity_data(0);
func_80138108();
clear_player_status();
clear_npcs();
clear_player_data();
func_80072B30();
func_8003E338();
func_80059C9C();
clear_item_entity_data();
clear_saved_variables();
initialize_collision();
func_8014AC08();
func_801473F0();
partner_initialize_data();
func_80149618();
func_8014A52C();
initialize_curtains();
for (i = 0; i < 4; i++) {
gameStatus->unk_50[i] = 4;
gameStatus->unk_48[i] = 0xF;
}
fio_has_valid_backup();
if (D_800D9620 == 0) {
GAME_STATUS->unk_AB = 1;
func_8005615C();
} else {
GAME_STATUS->unk_AB = 0;
func_80056180();
}
D_8009A650[0] &= ~0x8;
set_game_mode(1);
}
#else
INCLUDE_ASM(s32, "code_e940_len_290", step_init_state);
#endif
void func_80033788(void) {
func_8002AB5C(0, 0, 0x13F, 0xEF, 0, 0, 0, 0xFF);

View File

@ -6,7 +6,7 @@ import subprocess
from pathlib import Path
script_dir = os.path.dirname(os.path.realpath(__file__))
root_dir = script_dir + "/../"
root_dir = os.path.abspath(os.path.join(script_dir, ".."))
src_dir = root_dir + "src/"
@ -23,10 +23,10 @@ def get_c_file(directory):
if file.endswith(".c") and "data" not in file:
return file
def import_c_file(in_file):
in_file = os.path.relpath(in_file, root_dir)
cpp_command = ["cpp", "-P", "-Iinclude", "-undef", "-D__sgi", "-D_LANGUAGE_C",
"-DNON_MATCHING", "-D_Static_assert(x, y)=", "-D__attribute__(x)=", in_file]
cpp_command = ["gcc", "-E", "-P", "-Iinclude", "-D_LANGUAGE_C", "-ffreestanding", "-DF3DEX_GBI_2", in_file]
try:
return subprocess.check_output(cpp_command, cwd=root_dir, encoding="utf-8")
except subprocess.CalledProcessError:
@ -37,6 +37,7 @@ def import_c_file(in_file):
)
sys.exit(1)
def main():
if len(sys.argv) > 1:
arg = sys.argv[1]
@ -46,12 +47,23 @@ def main():
"Output will be saved in oot/ctx.c")
c_file_path = Path.cwd() / sys.argv[1]
else:
sys.exit("Please specify a .c file path as an argument to this script")
this_dir = Path.cwd()
c_dir_path = get_c_dir(this_dir.name)
if c_dir_path is None:
sys.exit("Cannot find appropriate c file dir. In argumentless mode, run this script from the c file's corresponding asm dir.")
c_file = get_c_file(c_dir_path)
c_file_path = os.path.join(c_dir_path, c_file)
output = import_c_file(c_file_path)
processed = import_c_file(c_file_path)
processed_lines = processed.split("\n")
output = []
for line in processed_lines:
if "__attribute__" not in line:
output.append(line)
with open(os.path.join(root_dir, "ctx.c"), "w", encoding="UTF-8") as f:
f.write(output)
f.write("\n".join(output))
if __name__ == "__main__":

View File

@ -31,6 +31,8 @@ D_8010CD20 = 0x8010CD20;
D_8010EF08 = 0x8010EF08;
D_8010F094 = 0x8010F094;
D_800D9620 = 0x800D9620;
gBattleStatus = 0x800DC070;
D_000759B0 = 0x000759B0;