Fixes for Refresh 12

This commit is contained in:
Prince Frizzy 2022-02-18 23:27:10 -05:00
parent cc9dc2c38c
commit 32b0c91935
No known key found for this signature in database
GPG key ID: 4042F12159699A18
128 changed files with 2012 additions and 1520 deletions

20
CHANGES
View file

@ -1,5 +1,23 @@
Refresh 12
1.) Debug box improvements (#1066)
2.) Improve 'geo_render_mirror_mario' (#1064)
3.) Cleanup and small labeling (#1063)
4.) Anim renames and other related renames (#1062)
5.) remove do while 0 and make one line comments consistent (#1061)
6.) fixed typo in segments.h (#1060)
7.) Name unknown fields (from public repo) (#1058)
8.) Change 'void *' to 'struct MainPoolState *' (#1057)
9.) Fix type of freeList (#1056)
10.) Newer version of diff script (#1055)
11.) Add stubbed_printfs based on unused audio strings (#1054)
12.) Fix comment in paintings.c (#1053)
13.) Add defines for hardcoded cell/floor height values (#1051)
14.) Update README.md: Remove GitHub specific Markdown syntax (#1052)
15.) Properly label interation status that handle's Bowser's shockwave attack (#1050)
Refresh 11 Refresh 11
1.) (HEAD -> master, origin/master, origin/HEAD) Make geo_process_level_of_detail endian-independent (#1049) 1.) Make geo_process_level_of_detail endian-independent (#1049)
2.) Label oMoveFlags and slight cleanup. (#1046) 2.) Label oMoveFlags and slight cleanup. (#1046)
3.) Avoid UB in synthesis_resample_and_mix_reverb (#1048) 3.) Avoid UB in synthesis_resample_and_mix_reverb (#1048)
4.) Change some void * to correct type (#1047) 4.) Change some void * to correct type (#1047)

View file

@ -1105,8 +1105,6 @@ $(BUILD_DIR)/actors/%.o: OPT_FLAGS := -g
$(BUILD_DIR)/bin/%.o: OPT_FLAGS := -g $(BUILD_DIR)/bin/%.o: OPT_FLAGS := -g
$(BUILD_DIR)/src/goddard/%.o: OPT_FLAGS := -g $(BUILD_DIR)/src/goddard/%.o: OPT_FLAGS := -g
$(BUILD_DIR)/src/goddard/%.o: MIPSISET := -mips1 $(BUILD_DIR)/src/goddard/%.o: MIPSISET := -mips1
$(BUILD_DIR)/src/audio/%.o: OPT_FLAGS := -O2 -Wo,-loopunroll,0
$(BUILD_DIR)/src/audio/load.o: OPT_FLAGS := -O2 -framepointer -Wo,-loopunroll,0
$(BUILD_DIR)/lib/src/%.o: OPT_FLAGS := $(BUILD_DIR)/lib/src/%.o: OPT_FLAGS :=
$(BUILD_DIR)/lib/src/math/ll%.o: MIPSISET := -mips3 -32 $(BUILD_DIR)/lib/src/math/ll%.o: MIPSISET := -mips3 -32
$(BUILD_DIR)/lib/src/math/%.o: OPT_FLAGS := -O2 $(BUILD_DIR)/lib/src/math/%.o: OPT_FLAGS := -O2
@ -1122,15 +1120,22 @@ $(BUILD_DIR)/lib/src/_Ldtob.o: OPT_FLAGS := -O3
$(BUILD_DIR)/lib/src/_Printf.o: OPT_FLAGS := -O3 $(BUILD_DIR)/lib/src/_Printf.o: OPT_FLAGS := -O3
$(BUILD_DIR)/lib/src/sprintf.o: OPT_FLAGS := -O3 $(BUILD_DIR)/lib/src/sprintf.o: OPT_FLAGS := -O3
# enable loop unrolling except for external.c (external.c might also have used # Enable loop unrolling except for external.c (external.c might also have used
# unrolling, but it makes one loop harder to match) # unrolling, but it makes one loop harder to match).
$(BUILD_DIR)/src/audio/%.o: OPT_FLAGS := -O2 # For all audio files other than external.c and port_eu.c, put string literals
$(BUILD_DIR)/src/audio/load.o: OPT_FLAGS := -O2 # in .data. (In Shindou, the port_eu.c string literals also moved to .data.)
$(BUILD_DIR)/src/audio/%.o: OPT_FLAGS := -O2 -use_readwrite_const
$(BUILD_DIR)/src/audio/port_eu.o: OPT_FLAGS := -O2
$(BUILD_DIR)/src/audio/external.o: OPT_FLAGS := -O2 -Wo,-loopunroll,0 $(BUILD_DIR)/src/audio/external.o: OPT_FLAGS := -O2 -Wo,-loopunroll,0
else else
$(BUILD_DIR)/src/audio/%.o: OPT_FLAGS := -O2 -Wo,-loopunroll,0
$(BUILD_DIR)/src/audio/load.o: OPT_FLAGS := -O2 -framepointer -Wo,-loopunroll,0
# The source-to-source optimizer copt is enabled for audio. This makes it use # The source-to-source optimizer copt is enabled for audio. This makes it use
# acpp, which needs -Wp,-+ to handle C++-style comments. # acpp, which needs -Wp,-+ to handle C++-style comments.
# All other files than external.c should really use copt, but only a few have
# been matched so far.
$(BUILD_DIR)/src/audio/effects.o: OPT_FLAGS := -O2 -Wo,-loopunroll,0 -sopt,-inline=sequence_channel_process_sound,-scalaroptimize=1 -Wp,-+ $(BUILD_DIR)/src/audio/effects.o: OPT_FLAGS := -O2 -Wo,-loopunroll,0 -sopt,-inline=sequence_channel_process_sound,-scalaroptimize=1 -Wp,-+
$(BUILD_DIR)/src/audio/synthesis.o: OPT_FLAGS := -O2 -sopt,-scalaroptimize=1 -Wp,-+ $(BUILD_DIR)/src/audio/synthesis.o: OPT_FLAGS := -O2 -sopt,-scalaroptimize=1 -Wp,-+
#$(BUILD_DIR)/src/audio/seqplayer.o: OPT_FLAGS := -O2 -sopt,-inline_manual,-scalaroptimize=1 -Wp,-+ #-Wo,-v,-bb,-l,seqplayer_list.txt #$(BUILD_DIR)/src/audio/seqplayer.o: OPT_FLAGS := -O2 -sopt,-inline_manual,-scalaroptimize=1 -Wp,-+ #-Wo,-v,-bb,-l,seqplayer_list.txt

View file

@ -16,4 +16,4 @@ Create a mod for the PC port where multiple people can play online together.
Unlike previous online attempts, this one synchronized enemies and events. This allows player to be interacting with the same world at the same time. Unlike previous online attempts, this one synchronized enemies and events. This allows player to be interacting with the same world at the same time.
## Discord ## Discord
[https://discord.gg/TJVKHS4](https://discord.gg/TJVKHS4) [https://discord.gg/TJVKHS4](https://discord.gg/TJVKHS4)

View file

@ -1,3 +1,17 @@
.data
.asciiz "Audio:Track :Call Macro Level Over Error!\n"
.balign 4
.asciiz "Audio:Track :Loops Macro Level Over Error!\n"
.balign 4
.asciiz "SUB:ERR:BANK %d NOT CACHED.\n"
.balign 4
.asciiz "SUB:ERR:BANK %d NOT CACHED.\n"
.balign 4
.asciiz "Audio:Track: CTBLCALL Macro Level Over Error!\n"
.balign 4
.asciiz "Err :Sub %x ,address %x:Undefined SubTrack Function %x"
.balign 4
.late_rodata .late_rodata
.late_rodata_alignment 4 .late_rodata_alignment 4
glabel jtbl_EU_80306714 glabel jtbl_EU_80306714

View file

@ -5,7 +5,7 @@
.byte 0x80, 0x37, 0x12, 0x40 /* PI BSD Domain 1 register */ .byte 0x80, 0x37, 0x12, 0x40 /* PI BSD Domain 1 register */
.word 0x0000000F /* Clockrate setting*/ .word 0x0000000F /* Clockrate setting*/
.word entry_point /* Entrypoint */ .word entry_point /* Entrypoint */
/* Revision */ /* Revision */
.if VERSION_SH == 1 .if VERSION_SH == 1
@ -39,8 +39,7 @@
.endif .endif
.if VERSION_SH == 1 .if VERSION_SH == 1
.byte 0x03 /* Version (Shindou) */ .byte 0x03 /* Version (Shindou) */
.else .else
.byte 0x00 /* Version */ .byte 0x00 /* Version */
.endif .endif

460
diff.py
View file

@ -5,6 +5,7 @@ import os
import ast import ast
import argparse import argparse
import subprocess import subprocess
import collections
import difflib import difflib
import string import string
import itertools import itertools
@ -20,7 +21,7 @@ def fail(msg):
MISSING_PREREQUISITES = ( MISSING_PREREQUISITES = (
"Missing prerequisite python module {}. " "Missing prerequisite python module {}. "
"Run `python3 -m pip install --user colorama ansiwrap attrs watchdog python-Levenshtein` to install prerequisites (python-Levenshtein only needed for --algorithm=levenshtein)." "Run `python3 -m pip install --user colorama ansiwrap attrs watchdog python-Levenshtein cxxfilt` to install prerequisites (cxxfilt only needed with --source)."
) )
try: try:
@ -49,6 +50,21 @@ parser.add_argument(
action="store_true", action="store_true",
help="Diff .o files rather than a whole binary. This makes it possible to see symbol names. (Recommended)", help="Diff .o files rather than a whole binary. This makes it possible to see symbol names. (Recommended)",
) )
parser.add_argument(
"--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+.",
)
parser.add_argument(
"--source",
action="store_true",
help="Show source code (if possible). Only works with -o and -e.",
)
parser.add_argument(
"--inlines",
action="store_true",
help="Show inline function calls (if possible). Only works with -o and -e.",
)
parser.add_argument( parser.add_argument(
"--base-asm", "--base-asm",
dest="base_asm", dest="base_asm",
@ -126,7 +142,7 @@ parser.add_argument(
parser.add_argument( parser.add_argument(
"--algorithm", "--algorithm",
dest="algorithm", dest="algorithm",
default="difflib", default="levenshtein",
choices=["levenshtein", "difflib"], choices=["levenshtein", "difflib"],
help="Diff algorithm to use.", help="Diff algorithm to use.",
) )
@ -137,7 +153,7 @@ parser.add_argument(
dest="max_lines", dest="max_lines",
type=int, type=int,
default=1024, default=1024,
help="The maximum length of the diff, in lines. Not recommended when -f is used.", help="The maximum length of the diff, in lines.",
) )
# Project-specific flags, e.g. different versions/make arguments. # Project-specific flags, e.g. different versions/make arguments.
@ -150,11 +166,13 @@ args = parser.parse_args()
config = {} config = {}
diff_settings.apply(config, args) diff_settings.apply(config, args)
arch = config.get("arch", "mips")
baseimg = config.get("baseimg", None) baseimg = config.get("baseimg", None)
myimg = config.get("myimg", None) myimg = config.get("myimg", None)
mapfile = config.get("mapfile", None) mapfile = config.get("mapfile", None)
makeflags = config.get("makeflags", []) makeflags = config.get("makeflags", [])
source_directories = config.get("source_directories", None) source_directories = config.get("source_directories", None)
objdump_executable = config.get("objdump_executable", None)
MAX_FUNCTION_SIZE_LINES = args.max_lines MAX_FUNCTION_SIZE_LINES = args.max_lines
MAX_FUNCTION_SIZE_BYTES = MAX_FUNCTION_SIZE_LINES * 4 MAX_FUNCTION_SIZE_BYTES = MAX_FUNCTION_SIZE_LINES * 4
@ -172,7 +190,7 @@ COLOR_ROTATION = [
] ]
BUFFER_CMD = ["tail", "-c", str(10 ** 9)] BUFFER_CMD = ["tail", "-c", str(10 ** 9)]
LESS_CMD = ["less", "-Ric"] LESS_CMD = ["less", "-SRic", "-#6"]
DEBOUNCE_DELAY = 0.1 DEBOUNCE_DELAY = 0.1
FS_WATCH_EXTENSIONS = [".c", ".h"] FS_WATCH_EXTENSIONS = [".c", ".h"]
@ -185,25 +203,30 @@ if args.algorithm == "levenshtein":
except ModuleNotFoundError as e: except ModuleNotFoundError as e:
fail(MISSING_PREREQUISITES.format(e.name)) fail(MISSING_PREREQUISITES.format(e.name))
binutils_prefix = None if args.source:
for binutils_cand in ["mips-linux-gnu-", "mips64-elf-"]:
try: try:
subprocess.check_call( import cxxfilt
[binutils_cand + "objdump", "--version"], except ModuleNotFoundError as e:
stdout=subprocess.DEVNULL, fail(MISSING_PREREQUISITES.format(e.name))
stderr=subprocess.DEVNULL,
)
binutils_prefix = binutils_cand
break
except subprocess.CalledProcessError:
pass
except FileNotFoundError:
pass
if not binutils_prefix: if objdump_executable is None:
for objdump_cand in ["mips-linux-gnu-objdump", "mips64-elf-objdump"]:
try:
subprocess.check_call(
[objdump_cand, "--version"],
stdout=subprocess.DEVNULL,
stderr=subprocess.DEVNULL,
)
objdump_executable = objdump_cand
break
except subprocess.CalledProcessError:
pass
except FileNotFoundError:
pass
if not objdump_executable:
fail( fail(
"Missing binutils; please ensure mips-linux-gnu-objdump or mips64-elf-objdump exist." "Missing binutils; please ensure mips-linux-gnu-objdump or mips64-elf-objdump exist, or configure objdump_executable."
) )
@ -219,6 +242,10 @@ def eval_int(expr, emsg=None):
return None return None
def eval_line_num(expr):
return int(expr.strip().replace(":", ""), 16)
def run_make(target, capture_output=False): def run_make(target, capture_output=False):
if capture_output: if capture_output:
return subprocess.run( return subprocess.run(
@ -244,10 +271,26 @@ def restrict_to_function(dump, fn_name):
return "\n".join(out) return "\n".join(out)
def maybe_get_objdump_source_flags():
if not args.source:
return []
flags = [
"--source",
"--source-comment=| ",
"-l",
]
if args.inlines:
flags.append("--inlines")
return flags
def run_objdump(cmd): def run_objdump(cmd):
flags, target, restrict = cmd flags, target, restrict = cmd
out = subprocess.check_output( out = subprocess.check_output(
[binutils_prefix + "objdump"] + flags + [target], universal_newlines=True [objdump_executable] + flags + [target], universal_newlines=True
) )
if restrict is not None: if restrict is not None:
return restrict_to_function(out, restrict) return restrict_to_function(out, restrict)
@ -300,6 +343,36 @@ def search_map_file(fn_name):
return None, None return None, None
def dump_elf():
if not baseimg or not myimg:
fail("Missing myimg/baseimg in config.")
if base_shift:
fail("--base-shift not compatible with -e")
start_addr = eval_int(args.start, "Start address must be an integer expression.")
if args.end is not None:
end_addr = eval_int(args.end, "End address must be an integer expression.")
else:
end_addr = start_addr + MAX_FUNCTION_SIZE_BYTES
flags1 = [
f"--start-address={start_addr}",
f"--stop-address={end_addr}",
]
flags2 = [
f"--disassemble={args.diff_elf_symbol}",
]
objdump_flags = ["-drz", "-j", ".text"]
return (
myimg,
(objdump_flags + flags1, baseimg, None),
(objdump_flags + flags2 + maybe_get_objdump_source_flags(), myimg, None),
)
def dump_objfile(): def dump_objfile():
if base_shift: if base_shift:
fail("--base-shift not compatible with -o") fail("--base-shift not compatible with -o")
@ -326,7 +399,7 @@ def dump_objfile():
return ( return (
objfile, objfile,
(objdump_flags, refobjfile, args.start), (objdump_flags, refobjfile, args.start),
(objdump_flags, objfile, args.start), (objdump_flags + maybe_get_objdump_source_flags(), objfile, args.start),
) )
@ -366,29 +439,45 @@ def ansi_ljust(s, width):
return s return s
re_int = re.compile(r"[0-9]+") if arch == "mips":
re_comments = re.compile(r"<.*?>") re_int = re.compile(r"[0-9]+")
re_regs = re.compile(r"\$?\b(a[0-3]|t[0-9]|s[0-8]|at|v[01]|f[12]?[0-9]|f3[01]|fp)\b") re_comment = re.compile(r"<.*?>")
re_sprel = re.compile(r",([0-9]+|0x[0-9a-f]+)\(sp\)") re_reg = re.compile(r"\$?\b(a[0-3]|t[0-9]|s[0-8]|at|v[01]|f[12]?[0-9]|f3[01]|k[01]|fp|ra)\b")
re_large_imm = re.compile(r"-?[1-9][0-9]{2,}|-?0x[0-9a-f]{3,}") re_sprel = re.compile(r"(?<=,)([0-9]+|0x[0-9a-f]+)\(sp\)")
re_imm = re.compile(r"(\b|-)([0-9]+|0x[0-9a-fA-F]+)\b(?!\(sp)|%(lo|hi)\([^)]*\)") re_large_imm = re.compile(r"-?[1-9][0-9]{2,}|-?0x[0-9a-f]{3,}")
forbidden = set(string.ascii_letters + "_") re_imm = re.compile(r"(\b|-)([0-9]+|0x[0-9a-fA-F]+)\b(?!\(sp)|%(lo|hi)\([^)]*\)")
branch_likely_instructions = { forbidden = set(string.ascii_letters + "_")
"beql", branch_likely_instructions = {
"bnel", "beql",
"beqzl", "bnel",
"bnezl", "beqzl",
"bgezl", "bnezl",
"bgtzl", "bgezl",
"blezl", "bgtzl",
"bltzl", "blezl",
"bc1tl", "bltzl",
"bc1fl", "bc1tl",
} "bc1fl",
branch_instructions = branch_likely_instructions.union( }
{"b", "beq", "bne", "beqz", "bnez", "bgez", "bgtz", "blez", "bltz", "bc1t", "bc1f"} branch_instructions = branch_likely_instructions.union(
) {"b", "beq", "bne", "beqz", "bnez", "bgez", "bgtz", "blez", "bltz", "bc1t", "bc1f"}
jump_instructions = branch_instructions.union({"jal", "j"}) )
instructions_with_address_immediates = branch_instructions.union({"jal", "j"})
elif arch == "aarch64":
re_int = re.compile(r"[0-9]+")
re_comment = re.compile(r"(<.*?>|//.*$)")
# GPRs and FP registers: X0-X30, W0-W30, [DSHQ]0..31
# The zero registers and SP should not be in this list.
re_reg = re.compile(r"\$?\b([dshq][12]?[0-9]|[dshq]3[01]|[xw][12]?[0-9]|[xw]30)\b")
re_sprel = re.compile(r"sp, #-?(0x[0-9a-fA-F]+|[0-9]+)\b")
re_large_imm = re.compile(r"-?[1-9][0-9]{2,}|-?0x[0-9a-f]{3,}")
re_imm = re.compile(r"(?<!sp, )#-?(0x[0-9a-fA-F]+|[0-9]+)\b")
forbidden = set(string.ascii_letters + "_")
branch_likely_instructions = set()
branch_instructions = {"bl", "b", "b.eq", "b.ne", "b.cs", "b.hs", "b.cc", "b.lo", "b.mi", "b.pl", "b.vs", "b.vc", "b.hi", "b.ls", "b.ge", "b.lt", "b.gt", "b.le", "cbz", "cbnz", "tbz", "tbnz"}
instructions_with_address_immediates = branch_instructions.union({"adrp"})
else:
fail("Unknown architecture.")
def hexify_int(row, pat): def hexify_int(row, pat):
@ -440,38 +529,63 @@ def process_reloc(row, prev):
return before + repl + after return before + repl + after
def cleanup_whitespace(line):
return "".join(f"{o:<8s}" for o in line.strip().split("\t"))
Line = collections.namedtuple(
"Line",
[
"mnemonic",
"diff_row",
"original",
"line_num",
"branch_target",
"source_lines",
"comment",
],
)
def process(lines): def process(lines):
mnemonics = []
diff_rows = []
rows_with_imms = []
skip_next = False skip_next = False
originals = [] source_lines = []
line_nums = []
branch_targets = []
if not args.diff_obj: if not args.diff_obj:
lines = lines[7:] lines = lines[7:]
if lines and not lines[-1]: if lines and not lines[-1]:
lines.pop() lines.pop()
output = []
for row in lines: for row in lines:
if args.diff_obj and (">:" in row or not row): if args.diff_obj and (">:" in row or not row):
continue continue
if "R_MIPS_" in row: if args.source and (row and row[0] != " "):
# N.B. Don't transform the diff rows, they already ignore immediates source_lines.append(row)
# if diff_rows[-1] != '<delay-slot>':
# diff_rows[-1] = process_reloc(row, rows_with_imms[-1])
originals[-1] = process_reloc(row, originals[-1])
continue continue
row = re.sub(re_comments, "", row) if "R_AARCH64_" in row:
# TODO: handle relocation
continue
if "R_MIPS_" in row:
# N.B. Don't transform the diff rows, they already ignore immediates
# if output[-1].diff_row != "<delay-slot>":
# output[-1] = output[-1].replace(diff_row=process_reloc(row, output[-1].row_with_imm))
new_original = process_reloc(row, output[-1].original)
output[-1] = output[-1]._replace(original=new_original)
continue
m_comment = re.search(re_comment, row)
comment = m_comment[0] if m_comment else None
row = re.sub(re_comment, "", row)
row = row.rstrip() row = row.rstrip()
tabs = row.split("\t") tabs = row.split("\t")
row = "\t".join(tabs[2:]) row = "\t".join(tabs[2:])
line_num = tabs[0].strip() line_num = tabs[0].strip()
row_parts = row.split("\t", 1) row_parts = row.split("\t", 1)
mnemonic = row_parts[0].strip() mnemonic = row_parts[0].strip()
if mnemonic not in jump_instructions: if mnemonic not in instructions_with_address_immediates:
row = re.sub(re_int, lambda s: hexify_int(row, s), row) row = re.sub(re_int, lambda s: hexify_int(row, s), row)
original = row original = row
if skip_next: if skip_next:
@ -480,38 +594,45 @@ def process(lines):
mnemonic = "<delay-slot>" mnemonic = "<delay-slot>"
if mnemonic in branch_likely_instructions: if mnemonic in branch_likely_instructions:
skip_next = True skip_next = True
row = re.sub(re_regs, "<reg>", row) row = re.sub(re_reg, "<reg>", row)
row = re.sub(re_sprel, ",addr(sp)", row) row = re.sub(re_sprel, "addr(sp)", row)
row_with_imm = row row_with_imm = row
if mnemonic in jump_instructions: if mnemonic in instructions_with_address_immediates:
row = row.strip() row = row.strip()
row, _ = split_off_branch(row) row, _ = split_off_branch(row)
row += "<imm>" row += "<imm>"
else: else:
row = re.sub(re_imm, "<imm>", row) row = normalize_imms(row)
mnemonics.append(mnemonic) branch_target = None
rows_with_imms.append(row_with_imm)
diff_rows.append(row)
originals.append(original)
line_nums.append(line_num)
if mnemonic in branch_instructions: if mnemonic in branch_instructions:
target = row_parts[1].strip().split(",")[-1] target = row_parts[1].strip().split(",")[-1]
if mnemonic in branch_likely_instructions: if mnemonic in branch_likely_instructions:
target = hex(int(target, 16) - 4)[2:] target = hex(int(target, 16) - 4)[2:]
branch_targets.append(target) branch_target = target.strip()
else:
branch_targets.append(None) output.append(
Line(
mnemonic=mnemonic,
diff_row=row,
original=original,
line_num=line_num,
branch_target=branch_target,
source_lines=source_lines,
comment=comment,
)
)
source_lines = []
if args.stop_jrra and mnemonic == "jr" and row_parts[1].strip() == "ra": if args.stop_jrra and mnemonic == "jr" and row_parts[1].strip() == "ra":
break break
# Cleanup whitespace # Cleanup whitespace, after relocation fixups have happened
originals = [original.strip() for original in originals] output = [
originals = [ line._replace(original=cleanup_whitespace(line.original)) for line in output
"".join(f"{o:<8s}" for o in original.split("\t")) for original in originals
] ]
# return diff_rows, diff_rows, line_nums
return mnemonics, diff_rows, originals, line_nums, branch_targets return output
def format_single_line_diff(line1, line2, column_width): def format_single_line_diff(line1, line2, column_width):
@ -545,7 +666,7 @@ def normalize_imms(row):
def normalize_stack(row): def normalize_stack(row):
return re.sub(re_sprel, ",addr(sp)", row) return re.sub(re_sprel, "addr(sp)", row)
def split_off_branch(line): def split_off_branch(line):
@ -614,20 +735,13 @@ def diff_sequences(seq1, seq2):
def do_diff(basedump, mydump): def do_diff(basedump, mydump):
asm_lines1 = basedump.split("\n")
asm_lines2 = mydump.split("\n")
output = [] output = []
# TODO: status line? # TODO: status line?
# output.append(sha1sum(mydump)) # output.append(sha1sum(mydump))
mnemonics1, asm_lines1, originals1, line_nums1, branch_targets1 = process( lines1 = process(basedump.split("\n"))
asm_lines1 lines2 = process(mydump.split("\n"))
)
mnemonics2, asm_lines2, originals2, line_nums2, branch_targets2 = process(
asm_lines2
)
sc1 = SymbolColorer(0) sc1 = SymbolColorer(0)
sc2 = SymbolColorer(0) sc2 = SymbolColorer(0)
@ -639,80 +753,74 @@ def do_diff(basedump, mydump):
bts2 = set() bts2 = set()
if args.show_branches: if args.show_branches:
for (bts, btset, sc) in [ for (lines, btset, sc) in [
(branch_targets1, bts1, sc5), (lines1, bts1, sc5),
(branch_targets2, bts2, sc6), (lines2, bts2, sc6),
]: ]:
for bt in bts: for line in lines:
bt = line.branch_target
if bt is not None: if bt is not None:
btset.add(bt + ":") btset.add(bt + ":")
sc.color_symbol(bt + ":") sc.color_symbol(bt + ":")
for (tag, i1, i2, j1, j2) in diff_sequences(mnemonics1, mnemonics2): for (tag, i1, i2, j1, j2) in diff_sequences(
lines1 = asm_lines1[i1:i2] [line.mnemonic for line in lines1], [line.mnemonic for line in lines2]
lines2 = asm_lines2[j1:j2] ):
for line1, line2 in itertools.zip_longest(lines1[i1:i2], lines2[j1:j2]):
for k, (line1, line2) in enumerate(itertools.zip_longest(lines1, lines2)):
if tag == "replace": if tag == "replace":
if line1 is None: if line1 is None:
tag = "insert" tag = "insert"
elif line2 is None: elif line2 is None:
tag = "delete" tag = "delete"
elif tag == "insert":
assert line1 is None
elif tag == "delete":
assert line2 is None
try:
original1 = originals1[i1 + k]
line_num1 = line_nums1[i1 + k]
except:
original1 = ""
line_num1 = ""
try:
original2 = originals2[j1 + k]
line_num2 = line_nums2[j1 + k]
except:
original2 = ""
line_num2 = ""
has1 = has2 = True
line_color1 = line_color2 = sym_color = Fore.RESET line_color1 = line_color2 = sym_color = Fore.RESET
line_prefix = " " line_prefix = " "
if line1 == line2: if line1 and line2 and line1.diff_row == line2.diff_row:
if not line1: if maybe_normalize_large_imms(
has1 = has2 = False line1.original
if maybe_normalize_large_imms(original1) == maybe_normalize_large_imms( ) == maybe_normalize_large_imms(line2.original):
original2 out1 = line1.original
): out2 = line2.original
out1 = original1 elif line1.diff_row == "<delay-slot>":
out2 = original2 out1 = f"{Style.BRIGHT}{Fore.LIGHTBLACK_EX}{line1.original}"
elif line1 == "<delay-slot>": out2 = f"{Style.BRIGHT}{Fore.LIGHTBLACK_EX}{line2.original}"
out1 = f"{Style.DIM}{original1}"
out2 = f"{Style.DIM}{original2}"
else: else:
mnemonic = original1.split()[0] mnemonic = line1.original.split()[0]
out1, out2 = original1, original2 out1, out2 = line1.original, line2.original
branch1 = branch2 = "" branch1 = branch2 = ""
if mnemonic in jump_instructions: if mnemonic in instructions_with_address_immediates:
out1, branch1 = split_off_branch(original1) out1, branch1 = split_off_branch(line1.original)
out2, branch2 = split_off_branch(original2) out2, branch2 = split_off_branch(line2.original)
branchless1 = out1 branchless1 = out1
branchless2 = out2 branchless2 = out2
out1, out2 = color_imms(out1, out2) out1, out2 = color_imms(out1, out2)
branch1, branch2 = color_branch_imms(branch1, branch2)
same_relative_target = False
if line1.branch_target is not None and line2.branch_target is not None:
relative_target1 = eval_line_num(line1.branch_target) - eval_line_num(line1.line_num)
relative_target2 = eval_line_num(line2.branch_target) - eval_line_num(line2.line_num)
same_relative_target = relative_target1 == relative_target2
if not same_relative_target:
branch1, branch2 = color_branch_imms(branch1, branch2)
out1 += branch1 out1 += branch1
out2 += branch2 out2 += branch2
if normalize_imms(branchless1) == normalize_imms(branchless2): if normalize_imms(branchless1) == normalize_imms(branchless2):
# only imms differences if not same_relative_target:
sym_color = Fore.LIGHTBLUE_EX # only imms differences
line_prefix = "i" sym_color = Fore.LIGHTBLUE_EX
line_prefix = "i"
else: else:
out1 = re.sub( out1 = re.sub(
re_sprel, re_sprel, lambda s: sc3.color_symbol(s.group()), out1,
lambda s: "," + sc3.color_symbol(s.group()[1:]),
out1,
) )
out2 = re.sub( out2 = re.sub(
re_sprel, re_sprel, lambda s: sc4.color_symbol(s.group()), out2,
lambda s: "," + sc4.color_symbol(s.group()[1:]),
out2,
) )
if normalize_stack(branchless1) == normalize_stack(branchless2): if normalize_stack(branchless1) == normalize_stack(branchless2):
# only stack differences (luckily stack and imm # only stack differences (luckily stack and imm
@ -723,61 +831,81 @@ def do_diff(basedump, mydump):
else: else:
# regs differences and maybe imms as well # regs differences and maybe imms as well
out1 = re.sub( out1 = re.sub(
re_regs, lambda s: sc1.color_symbol(s.group()), out1 re_reg, lambda s: sc1.color_symbol(s.group()), out1
) )
out2 = re.sub( out2 = re.sub(
re_regs, lambda s: sc2.color_symbol(s.group()), out2 re_reg, lambda s: sc2.color_symbol(s.group()), out2
) )
line_color1 = line_color2 = sym_color = Fore.YELLOW line_color1 = line_color2 = sym_color = Fore.YELLOW
line_prefix = "r" line_prefix = "r"
elif tag in ["replace", "equal"]: elif line1 and line2:
line_prefix = "|" line_prefix = "|"
line_color1 = Fore.LIGHTBLUE_EX line_color1 = Fore.LIGHTBLUE_EX
line_color2 = Fore.LIGHTBLUE_EX line_color2 = Fore.LIGHTBLUE_EX
sym_color = Fore.LIGHTBLUE_EX sym_color = Fore.LIGHTBLUE_EX
out1 = original1 out1 = line1.original
out2 = original2 out2 = line2.original
elif tag == "delete": elif line1:
line_prefix = "<" line_prefix = "<"
line_color1 = line_color2 = sym_color = Fore.RED line_color1 = line_color2 = sym_color = Fore.RED
has2 = False out1 = line1.original
out1 = original1
out2 = "" out2 = ""
elif tag == "insert": elif line2:
line_prefix = ">" line_prefix = ">"
line_color1 = line_color2 = sym_color = Fore.GREEN line_color1 = line_color2 = sym_color = Fore.GREEN
has1 = False
out1 = "" out1 = ""
out2 = original2 out2 = line2.original
in_arrow1 = " " in_arrow1 = " "
in_arrow2 = " " in_arrow2 = " "
out_arrow1 = "" out_arrow1 = ""
out_arrow2 = "" out_arrow2 = ""
line_num1 = line_num1 if has1 else ""
line_num2 = line_num2 if has2 else ""
if sym_color == line_color2: if args.show_branches and line1:
line_color2 = "" 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.show_branches and has1: if args.source and line2 and line2.comment:
if line_num1 in bts1: out2 += f" {line2.comment}"
in_arrow1 = sc5.color_symbol(line_num1, "~>") + line_color1
if branch_targets1[i1 + k] is not None: line_num1 = line1.line_num if line1 else ""
out_arrow1 = " " + sc5.color_symbol( line_num2 = line2.line_num if line2 else ""
branch_targets1[i1 + k] + ":", "~>"
)
if args.show_branches and has2:
if line_num2 in bts2:
in_arrow2 = sc6.color_symbol(line_num2, "~>") + line_color2
if branch_targets2[j1 + k] is not None:
out_arrow2 = " " + sc6.color_symbol(
branch_targets2[j1 + k] + ":", "~>"
)
out1 = f"{line_color1}{line_num1} {in_arrow1} {out1}{Style.RESET_ALL}{out_arrow1}" 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}" out2 = f"{line_color2}{line_num2} {in_arrow2} {out2}{Style.RESET_ALL}{out_arrow2}"
mid = f"{sym_color}{line_prefix} " mid = f"{sym_color}{line_prefix} "
if line2:
for source_line in line2.source_lines:
color = Style.DIM
# File names and function names
if source_line and source_line[0] != "|":
color += Style.BRIGHT
# Function names
if source_line.endswith("():"):
# Underline. Colorama does not provide this feature, unfortunately.
color += "\u001b[4m"
try:
source_line = cxxfilt.demangle(
source_line[:-3], external_only=False
)
except:
pass
output.append(
format_single_line_diff(
"",
f" {color}{source_line}{Style.RESET_ALL}",
args.column_width,
)
)
output.append(format_single_line_diff(out1, mid + out2, args.column_width)) output.append(format_single_line_diff(out1, mid + out2, args.column_width))
return output[args.skip_lines :] return output[args.skip_lines :]
@ -941,7 +1069,9 @@ class Display:
def main(): def main():
if args.diff_obj: if args.diff_elf_symbol:
make_target, basecmd, mycmd = dump_elf()
elif args.diff_obj:
make_target, basecmd, mycmd = dump_objfile() make_target, basecmd, mycmd = dump_objfile()
else: else:
make_target, basecmd, mycmd = dump_binary() make_target, basecmd, mycmd = dump_binary()

View file

@ -1,7 +1,7 @@
#ifndef EU_TRANSLATION_H #ifndef EU_TRANSLATION_H
#define EU_TRANSLATION_H #define EU_TRANSLATION_H
// PAL changes most text to arrays for each language. This define allows these // EU changes most text to arrays for each language. This define allows these
// differences to be combined. // differences to be combined.
#ifdef VERSION_EU #ifdef VERSION_EU
#define LANGUAGE_ARRAY(cmd) cmd[LANGUAGE_FUNCTION] #define LANGUAGE_ARRAY(cmd) cmd[LANGUAGE_FUNCTION]

View file

@ -634,15 +634,15 @@
#define UKIKI_TEXT_DEFAULT 0 #define UKIKI_TEXT_DEFAULT 0
#define UKIKI_TEXT_CAGE_TEXTBOX 1 #define UKIKI_TEXT_CAGE_TEXTBOX 1
#define UKIKI_TEXT_GO_TO_CAGE 2 #define UKIKI_TEXT_GO_TO_CAGE 2
#define UKIKI_TEXT_STOLE_HAT 3 #define UKIKI_TEXT_STOLE_CAP 3
#define UKIKI_TEXT_HAS_HAT 4 #define UKIKI_TEXT_HAS_CAP 4
#define UKIKI_TEXT_GAVE_HAT_BACK 5 #define UKIKI_TEXT_GAVE_CAP_BACK 5
#define UKIKI_TEXT_DO_NOT_LET_GO 6 #define UKIKI_TEXT_DO_NOT_LET_GO 6
#define UKIKI_TEXT_STEAL_HAT 7 #define UKIKI_TEXT_STEAL_CAP 7
/* oBehParams2ndByte */ /* oBehParams2ndByte */
#define UKIKI_CAGE 0 #define UKIKI_CAGE 0
#define UKIKI_HAT 1 #define UKIKI_CAP 1
/* Animations */ /* Animations */
#define UKIKI_ANIM_RUN 0 #define UKIKI_ANIM_RUN 0
@ -660,13 +660,12 @@
#define UKIKI_ANIM_HELD 12 #define UKIKI_ANIM_HELD 12
/* oAnimState */ /* oAnimState */
#define UKIKI_ANIM_STATE_DEFAULT 0 #define UKIKI_ANIM_STATE_DEFAULT 0
#define UKIKI_ANIM_STATE_EYE_CLOSED 1 // unused #define UKIKI_ANIM_STATE_EYE_CLOSED 1
#define UKIKI_ANIM_STATE_HAT_ON 2 #define UKIKI_ANIM_STATE_CAP_ON 2
#define UKIKI_ANIM_STATE_UNUSED 3 // unused, HAT_ON+EYE_CLOSED
/* oUkikiHasHat */ /* oUkikiHasCap */
#define UKIKI_HAT_ON 1 #define UKIKI_CAP_ON 1
/* Ukiki Cage Star */ /* Ukiki Cage Star */
/* oAction */ /* oAction */

View file

@ -509,9 +509,9 @@
#define /*0x0F8*/ oBlueFlameUnkF8 OBJECT_FIELD_F32(0x1C) #define /*0x0F8*/ oBlueFlameUnkF8 OBJECT_FIELD_F32(0x1C)
/* Small Piranha Flame */ /* Small Piranha Flame */
#define /*0x0F4*/ oSmallPiranhaFlameUnkF4 OBJECT_FIELD_F32(0x1B) #define /*0x0F4*/ oSmallPiranhaFlameStartSpeed OBJECT_FIELD_F32(0x1B)
#define /*0x0F8*/ oSmallPiranhaFlameUnkF8 OBJECT_FIELD_F32(0x1C) #define /*0x0F8*/ oSmallPiranhaFlameEndSpeed OBJECT_FIELD_F32(0x1C)
#define /*0x0FC*/ oSmallPiranhaFlameUnkFC OBJECT_FIELD_S32(0x1D) #define /*0x0FC*/ oSmallPiranhaFlameModel OBJECT_FIELD_S32(0x1D)
#define /*0x100*/ oSmallPiranhaFlameUnk100 OBJECT_FIELD_S32(0x1E) #define /*0x100*/ oSmallPiranhaFlameUnk100 OBJECT_FIELD_S32(0x1E)
#define /*0x104*/ oSmallPiranhaFlameUnk104 OBJECT_FIELD_F32(0x1F) #define /*0x104*/ oSmallPiranhaFlameUnk104 OBJECT_FIELD_F32(0x1F)
@ -970,7 +970,7 @@
#define /*0x10C*/ oTiltingPyramidMarioOnPlatform OBJECT_FIELD_S32(0x21) #define /*0x10C*/ oTiltingPyramidMarioOnPlatform OBJECT_FIELD_S32(0x21)
/* Toad Message */ /* Toad Message */
#define /*0x108*/ oToadMessageDialogId OBJECT_FIELD_U32(0x20) #define /*0x108*/ oToadMessageDialogId OBJECT_FIELD_U32(0x20)
#define /*0x10C*/ oToadMessageRecentlyTalked OBJECT_FIELD_S32(0x21) #define /*0x10C*/ oToadMessageRecentlyTalked OBJECT_FIELD_S32(0x21)
#define /*0x110*/ oToadMessageState OBJECT_FIELD_S32(0x22) #define /*0x110*/ oToadMessageState OBJECT_FIELD_S32(0x22)
@ -1062,7 +1062,7 @@
#define /*0x1AC*/ oUkikiTextState OBJECT_FIELD_S16(0x49, 0) #define /*0x1AC*/ oUkikiTextState OBJECT_FIELD_S16(0x49, 0)
#define /*0x1AE*/ oUkikiTextboxTimer OBJECT_FIELD_S16(0x49, 1) #define /*0x1AE*/ oUkikiTextboxTimer OBJECT_FIELD_S16(0x49, 1)
#define /*0x1B0*/ oUkikiCageSpinTimer OBJECT_FIELD_S16(0x4A, 0) #define /*0x1B0*/ oUkikiCageSpinTimer OBJECT_FIELD_S16(0x4A, 0)
#define /*0x1B2*/ oUkikiHasHat OBJECT_FIELD_S16(0x4A, 1) #define /*0x1B2*/ oUkikiHasCap OBJECT_FIELD_S16(0x4A, 1)
/* Ukiki Cage*/ /* Ukiki Cage*/
#define /*0x088*/ oUkikiCageNextAction OBJECT_FIELD_S32(0x00) #define /*0x088*/ oUkikiCageNextAction OBJECT_FIELD_S32(0x00)
@ -1096,7 +1096,7 @@
#define /*0x0F4*/ oCannonBarrelBubblesUnkF4 OBJECT_FIELD_F32(0x1B) #define /*0x0F4*/ oCannonBarrelBubblesUnkF4 OBJECT_FIELD_F32(0x1B)
/* Water Level Pillar */ /* Water Level Pillar */
#define /*0x0F8*/ oWaterLevelPillarUnkF8 OBJECT_FIELD_S32(0x1C) #define /*0x0F8*/ oWaterLevelPillarDrained OBJECT_FIELD_S32(0x1C)
/* Water Level Trigger */ /* Water Level Trigger */
#define /*0x0F4*/ oWaterLevelTriggerUnkF4 OBJECT_FIELD_S32(0x1B) #define /*0x0F4*/ oWaterLevelTriggerUnkF4 OBJECT_FIELD_S32(0x1B)

View file

@ -49,12 +49,12 @@
#define SEG_BUFFERS 0x8005C000 // 0x0085000 in size #define SEG_BUFFERS 0x8005C000 // 0x0085000 in size
#ifdef BETTERCAMERA #ifdef BETTERCAMERA
#define SEG_MAIN 0x800F1000 // 0x1328000 in size #define SEG_MAIN 0x800F1000 // 0x0132800 in size
#define SEG_ENGINE 0x80223800 // 0x0017000 in size #define SEG_ENGINE 0x80223800 // 0x0017000 in size
#define SEG_FRAMEBUFFERS 0x8023A800 // 0x0070800 in size #define SEG_FRAMEBUFFERS 0x8023A800 // 0x0070800 in size
#define SEG_POOL_START 0x802AB000 // 0x0165000 in size #define SEG_POOL_START 0x802AB000 // 0x0165000 in size
#else #else
#define SEG_MAIN 0x800E1000 // 0x1328000 in size #define SEG_MAIN 0x800E1000 // 0x0132800 in size
#define SEG_ENGINE 0x80213800 // 0x0017000 in size #define SEG_ENGINE 0x80213800 // 0x0017000 in size
#define SEG_FRAMEBUFFERS 0x8022A800 // 0x0070800 in size #define SEG_FRAMEBUFFERS 0x8022A800 // 0x0070800 in size
#define SEG_POOL_START 0x8029B000 // 0x0165000 in size #define SEG_POOL_START 0x8029B000 // 0x0165000 in size

View file

@ -132,7 +132,8 @@
#define MARIO_UNKNOWN_30 0x40000000 #define MARIO_UNKNOWN_30 0x40000000
#define MARIO_UNKNOWN_31 0x80000000 #define MARIO_UNKNOWN_31 0x80000000
#define MARIO_CAP_FLAGS 0x0000001F #define MARIO_SPECIAL_CAPS (MARIO_VANISH_CAP | MARIO_METAL_CAP | MARIO_WING_CAP)
#define MARIO_CAPS (MARIO_NORMAL_CAP | MARIO_SPECIAL_CAPS)
#define ACT_ID_MASK 0x000001FF #define ACT_ID_MASK 0x000001FF
@ -183,6 +184,7 @@
#define ACT_COUGHING 0x0C40020A // (0x00A | ACT_FLAG_STATIONARY | ACT_FLAG_IDLE | ACT_FLAG_ALLOW_FIRST_PERSON | ACT_FLAG_PAUSE_EXIT) #define ACT_COUGHING 0x0C40020A // (0x00A | ACT_FLAG_STATIONARY | ACT_FLAG_IDLE | ACT_FLAG_ALLOW_FIRST_PERSON | ACT_FLAG_PAUSE_EXIT)
#define ACT_SHIVERING 0x0C40020B // (0x00B | ACT_FLAG_STATIONARY | ACT_FLAG_IDLE | ACT_FLAG_ALLOW_FIRST_PERSON | ACT_FLAG_PAUSE_EXIT) #define ACT_SHIVERING 0x0C40020B // (0x00B | ACT_FLAG_STATIONARY | ACT_FLAG_IDLE | ACT_FLAG_ALLOW_FIRST_PERSON | ACT_FLAG_PAUSE_EXIT)
#define ACT_IN_QUICKSAND 0x0002020D // (0x00D | ACT_FLAG_STATIONARY | ACT_FLAG_INVULNERABLE) #define ACT_IN_QUICKSAND 0x0002020D // (0x00D | ACT_FLAG_STATIONARY | ACT_FLAG_INVULNERABLE)
#define ACT_UNKNOWN_0002020E 0x0002020E // (0x00E | ACT_FLAG_STATIONARY | ACT_FLAG_INVULNERABLE)
#define ACT_CROUCHING 0x0C008220 // (0x020 | ACT_FLAG_STATIONARY | ACT_FLAG_SHORT_HITBOX | ACT_FLAG_ALLOW_FIRST_PERSON | ACT_FLAG_PAUSE_EXIT) #define ACT_CROUCHING 0x0C008220 // (0x020 | ACT_FLAG_STATIONARY | ACT_FLAG_SHORT_HITBOX | ACT_FLAG_ALLOW_FIRST_PERSON | ACT_FLAG_PAUSE_EXIT)
#define ACT_START_CROUCHING 0x0C008221 // (0x021 | ACT_FLAG_STATIONARY | ACT_FLAG_SHORT_HITBOX | ACT_FLAG_ALLOW_FIRST_PERSON | ACT_FLAG_PAUSE_EXIT) #define ACT_START_CROUCHING 0x0C008221 // (0x021 | ACT_FLAG_STATIONARY | ACT_FLAG_SHORT_HITBOX | ACT_FLAG_ALLOW_FIRST_PERSON | ACT_FLAG_PAUSE_EXIT)
#define ACT_STOP_CROUCHING 0x0C008222 // (0x022 | ACT_FLAG_STATIONARY | ACT_FLAG_SHORT_HITBOX | ACT_FLAG_ALLOW_FIRST_PERSON | ACT_FLAG_PAUSE_EXIT) #define ACT_STOP_CROUCHING 0x0C008222 // (0x022 | ACT_FLAG_STATIONARY | ACT_FLAG_SHORT_HITBOX | ACT_FLAG_ALLOW_FIRST_PERSON | ACT_FLAG_PAUSE_EXIT)

View file

@ -92,11 +92,11 @@ struct VblankHandler
struct Animation { struct Animation {
/*0x00*/ s16 flags; /*0x00*/ s16 flags;
/*0x02*/ s16 unk02; /*0x02*/ s16 animYTransDivisor;
/*0x04*/ s16 unk04; /*0x04*/ s16 startFrame;
/*0x06*/ s16 unk06; /*0x06*/ s16 loopStart;
/*0x08*/ s16 unk08; /*0x08*/ s16 loopEnd;
/*0x0A*/ s16 unk0A; /*0x0A*/ s16 unusedBoneCount;
/*0x0C*/ const s16 *values; /*0x0C*/ const s16 *values;
/*0x10*/ const u16 *index; /*0x10*/ const u16 *index;
/*0x14*/ u32 length; // only used with Mario animations to determine how much to load. 0 otherwise. /*0x14*/ u32 length; // only used with Mario animations to determine how much to load. 0 otherwise.
@ -114,8 +114,7 @@ struct GraphNode
/*0x10*/ struct GraphNode *children; /*0x10*/ struct GraphNode *children;
}; };
// struct AnimInfo? struct AnimInfo
struct GraphNodeObject_sub
{ {
/*0x00 0x38*/ s16 animID; /*0x00 0x38*/ s16 animID;
/*0x02 0x3A*/ s16 animYTrans; /*0x02 0x3A*/ s16 animYTrans;
@ -134,8 +133,8 @@ struct GraphNodeObject
{ {
/*0x00*/ struct GraphNode node; /*0x00*/ struct GraphNode node;
/*0x14*/ struct GraphNode *sharedChild; /*0x14*/ struct GraphNode *sharedChild;
/*0x18*/ s8 unk18; /*0x18*/ s8 areaIndex;
/*0x19*/ s8 unk19; /*0x19*/ s8 activeAreaIndex;
/*0x1A*/ Vec3s angle; /*0x1A*/ Vec3s angle;
/*0x20*/ Vec3f pos; /*0x20*/ Vec3f pos;
Vec3s prevAngle; Vec3s prevAngle;
@ -146,7 +145,7 @@ struct GraphNodeObject
/*0x2C*/ Vec3f scale; /*0x2C*/ Vec3f scale;
Vec3f prevScale; Vec3f prevScale;
u32 prevScaleTimestamp; u32 prevScaleTimestamp;
/*0x38*/ struct GraphNodeObject_sub unk38; /*0x38*/ struct AnimInfo animInfo;
/*0x4C*/ struct SpawnInfo *unk4C; /*0x4C*/ struct SpawnInfo *unk4C;
/*0x50*/ Mat4 *throwMatrix; // matrix ptr /*0x50*/ Mat4 *throwMatrix; // matrix ptr
Mat4 prevThrowMatrix; Mat4 prevThrowMatrix;

View file

@ -420,6 +420,12 @@ SECTIONS
/* wildcard doesn't match on EU due to files being moved to engine/ */ /* wildcard doesn't match on EU due to files being moved to engine/ */
BUILD_DIR/src/game*.o(.data*); BUILD_DIR/src/game*.o(.data*);
#endif #endif
BUILD_DIR/src/audio/synthesis.o(.data*);
BUILD_DIR/src/audio/heap.o(.data*);
BUILD_DIR/src/audio/load.o(.data*);
BUILD_DIR/src/audio/playback.o(.data*);
BUILD_DIR/src/audio/effects.o(.data*);
BUILD_DIR/src/audio/seqplayer.o(.data*);
BUILD_DIR/src/audio/external.o(.data*); BUILD_DIR/src/audio/external.o(.data*);
BUILD_DIR/src/audio/port_eu.o(.data*); BUILD_DIR/src/audio/port_eu.o(.data*);
BUILD_DIR/src/audio/data.o(.data*); BUILD_DIR/src/audio/data.o(.data*);

View file

@ -340,11 +340,11 @@ s16 gEuUnknownWave7[256] = {
0x0000, 0x8d2e, 0x4e20, 0xe14e, 0x0000, 0x1eb2, 0xb1e0, 0x72d2, 0x0000, 0x8d2e, 0x4e20, 0xe14e, 0x0000, 0x8d2e, 0x4e20, 0xe14e, 0x0000, 0x1eb2, 0xb1e0, 0x72d2, 0x0000, 0x8d2e, 0x4e20, 0xe14e,
0x0000, 0x1eb2, 0xb1e0, 0x72d2, 0x0000, 0x1eb2, 0xb1e0, 0x72d2,
}; };
// u8 buffer_remove2[764] = { 0 };
s16 *gWaveSamples[6] = { sSawtoothWaves, sTriangleWaves, sSineWaves, sSquareWaves, sEuUnknownWave6, gEuUnknownWave7 }; s16 *gWaveSamples[6] = { sSawtoothWaves, sTriangleWaves, sSineWaves, sSquareWaves, sEuUnknownWave6, gEuUnknownWave7 };
#endif
#ifndef VERSION_EU #else
// !VERSION_EU
s16 sSineWave[0x40] = { s16 sSineWave[0x40] = {
0, 3211, 6392, 9511, 12539, 15446, 18204, 20787, 23169, 25329, 27244, 0, 3211, 6392, 9511, 12539, 15446, 18204, 20787, 23169, 25329, 27244,
28897, 30272, 31356, 32137, 32609, 0x7FFF, 32609, 32137, 31356, 30272, 28897, 28897, 30272, 31356, 32137, 32609, 0x7FFF, 32609, 32137, 31356, 30272, 28897,

View file

@ -62,8 +62,8 @@ extern f32 gVolRampingRhs128[128];
// non-constant .data // non-constant .data
extern s16 gTatumsPerBeat; extern s16 gTatumsPerBeat;
extern s8 gUnusedCount80333EE8; extern s8 gUnusedCount80333EE8;
extern s32 gAudioHeapSize; extern s32 gAudioHeapSize; // AUDIO_HEAP_SIZE
extern s32 gAudioInitPoolSize; // amount of heap designated to gAudioInitPool, 0x2500 extern s32 gAudioInitPoolSize; // AUDIO_INIT_POOL_SIZE
extern volatile s32 gAudioLoadLock; extern volatile s32 gAudioLoadLock;
// .bss // .bss

View file

@ -504,6 +504,7 @@ s32 adsr_update(struct AdsrState *adsr) {
return 0.0f; return 0.0f;
} }
if (adsr->current > 1.0f) { if (adsr->current > 1.0f) {
eu_stubbed_printf_1("Audio:Envp: overflow %f\n", adsr->current);
return 1.0f; return 1.0f;
} }
return adsr->current; return adsr->current;

View file

@ -20,136 +20,6 @@
#define EU_FLOAT(x) x #define EU_FLOAT(x) x
#endif #endif
#ifdef VERSION_EU
u8 audioString1[] = "pitch %x: delaybytes %d : olddelay %d\n";
u8 audioString2[] = "cont %x: delaybytes %d : olddelay %d\n";
u8 audioString3[] = "Warning:Kill Note %x \n";
u8 audioString4[] = "Kill Voice %d (ID %d) %d\n";
u8 audioString5[] = "Warning: Running Sequence's data disappear!\n";
u8 audioString6[] = "Heap OverFlow : Not Allocate %d!\n";
u8 audioString7[] = "DataHeap Not Allocate \n";
u8 audioString8[] = "StayHeap Not Allocate %d\n";
u8 audioString9[] = "AutoHeap Not Allocate %d\n";
u8 audioString10[] = "WARNING: NO FREE AUTOSEQ AREA.\n";
u8 audioString11[] = "WARNING: NO STOP AUTO AREA.\n";
u8 audioString12[] = " AND TRY FORCE TO STOP SIDE \n";
u8 audioString13[] = "TWO SIDES ARE LOADING... ALLOC CANCELED.\n";
u8 audioString14[] = "WARNING: Before Area Overlaid After.";
u8 audioString15[] = "WARNING: After Area Overlaid Before.";
u8 audioString16[] = "MEMORY:SzHeapAlloc ERROR: sza->side %d\n";
u8 audioString17[] = "MEMORY:StayHeap OVERFLOW.";
u8 audioString18[] = "MEMORY:StayHeap OVERFLOW (REQ:%d)";
u8 audioString19[] = "Auto Heap Unhit for ID %d\n";
u8 audioString20[] = "Cache hit %d at stay %d\n";
u8 audioString20_[] = "%d ";
u8 audioString20__[] = "\n";
u8 audioString20___[] = "%d ";
u8 audioString20____[] = "\n";
u8 audioString21[] = "Heap Reconstruct Start %x\n";
u8 audioString22[] = "SFrame Sample %d %d %d\n";
u8 audioString23[] = "AHPBASE %x\n";
u8 audioString24[] = "AHPCUR %x\n";
u8 audioString25[] = "HeapTop %x\n";
u8 audioString26[] = "SynoutRate %d / %d \n";
u8 audioString27[] = "FXSIZE %d\n";
u8 audioString28[] = "FXCOMP %d\n";
u8 audioString29[] = "FXDOWN %d\n";
u8 audioString30[] = "WaveCacheLen: %d\n";
u8 audioString31[] = "SpecChange Finished\n";
u8 audioString31_[] = "";
u8 audioString32[] = "Romcopy %x -> %x ,size %x\n";
u8 audioString33[] = "Romcopyend\n";
u8 audioString34[] = "CAUTION:WAVE CACHE FULL %d";
u8 audioString35[] = "BASE %x %x\n";
u8 audioString36[] = "LOAD %x %x %x\n";
u8 audioString37[] = "INSTTOP %x\n";
u8 audioString38[] = "INSTMAP[0] %x\n";
u8 audioString39[] = "already flags %d\n";
u8 audioString40[] = "already flags %d\n";
u8 audioString41[] = "ERR:SLOW BANK DMA BUSY\n";
u8 audioString42[] = "ERR:SLOW DMA BUSY\n";
u8 audioString43[] = "Check %d bank %d\n";
u8 audioString44[] = "Cache Check\n";
u8 audioString45[] = "NO BANK ERROR\n";
u8 audioString46[] = "BANK %d LOADING START\n";
u8 audioString47[] = "BANK %d LOAD MISS (NO MEMORY)!\n";
u8 audioString48[] = "BANK %d ALREADY CACHED\n";
u8 audioString49[] = "BANK LOAD MISS! FOR %d\n";
u8 audioString50[] = "Seq %d Loading Start\n";
u8 audioString51[] = "Heap Overflow Error\n";
u8 audioString52[] = "SEQ %d ALREADY CACHED\n";
u8 audioString53[] = "Ok,one bank slow load Start \n";
u8 audioString54[] = "Sorry,too many %d bank is none.fast load Start \n";
u8 audioString55[] = "Seq %d:Default Load Id is %d\n";
u8 audioString56[] = "Seq Loading Start\n";
u8 audioString57[] = "Error:Before Sequence-SlowDma remain.\n";
u8 audioString58[] = " Cancel Seq Start.\n";
u8 audioString59[] = "SEQ %d ALREADY CACHED\n";
u8 audioString60[] = "Clear Workarea %x -%x size %x \n";
u8 audioString61[] = "AudioHeap is %x\n";
u8 audioString62[] = "Heap reset.Synth Change %x \n";
u8 audioString63[] = "Heap %x %x %x\n";
u8 audioString64[] = "Main Heap Initialize.\n";
u8 audioString65[] = "---------- Init Completed. ------------\n";
u8 audioString66[] = " Syndrv :[%6d]\n";
u8 audioString67[] = " Seqdrv :[%6d]\n";
u8 audioString68[] = " audiodata :[%6d]\n";
u8 audioString69[] = "---------------------------------------\n";
u8 audioString69_[] = "";
u8 audioString70[] = "Audio: setvol: volume minus %f\n";
u8 audioString71[] = "Audio: setvol: volume overflow %f\n";
u8 audioString72[] = "Audio: setpitch: pitch minus %f\n";
u8 audioString73[] = "Audio: voiceman: No bank error %d\n";
u8 audioString74[] = "Audio: voiceman: progNo. overflow %d,%d\n";
u8 audioString75[] = "Audio: voiceman: progNo. undefined %d,%d\n";
u8 audioString76[] = "Audio: voiceman: BAD Voicepointer %x,%d,%d\n";
u8 audioString77[] = "Audio: voiceman: Percussion Overflow %d,%d\n";
u8 audioString78[] = "Percussion Pointer Error\n";
u8 audioString79[] = "Audio: voiceman: Percpointer NULL %d,%d\n";
u8 audioString80[] = "CAUTION:SUB IS SEPARATED FROM GROUP";
u8 audioString81[] = "Error:Wait Track disappear\n";
u8 audioString82[] = "Slow Release Batting\n";
u8 audioString83[] = "Audio:Wavemem: Bad voiceno (%d)\n";
u8 audioString84[] = "Audio: C-Alloc : Dealloc voice is NULL\n";
u8 audioString85[] = "Alloc Error:Dim voice-Alloc %d";
u8 audioString86[] = "Error:Same List Add\n";
u8 audioString87[] = "Already Cut\n";
u8 audioString88[] = "Audio: C-Alloc : lowerPrio is NULL\n";
u8 audioString89[] = "Sub Limited Warning: Drop Voice";
u8 audioString90[] = "Warning: Drop Voice";
u8 audioString91[] = "Warning: Drop Voice";
u8 audioString92[] = "Warning: Drop Voice";
u8 audioString93[] = "Audio:Envp: overflow %f\n";
u8 audioString93_[] = "";
u8 audioString94[] = "Audio:Track:Warning: No Free Notetrack\n";
u8 audioString95[] = "SUBTRACK DIM\n";
u8 audioString96[] = "Audio:Track: Warning SUBTRACK PARENT CHANGED\n";
u8 audioString97[] = "GROUP 0:";
u8 audioString98[] = "GROUP 1:";
u8 audioString99[] = "SEQID %d,BANKID %d\n";
u8 audioString100[] = "ERR:SUBTRACK %d NOT ALLOCATED\n";
u8 audioString101[] = "Error:Same List Add\n";
u8 audioString102[] = "Macro Level Over Error!\n";
u8 audioString103[] = "Macro Level Over Error!\n";
u8 audioString104[] = "WARNING: NPRG: cannot change %d\n";
u8 audioString105[] = "Audio:Track:NOTE:UNDEFINED NOTE COM. %x\n";
u8 audioString106[] = "Audio: Note:Velocity Error %d\n";
u8 audioString107[] = "Error: Your assignchannel is stolen.\n";
u8 audioString108[] = "Audio:Track :Call Macro Level Over Error!\n";
u8 audioString109[] = "Audio:Track :Loops Macro Level Over Error!\n";
u8 audioString110[] = "SUB:ERR:BANK %d NOT CACHED.\n";
u8 audioString111[] = "SUB:ERR:BANK %d NOT CACHED.\n";
u8 audioString112[] = "Audio:Track: CTBLCALL Macro Level Over Error!\n";
u8 audioString113[] = "Err :Sub %x ,address %x:Undefined SubTrack Function %x";
u8 audioString114[] = "Disappear Sequence or Bank %d\n";
u8 audioString115[] = "Macro Level Over Error!\n";
u8 audioString116[] = "Macro Level Over Error!\n";
u8 audioString117[] = "Group:Undefine upper C0h command (%x)\n";
u8 audioString118[] = "Group:Undefined Command\n";
u8 audioString118_[] = "";
u8 audioString118__[] = "";
#endif
// N.B. sound banks are different from the audio banks referred to in other // N.B. sound banks are different from the audio banks referred to in other
// files. We should really fix our naming to be less ambiguous... // files. We should really fix our naming to be less ambiguous...
#define MAX_BG_MUSIC_QUEUE_SIZE 6 #define MAX_BG_MUSIC_QUEUE_SIZE 6
@ -161,15 +31,6 @@ u8 audioString118__[] = "";
#define SAMPLES_TO_OVERPRODUCE 0x10 #define SAMPLES_TO_OVERPRODUCE 0x10
#define EXTRA_BUFFERED_AI_SAMPLES_TARGET 0x40 #define EXTRA_BUFFERED_AI_SAMPLES_TARGET 0x40
// No-op printf macro which leaves string literals in rodata in IDO. (IDO
// doesn't support variadic macros, so instead they let the parameter list
// expand to a no-op comma expression.) See also goddard/gd_main.h.
#ifdef __sgi
#define stubbed_printf
#else
#define stubbed_printf(...)
#endif
struct Sound { struct Sound {
s32 soundBits; s32 soundBits;
f32 *position; f32 *position;

View file

@ -21,6 +21,9 @@
extern s32 gAudioErrorFlags; extern s32 gAudioErrorFlags;
extern f32 gDefaultSoundArgs[3]; extern f32 gDefaultSoundArgs[3];
// defined in data.c, used by the game
extern u32 gAudioRandom;
extern u8 gAudioSPTaskYieldBuffer[]; // ucode yield data ptr; only used in JP extern u8 gAudioSPTaskYieldBuffer[]; // ucode yield data ptr; only used in JP
struct SPTask *create_next_audio_frame_task(void); struct SPTask *create_next_audio_frame_task(void);

View file

@ -168,11 +168,17 @@ void discard_bank(s32 bankId) {
struct Note *note = &gNotes[i]; struct Note *note = &gNotes[i];
#ifdef VERSION_EU #ifdef VERSION_EU
if (note->noteSubEu.bankId == bankId) { if (note->noteSubEu.bankId == bankId)
#else #else
if (note->bankId == bankId) { if (note->bankId == bankId)
#endif #endif
{
// (These prints are unclear. Arguments are picked semi-randomly.)
eu_stubbed_printf_1("Warning:Kill Note %x \n", i);
if (note->priority >= NOTE_PRIORITY_MIN) { if (note->priority >= NOTE_PRIORITY_MIN) {
eu_stubbed_printf_3("Kill Voice %d (ID %d) %d\n", note->waveId,
bankId, note->priority);
eu_stubbed_printf_0("Warning: Running Sequence's data disappear!\n");
note->parentLayer->enabled = FALSE; note->parentLayer->enabled = FALSE;
note->parentLayer->finished = TRUE; note->parentLayer->finished = TRUE;
} }
@ -310,7 +316,7 @@ static void unused_803163D4(void) {
void *alloc_bank_or_seq(struct SoundMultiPool *arg0, s32 arg1, s32 size, s32 arg3, s32 id) { void *alloc_bank_or_seq(struct SoundMultiPool *arg0, s32 arg1, s32 size, s32 arg3, s32 id) {
// arg3 = 0, 1 or 2? // arg3 = 0, 1 or 2?
struct TemporaryPool *tp; // sp30 struct TemporaryPool *tp;
struct PersistentPool *persistent = &arg0->persistent; struct PersistentPool *persistent = &arg0->persistent;
struct SoundAllocPool *pool; struct SoundAllocPool *pool;
void *ret; void *ret;
@ -343,17 +349,17 @@ void *alloc_bank_or_seq(struct SoundMultiPool *arg0, s32 arg1, s32 size, s32 arg
isSound = TRUE; isSound = TRUE;
} }
firstVal = (tp->entries[0].id == (s8)nullID ? SOUND_LOAD_STATUS_NOT_LOADED : table[tp->entries[0].id]); // a3, a2 firstVal = (tp->entries[0].id == (s8)nullID ? SOUND_LOAD_STATUS_NOT_LOADED : table[tp->entries[0].id]);
secondVal = (tp->entries[1].id == (s8)nullID ? SOUND_LOAD_STATUS_NOT_LOADED : table[tp->entries[1].id]); // a1 secondVal = (tp->entries[1].id == (s8)nullID ? SOUND_LOAD_STATUS_NOT_LOADED : table[tp->entries[1].id]);
#ifndef VERSION_EU #ifndef VERSION_EU
leftNotLoaded = (firstVal == SOUND_LOAD_STATUS_NOT_LOADED); leftNotLoaded = (firstVal == SOUND_LOAD_STATUS_NOT_LOADED);
leftDiscardable = (firstVal == SOUND_LOAD_STATUS_DISCARDABLE); // t0 leftDiscardable = (firstVal == SOUND_LOAD_STATUS_DISCARDABLE);
leftAvail = (firstVal != SOUND_LOAD_STATUS_IN_PROGRESS); leftAvail = (firstVal != SOUND_LOAD_STATUS_IN_PROGRESS);
rightNotLoaded = (secondVal == SOUND_LOAD_STATUS_NOT_LOADED); rightNotLoaded = (secondVal == SOUND_LOAD_STATUS_NOT_LOADED);
rightDiscardable = (secondVal == SOUND_LOAD_STATUS_DISCARDABLE); rightDiscardable = (secondVal == SOUND_LOAD_STATUS_DISCARDABLE);
rightAvail = (secondVal != SOUND_LOAD_STATUS_IN_PROGRESS); rightAvail = (secondVal != SOUND_LOAD_STATUS_IN_PROGRESS);
bothDiscardable = (leftDiscardable && rightDiscardable); // a0 bothDiscardable = (leftDiscardable && rightDiscardable);
if (leftNotLoaded) { if (leftNotLoaded) {
tp->nextSide = 0; tp->nextSide = 0;
@ -361,7 +367,7 @@ void *alloc_bank_or_seq(struct SoundMultiPool *arg0, s32 arg1, s32 size, s32 arg
tp->nextSide = 1; tp->nextSide = 1;
} else if (bothDiscardable) { } else if (bothDiscardable) {
// Use the opposite side from last time. // Use the opposite side from last time.
} else if (firstVal == SOUND_LOAD_STATUS_DISCARDABLE) { //??! } else if (firstVal == SOUND_LOAD_STATUS_DISCARDABLE) { // ??! (I blame copt)
tp->nextSide = 0; tp->nextSide = 0;
} else if (rightDiscardable) { } else if (rightDiscardable) {
tp->nextSide = 1; tp->nextSide = 1;
@ -374,27 +380,42 @@ void *alloc_bank_or_seq(struct SoundMultiPool *arg0, s32 arg1, s32 size, s32 arg
return NULL; return NULL;
} }
#else #else
if (0) {
// It's unclear where these string literals go.
eu_stubbed_printf_0("DataHeap Not Allocate \n");
eu_stubbed_printf_1("StayHeap Not Allocate %d\n", 0);
eu_stubbed_printf_1("AutoHeap Not Allocate %d\n", 0);
}
if (firstVal == SOUND_LOAD_STATUS_NOT_LOADED) { if (firstVal == SOUND_LOAD_STATUS_NOT_LOADED) {
tp->nextSide = 0; tp->nextSide = 0;
} else if (secondVal == SOUND_LOAD_STATUS_NOT_LOADED) { } else if (secondVal == SOUND_LOAD_STATUS_NOT_LOADED) {
tp->nextSide = 1; tp->nextSide = 1;
} else if ((firstVal == SOUND_LOAD_STATUS_DISCARDABLE) && (secondVal == SOUND_LOAD_STATUS_DISCARDABLE)) {
// Use the opposite side from last time.
} else if (firstVal == SOUND_LOAD_STATUS_DISCARDABLE) {
tp->nextSide = 0;
} else if (secondVal == SOUND_LOAD_STATUS_DISCARDABLE) {
tp->nextSide = 1;
} else if (firstVal != SOUND_LOAD_STATUS_IN_PROGRESS) {
tp->nextSide = 0;
} else if (secondVal != SOUND_LOAD_STATUS_IN_PROGRESS) {
tp->nextSide = 1;
} else { } else {
// Both left and right sides are being loaded into. eu_stubbed_printf_0("WARNING: NO FREE AUTOSEQ AREA.\n");
return NULL; if ((firstVal == SOUND_LOAD_STATUS_DISCARDABLE) && (secondVal == SOUND_LOAD_STATUS_DISCARDABLE)) {
// Use the opposite side from last time.
} else if (firstVal == SOUND_LOAD_STATUS_DISCARDABLE) {
tp->nextSide = 0;
} else if (secondVal == SOUND_LOAD_STATUS_DISCARDABLE) {
tp->nextSide = 1;
} else {
eu_stubbed_printf_0("WARNING: NO STOP AUTO AREA.\n");
eu_stubbed_printf_0(" AND TRY FORCE TO STOP SIDE \n");
if (firstVal != SOUND_LOAD_STATUS_IN_PROGRESS) {
tp->nextSide = 0;
} else if (secondVal != SOUND_LOAD_STATUS_IN_PROGRESS) {
tp->nextSide = 1;
} else {
// Both left and right sides are being loaded into.
eu_stubbed_printf_0("TWO SIDES ARE LOADING... ALLOC CANCELED.\n");
return NULL;
}
}
} }
#endif #endif
pool = &arg0->temporary.pool; // a1 pool = &arg0->temporary.pool;
if (tp->entries[tp->nextSide].id != (s8)nullID) { if (tp->entries[tp->nextSide].id != (s8)nullID) {
table[tp->entries[tp->nextSide].id] = SOUND_LOAD_STATUS_NOT_LOADED; table[tp->entries[tp->nextSide].id] = SOUND_LOAD_STATUS_NOT_LOADED;
if (isSound == TRUE) { if (isSound == TRUE) {
@ -411,6 +432,8 @@ void *alloc_bank_or_seq(struct SoundMultiPool *arg0, s32 arg1, s32 size, s32 arg
pool->cur = pool->start + size; pool->cur = pool->start + size;
if (tp->entries[1].ptr < pool->cur) { if (tp->entries[1].ptr < pool->cur) {
eu_stubbed_printf_0("WARNING: Before Area Overlaid After.");
// Throw out the entry on the other side if it doesn't fit. // Throw out the entry on the other side if it doesn't fit.
// (possible @bug: what if it's currently being loaded?) // (possible @bug: what if it's currently being loaded?)
table[tp->entries[1].id] = SOUND_LOAD_STATUS_NOT_LOADED; table[tp->entries[1].id] = SOUND_LOAD_STATUS_NOT_LOADED;
@ -445,6 +468,8 @@ void *alloc_bank_or_seq(struct SoundMultiPool *arg0, s32 arg1, s32 size, s32 arg
tp->entries[1].size = size; tp->entries[1].size = size;
if (tp->entries[1].ptr < pool->cur) { if (tp->entries[1].ptr < pool->cur) {
eu_stubbed_printf_0("WARNING: After Area Overlaid Before.");
table[tp->entries[0].id] = SOUND_LOAD_STATUS_NOT_LOADED; table[tp->entries[0].id] = SOUND_LOAD_STATUS_NOT_LOADED;
switch (isSound) { switch (isSound) {
@ -464,6 +489,7 @@ void *alloc_bank_or_seq(struct SoundMultiPool *arg0, s32 arg1, s32 size, s32 arg
break; break;
default: default:
eu_stubbed_printf_1("MEMORY:SzHeapAlloc ERROR: sza->side %d\n", tp->nextSide);
return NULL; return NULL;
} }
@ -487,6 +513,7 @@ void *alloc_bank_or_seq(struct SoundMultiPool *arg0, s32 arg1, s32 size, s32 arg
{ {
switch (arg3) { switch (arg3) {
case 2: case 2:
eu_stubbed_printf_0("MEMORY:StayHeap OVERFLOW.");
#ifdef VERSION_EU #ifdef VERSION_EU
return alloc_bank_or_seq(arg0, arg1, size, 0, id); return alloc_bank_or_seq(arg0, arg1, size, 0, id);
#else #else
@ -495,6 +522,7 @@ void *alloc_bank_or_seq(struct SoundMultiPool *arg0, s32 arg1, s32 size, s32 arg
return ret; return ret;
#endif #endif
case 1: case 1:
eu_stubbed_printf_1("MEMORY:StayHeap OVERFLOW (REQ:%d)", arg1 * size);
return NULL; return NULL;
} }
} }
@ -524,11 +552,13 @@ void *get_bank_or_seq(struct SoundMultiPool *arg0, s32 arg1, s32 id) {
temporary->nextSide = 0; temporary->nextSide = 0;
return temporary->entries[1].ptr; return temporary->entries[1].ptr;
} }
eu_stubbed_printf_1("Auto Heap Unhit for ID %d\n", id);
return NULL; return NULL;
} else { } else {
struct PersistentPool *persistent = &arg0->persistent; struct PersistentPool *persistent = &arg0->persistent;
for (i = 0; i < persistent->numEntries; i++) { for (i = 0; i < persistent->numEntries; i++) {
if (id == persistent->entries[i].id) { if (id == persistent->entries[i].id) {
eu_stubbed_printf_2("Cache hit %d at stay %d\n", id, i);
return persistent->entries[i].ptr; return persistent->entries[i].ptr;
} }
} }
@ -538,7 +568,7 @@ void *get_bank_or_seq(struct SoundMultiPool *arg0, s32 arg1, s32 id) {
return get_bank_or_seq(arg0, 0, id); return get_bank_or_seq(arg0, 0, id);
#else #else
// Prevent tail call optimization by using a temporary. // Prevent tail call optimization by using a temporary.
// (Did they compile with -Wo,-notail?) // Either copt or -Wo,-notail.
ret = get_bank_or_seq(arg0, 0, id); ret = get_bank_or_seq(arg0, 0, id);
return ret; return ret;
#endif #endif
@ -568,25 +598,27 @@ void func_eu_802e27e4_unused(f32 arg0, f32 arg1, u16 *arg2) {
} }
for (i = 0; i < 8; i++) { for (i = 0; i < 8; i++) {
eu_stubbed_printf_1("%d ", arg2[i]);
} }
eu_stubbed_printf_0("\n");
for (i = 8; i < 16; i += 4) { for (i = 8; i < 16; i++) {
eu_stubbed_printf_1("%d ", arg2[i]);
} }
eu_stubbed_printf_0("\n");
} }
#endif #endif
#ifdef VERSION_EU
void decrease_reverb_gain(void) { void decrease_reverb_gain(void) {
#ifdef VERSION_EU
s32 i; s32 i;
for (i = 0; i < gNumSynthesisReverbs; i++) { for (i = 0; i < gNumSynthesisReverbs; i++) {
gSynthesisReverbs[i].reverbGain -= gSynthesisReverbs[i].reverbGain / 8; gSynthesisReverbs[i].reverbGain -= gSynthesisReverbs[i].reverbGain / 8;
} }
}
#else #else
void decrease_reverb_gain(void) {
gSynthesisReverb.reverbGain -= gSynthesisReverb.reverbGain / 4; gSynthesisReverb.reverbGain -= gSynthesisReverb.reverbGain / 4;
}
#endif #endif
}
#ifdef VERSION_EU #ifdef VERSION_EU
s32 audio_shut_down_and_reset_step(void) { s32 audio_shut_down_and_reset_step(void) {
@ -676,10 +708,10 @@ void audio_reset_session(void) {
#ifndef VERSION_EU #ifndef VERSION_EU
s32 frames; s32 frames;
s32 remainingDmas; s32 remainingDmas;
#endif #else
#ifdef VERSION_EU
struct SynthesisReverb *reverb; struct SynthesisReverb *reverb;
#endif #endif
eu_stubbed_printf_1("Heap Reconstruct Start %x\n", gAudioResetPresetIdToLoad);
#ifndef VERSION_EU #ifndef VERSION_EU
if (gAudioLoadLock != AUDIO_LOCK_UNINITIALIZED) { if (gAudioLoadLock != AUDIO_LOCK_UNINITIALIZED) {
@ -933,3 +965,16 @@ void audio_reset_session(void) {
} }
#endif #endif
} }
#ifdef VERSION_EU
u8 audioString22[] = "SFrame Sample %d %d %d\n";
u8 audioString23[] = "AHPBASE %x\n";
u8 audioString24[] = "AHPCUR %x\n";
u8 audioString25[] = "HeapTop %x\n";
u8 audioString26[] = "SynoutRate %d / %d \n";
u8 audioString27[] = "FXSIZE %d\n";
u8 audioString28[] = "FXCOMP %d\n";
u8 audioString29[] = "FXDOWN %d\n";
u8 audioString30[] = "WaveCacheLen: %d\n";
u8 audioString31[] = "SpecChange Finished\n";
#endif

View file

@ -63,6 +63,29 @@
#define FLOAT_CAST(x) (f32) (s32) (x) #define FLOAT_CAST(x) (f32) (s32) (x)
#endif #endif
// No-op printf macro which leaves string literals in rodata in IDO. IDO
// doesn't support variadic macros, so instead we let the parameter list
// expand to a no-op comma expression. Another possibility is that it might
// have expanded to something with "if (0)". See also goddard/gd_main.h.
// On US/JP, -sopt optimizes away these except for external.c.
#ifdef __sgi
#define stubbed_printf
#else
#define stubbed_printf(...)
#endif
#ifdef VERSION_EU
#define eu_stubbed_printf_0(msg) stubbed_printf(msg)
#define eu_stubbed_printf_1(msg, a) stubbed_printf(msg, a)
#define eu_stubbed_printf_2(msg, a, b) stubbed_printf(msg, a, b)
#define eu_stubbed_printf_3(msg, a, b, c) stubbed_printf(msg, a, b, c)
#else
#define eu_stubbed_printf_0(msg)
#define eu_stubbed_printf_1(msg, a)
#define eu_stubbed_printf_2(msg, a, b)
#define eu_stubbed_printf_3(msg, a, b, c)
#endif
struct NotePool; struct NotePool;
struct AudioListItem struct AudioListItem
@ -202,6 +225,7 @@ struct M64ScriptState {
u8 depth; u8 depth;
}; // size = 0x1C }; // size = 0x1C
// Also known as a Group, according to debug strings.
struct SequencePlayer struct SequencePlayer
{ {
/*US/JP, EU */ /*US/JP, EU */
@ -327,6 +351,8 @@ struct NoteAttributes
#endif #endif
}; // size = 0x10 }; // size = 0x10
// Also known as a SubTrack, according to debug strings.
// Confusingly, a SubTrack is a container of Tracks.
struct SequenceChannel struct SequenceChannel
{ {
/* U/J, EU */ /* U/J, EU */
@ -395,7 +421,8 @@ struct SequenceChannel
/*0x80, 0x84*/ struct NotePool notePool; /*0x80, 0x84*/ struct NotePool notePool;
}; // size = 0xC0, 0xC4 in EU }; // size = 0xC0, 0xC4 in EU
struct SequenceChannelLayer // Maybe SequenceTrack? // Also known as a Track, according to debug strings.
struct SequenceChannelLayer
{ {
/* U/J, EU */ /* U/J, EU */
/*0x00, 0x00*/ u8 enabled : 1; /*0x00, 0x00*/ u8 enabled : 1;
@ -508,6 +535,16 @@ struct Note
/* U/J, EU */ /* U/J, EU */
/*0xA4, 0x00*/ struct AudioListItem listItem; /*0xA4, 0x00*/ struct AudioListItem listItem;
/* 0x10*/ struct NoteSynthesisState synthesisState; /* 0x10*/ struct NoteSynthesisState synthesisState;
// The next members are actually part of a struct (NotePlaybackState), but
// that results in messy US/EU ifdefs. Instead we cast to a struct pointer
// when needed... This breaks alignment on non-N64 platforms, which we hack
// around by skipping the padding in that case.
// TODO: use macros or something instead.
#ifdef TARGET_N64
u8 pad0[12];
#endif
/*0x04, 0x30*/ u8 priority; /*0x04, 0x30*/ u8 priority;
/* 0x31*/ u8 waveId; /* 0x31*/ u8 waveId;
/* 0x32*/ u8 sampleCountIndex; /* 0x32*/ u8 sampleCountIndex;
@ -525,6 +562,7 @@ struct Note
/* , 0xB0*/ struct NoteSubEu noteSubEu; /* , 0xB0*/ struct NoteSubEu noteSubEu;
}; // size = 0xC0 }; // size = 0xC0
#else #else
// volatile Note, needed in synthesis_process_notes
struct vNote struct vNote
{ {
/* U/J, EU */ /* U/J, EU */

View file

@ -112,12 +112,33 @@ extern u8 gBankSetsData[]; // bank_sets.s
* Performs an immediate DMA copy * Performs an immediate DMA copy
*/ */
void audio_dma_copy_immediate(uintptr_t devAddr, void *vAddr, size_t nbytes) { void audio_dma_copy_immediate(uintptr_t devAddr, void *vAddr, size_t nbytes) {
eu_stubbed_printf_3("Romcopy %x -> %x ,size %x\n", devAddr, vAddr, nbytes);
osInvalDCache(vAddr, nbytes); osInvalDCache(vAddr, nbytes);
osPiStartDma(&gAudioDmaIoMesg, OS_MESG_PRI_HIGH, OS_READ, devAddr, vAddr, nbytes, osPiStartDma(&gAudioDmaIoMesg, OS_MESG_PRI_HIGH, OS_READ, devAddr, vAddr, nbytes,
&gAudioDmaMesgQueue); &gAudioDmaMesgQueue);
osRecvMesg(&gAudioDmaMesgQueue, NULL, OS_MESG_BLOCK); osRecvMesg(&gAudioDmaMesgQueue, NULL, OS_MESG_BLOCK);
eu_stubbed_printf_0("Romcopyend\n");
} }
#ifdef VERSION_EU
u8 audioString34[] = "CAUTION:WAVE CACHE FULL %d";
u8 audioString35[] = "BASE %x %x\n";
u8 audioString36[] = "LOAD %x %x %x\n";
u8 audioString37[] = "INSTTOP %x\n";
u8 audioString38[] = "INSTMAP[0] %x\n";
u8 audioString39[] = "already flags %d\n";
u8 audioString40[] = "already flags %d\n";
u8 audioString41[] = "ERR:SLOW BANK DMA BUSY\n";
u8 audioString42[] = "ERR:SLOW DMA BUSY\n";
u8 audioString43[] = "Check %d bank %d\n";
u8 audioString44[] = "Cache Check\n";
u8 audioString45[] = "NO BANK ERROR\n";
u8 audioString46[] = "BANK %d LOADING START\n";
u8 audioString47[] = "BANK %d LOAD MISS (NO MEMORY)!\n";
u8 audioString48[] = "BANK %d ALREADY CACHED\n";
u8 audioString49[] = "BANK LOAD MISS! FOR %d\n";
#endif
/** /**
* Performs an asynchronus (normal priority) DMA copy * Performs an asynchronus (normal priority) DMA copy
*/ */
@ -664,11 +685,13 @@ void *sequence_dma_async(s32 seqId, s32 arg1, struct SequencePlayer *seqPlayer)
u8 *seqData; u8 *seqData;
OSMesgQueue *mesgQueue; OSMesgQueue *mesgQueue;
eu_stubbed_printf_1("Seq %d Loading Start\n", seqId);
seqLength = gSeqFileHeader->seqArray[seqId].len + 0xf; seqLength = gSeqFileHeader->seqArray[seqId].len + 0xf;
seqLength = ALIGN16(seqLength); seqLength = ALIGN16(seqLength);
seqData = gSeqFileHeader->seqArray[seqId].offset; seqData = gSeqFileHeader->seqArray[seqId].offset;
ptr = alloc_bank_or_seq(&gSeqLoadedPool, 1, seqLength, arg1, seqId); ptr = alloc_bank_or_seq(&gSeqLoadedPool, 1, seqLength, arg1, seqId);
if (ptr == NULL) { if (ptr == NULL) {
eu_stubbed_printf_0("Heap Overflow Error\n");
return NULL; return NULL;
} }
@ -676,8 +699,8 @@ void *sequence_dma_async(s32 seqId, s32 arg1, struct SequencePlayer *seqPlayer)
// Immediately load short sequenece // Immediately load short sequenece
audio_dma_copy_immediate((uintptr_t) seqData, ptr, seqLength); audio_dma_copy_immediate((uintptr_t) seqData, ptr, seqLength);
if (1) { if (1) {
gSeqLoadStatus[seqId] = SOUND_LOAD_STATUS_COMPLETE;
} }
gSeqLoadStatus[seqId] = SOUND_LOAD_STATUS_COMPLETE;
} else { } else {
audio_dma_copy_immediate((uintptr_t) seqData, ptr, 0x40); audio_dma_copy_immediate((uintptr_t) seqData, ptr, 0x40);
mesgQueue = &seqPlayer->seqDmaMesgQueue; mesgQueue = &seqPlayer->seqDmaMesgQueue;
@ -740,12 +763,12 @@ struct AudioBank *load_banks_immediate(s32 seqId, u8 *arg1) {
u16 offset; u16 offset;
u8 i; u8 i;
#ifdef VERSION_EU
offset = ((u16 *) gAlBankSets)[seqId]; offset = ((u16 *) gAlBankSets)[seqId];
#ifdef VERSION_EU
for (i = gAlBankSets[offset++]; i != 0; i--) { for (i = gAlBankSets[offset++]; i != 0; i--) {
bankId = gAlBankSets[offset++]; bankId = gAlBankSets[offset++];
#else #else
offset = ((u16 *) gAlBankSets)[seqId] + 1; offset++;
for (i = gAlBankSets[offset - 1]; i != 0; i--) { for (i = gAlBankSets[offset - 1]; i != 0; i--) {
offset++; offset++;
bankId = gAlBankSets[offset - 1]; bankId = gAlBankSets[offset - 1];
@ -785,6 +808,7 @@ void preload_sequence(u32 seqId, u8 preloadMask) {
if (preloadMask & PRELOAD_SEQUENCE) { if (preloadMask & PRELOAD_SEQUENCE) {
// @bug should be IS_SEQ_LOAD_COMPLETE // @bug should be IS_SEQ_LOAD_COMPLETE
if (IS_BANK_LOAD_COMPLETE(seqId) == TRUE) { if (IS_BANK_LOAD_COMPLETE(seqId) == TRUE) {
eu_stubbed_printf_1("SEQ %d ALREADY CACHED\n", seqId);
sequenceData = get_bank_or_seq(&gSeqLoadedPool, 2, seqId); sequenceData = get_bank_or_seq(&gSeqLoadedPool, 2, seqId);
} else { } else {
sequenceData = NULL; sequenceData = NULL;
@ -826,6 +850,7 @@ void load_sequence_internal(u32 player, u32 seqId, s32 loadAsync) {
s32 dummy = 0; s32 dummy = 0;
s32 bankId = get_missing_bank(seqId, &dummy, &numMissingBanks); s32 bankId = get_missing_bank(seqId, &dummy, &numMissingBanks);
if (numMissingBanks == 1) { if (numMissingBanks == 1) {
eu_stubbed_printf_0("Ok,one bank slow load Start \n");
if (bank_load_async(bankId, 2, seqPlayer) == NULL) { if (bank_load_async(bankId, 2, seqPlayer) == NULL) {
return; return;
} }
@ -833,17 +858,25 @@ void load_sequence_internal(u32 player, u32 seqId, s32 loadAsync) {
// as default, not the missing one. This code path never gets // as default, not the missing one. This code path never gets
// taken, though -- all sequence loading is synchronous. // taken, though -- all sequence loading is synchronous.
seqPlayer->defaultBank[0] = bankId; seqPlayer->defaultBank[0] = bankId;
} else if (load_banks_immediate(seqId, &seqPlayer->defaultBank[0]) == NULL) { } else {
return; eu_stubbed_printf_1("Sorry,too many %d bank is none.fast load Start \n", numMissingBanks);
if (load_banks_immediate(seqId, &seqPlayer->defaultBank[0]) == NULL) {
return;
}
} }
} else if (load_banks_immediate(seqId, &seqPlayer->defaultBank[0]) == NULL) { } else if (load_banks_immediate(seqId, &seqPlayer->defaultBank[0]) == NULL) {
return; return;
} }
eu_stubbed_printf_2("Seq %d:Default Load Id is %d\n", seqId, seqPlayer->defaultBank[0]);
eu_stubbed_printf_0("Seq Loading Start\n");
seqPlayer->seqId = seqId; seqPlayer->seqId = seqId;
sequenceData = get_bank_or_seq(&gSeqLoadedPool, 2, seqId); sequenceData = get_bank_or_seq(&gSeqLoadedPool, 2, seqId);
if (sequenceData == NULL) { if (sequenceData == NULL) {
if (seqPlayer->seqDmaInProgress) { if (seqPlayer->seqDmaInProgress) {
eu_stubbed_printf_0("Error:Before Sequence-SlowDma remain.\n");
eu_stubbed_printf_0(" Cancel Seq Start.\n");
return; return;
} }
@ -858,6 +891,7 @@ void load_sequence_internal(u32 player, u32 seqId, s32 loadAsync) {
} }
} }
eu_stubbed_printf_1("SEQ %d ALREADY CACHED\n", seqId);
init_sequence_player(player); init_sequence_player(player);
seqPlayer->scriptState.depth = 0; seqPlayer->scriptState.depth = 0;
seqPlayer->delay = 0; seqPlayer->delay = 0;
@ -927,6 +961,16 @@ void audio_init() {
} }
#endif #endif
#ifdef TARGET_N64
eu_stubbed_printf_3("Clear Workarea %x -%x size %x \n",
(uintptr_t) &gAudioGlobalsStartMarker,
(uintptr_t) &gAudioGlobalsEndMarker,
(uintptr_t) &gAudioGlobalsEndMarker - (uintptr_t) &gAudioGlobalsStartMarker
);
#endif
eu_stubbed_printf_1("AudioHeap is %x\n", gAudioHeapSize);
for (i = 0; i < NUMAIBUFFERS; i++) { for (i = 0; i < NUMAIBUFFERS; i++) {
gAiBufferLengths[i] = 0xa0; gAiBufferLengths[i] = 0xa0;
} }
@ -959,6 +1003,11 @@ void audio_init() {
audio_reset_session(&gAudioSessionPresets[0]); audio_reset_session(&gAudioSessionPresets[0]);
#endif #endif
// Not sure about these prints
eu_stubbed_printf_1("Heap reset.Synth Change %x \n", 0);
eu_stubbed_printf_3("Heap %x %x %x\n", 0, 0, 0);
eu_stubbed_printf_0("Main Heap Initialize.\n");
// Load header for sequence data (assets/music_data.sbk.s) // Load header for sequence data (assets/music_data.sbk.s)
gSeqFileHeader = (ALSeqFile *) buf; gSeqFileHeader = (ALSeqFile *) buf;
data = LOAD_DATA(gMusicData); data = LOAD_DATA(gMusicData);
@ -1003,5 +1052,12 @@ void audio_init() {
init_sequence_players(); init_sequence_players();
gAudioLoadLock = AUDIO_LOCK_NOT_LOADING; gAudioLoadLock = AUDIO_LOCK_NOT_LOADING;
}
// Should probably contain the sizes of the data banks, but those aren't
// easily accessible from here.
eu_stubbed_printf_0("---------- Init Completed. ------------\n");
eu_stubbed_printf_1(" Syndrv :[%6d]\n", 0); // gSoundDataADSR
eu_stubbed_printf_1(" Seqdrv :[%6d]\n", 0); // gMusicData
eu_stubbed_printf_1(" audiodata :[%6d]\n", 0); // gSoundDataRaw
eu_stubbed_printf_0("---------------------------------------\n");
}

View file

@ -31,6 +31,7 @@ extern struct NotePool gNoteFreeLists;
extern OSMesgQueue gCurrAudioFrameDmaQueue; extern OSMesgQueue gCurrAudioFrameDmaQueue;
extern u32 gSampleDmaNumListItems; extern u32 gSampleDmaNumListItems;
extern ALSeqFile *gAlTbl; extern ALSeqFile *gAlTbl;
extern ALSeqFile *gSeqFileHeader;
extern u8 *gAlBankSets; extern u8 *gAlBankSets;
extern struct CtlEntry *gCtlEntries; extern struct CtlEntry *gCtlEntries;

View file

@ -55,8 +55,14 @@ void note_set_vel_pan_reverb(struct Note *note, f32 velocity, u8 pan, u8 reverb)
volRight = gDefaultPanVolume[127 - pan]; volRight = gDefaultPanVolume[127 - pan];
} }
velocity = MAX(0.0f, velocity); if (velocity < 0.0f) {
velocity = MIN(32767.f, velocity); stubbed_printf("Audio: setvol: volume minus %f\n", velocity);
velocity = 0.0f;
}
if (velocity > 32767.f) {
stubbed_printf("Audio: setvol: volume overflow %f\n", velocity);
velocity = 32767.f;
}
sub->targetVolLeft = ((s32) (velocity * volLeft) & 0xffff) >> 5; sub->targetVolLeft = ((s32) (velocity * volLeft) & 0xffff) >> 5;
sub->targetVolRight = ((s32) (velocity * volRight) & 0xffff) >> 5; sub->targetVolRight = ((s32) (velocity * volRight) & 0xffff) >> 5;
@ -79,6 +85,7 @@ void note_set_resampling_rate(struct Note *note, f32 resamplingRateInput) {
struct NoteSubEu *tempSub = &note->noteSubEu; struct NoteSubEu *tempSub = &note->noteSubEu;
if (resamplingRateInput < 0.0f) { if (resamplingRateInput < 0.0f) {
stubbed_printf("Audio: setpitch: pitch minus %f\n", resamplingRateInput);
resamplingRateInput = 0.0f; resamplingRateInput = 0.0f;
} }
if (resamplingRateInput < 2.0f) { if (resamplingRateInput < 2.0f) {
@ -117,17 +124,21 @@ struct Instrument *get_instrument_inner(s32 bankId, s32 instId) {
struct Instrument *inst; struct Instrument *inst;
if (IS_BANK_LOAD_COMPLETE(bankId) == FALSE) { if (IS_BANK_LOAD_COMPLETE(bankId) == FALSE) {
stubbed_printf("Audio: voiceman: No bank error %d\n", bankId);
gAudioErrorFlags = bankId + 0x10000000; gAudioErrorFlags = bankId + 0x10000000;
return NULL; return NULL;
} }
if (instId >= gCtlEntries[bankId].numInstruments) { if (instId >= gCtlEntries[bankId].numInstruments) {
stubbed_printf("Audio: voiceman: progNo. overflow %d,%d\n",
instId, gCtlEntries[bankId].numInstruments);
gAudioErrorFlags = ((bankId << 8) + instId) + 0x3000000; gAudioErrorFlags = ((bankId << 8) + instId) + 0x3000000;
return NULL; return NULL;
} }
inst = gCtlEntries[bankId].instruments[instId]; inst = gCtlEntries[bankId].instruments[instId];
if (inst == NULL) { if (inst == NULL) {
stubbed_printf("Audio: voiceman: progNo. undefined %d,%d\n", bankId, instId);
gAudioErrorFlags = ((bankId << 8) + instId) + 0x1000000; gAudioErrorFlags = ((bankId << 8) + instId) + 0x1000000;
return inst; return inst;
} }
@ -141,6 +152,7 @@ struct Instrument *get_instrument_inner(s32 bankId, s32 instId) {
return inst; return inst;
} }
stubbed_printf("Audio: voiceman: BAD Voicepointer %x,%d,%d\n", inst, bankId, instId);
gAudioErrorFlags = ((bankId << 8) + instId) + 0x2000000; gAudioErrorFlags = ((bankId << 8) + instId) + 0x2000000;
return NULL; return NULL;
} }
@ -148,11 +160,14 @@ struct Instrument *get_instrument_inner(s32 bankId, s32 instId) {
struct Drum *get_drum(s32 bankId, s32 drumId) { struct Drum *get_drum(s32 bankId, s32 drumId) {
struct Drum *drum; struct Drum *drum;
if (drumId >= gCtlEntries[bankId].numDrums) { if (drumId >= gCtlEntries[bankId].numDrums) {
stubbed_printf("Audio: voiceman: Percussion Overflow %d,%d\n",
drumId, gCtlEntries[bankId].numDrums);
gAudioErrorFlags = ((bankId << 8) + drumId) + 0x4000000; gAudioErrorFlags = ((bankId << 8) + drumId) + 0x4000000;
return 0; return NULL;
} }
drum = gCtlEntries[bankId].drums[drumId]; drum = gCtlEntries[bankId].drums[drumId];
if (drum == NULL) { if (drum == NULL) {
stubbed_printf("Audio: voiceman: Percpointer NULL %d,%d\n", bankId, drumId);
gAudioErrorFlags = ((bankId << 8) + drumId) + 0x5000000; gAudioErrorFlags = ((bankId << 8) + drumId) + 0x5000000;
} }
return drum; return drum;
@ -227,8 +242,8 @@ void process_notes(void) {
#endif #endif
s32 i; s32 i;
// Macro versions of audio_list_push_front and audio_list_remove // Macro versions of audio_list_push_front and audio_list_remove.
// (PREPEND does not actually need to be a macro, but it seems likely.) // Should ideally be changed to use copt.
#define PREPEND(item, head_arg) \ #define PREPEND(item, head_arg) \
((it = (item), it->prev != NULL) \ ((it = (item), it->prev != NULL) \
? it \ ? it \
@ -247,6 +262,7 @@ void process_notes(void) {
if (!playbackState->parentLayer->enabled && playbackState->priority >= NOTE_PRIORITY_MIN) { if (!playbackState->parentLayer->enabled && playbackState->priority >= NOTE_PRIORITY_MIN) {
goto c; goto c;
} else if (playbackState->parentLayer->seqChannel->seqPlayer == NULL) { } else if (playbackState->parentLayer->seqChannel->seqPlayer == NULL) {
eu_stubbed_printf_0("CAUTION:SUB IS SEPARATED FROM GROUP");
sequence_channel_disable(playbackState->parentLayer->seqChannel); sequence_channel_disable(playbackState->parentLayer->seqChannel);
playbackState->priority = NOTE_PRIORITY_STOPPING; playbackState->priority = NOTE_PRIORITY_STOPPING;
continue; continue;
@ -282,6 +298,7 @@ void process_notes(void) {
playbackState->wantedParentLayer = NO_LAYER; playbackState->wantedParentLayer = NO_LAYER;
// don't skip // don't skip
} else { } else {
eu_stubbed_printf_0("Error:Wait Track disappear\n");
note_disable(note); note_disable(note);
audio_list_remove(&note->listItem); audio_list_remove(&note->listItem);
audio_list_push_back(&note->listItem.pool->disabled, &note->listItem); audio_list_push_back(&note->listItem.pool->disabled, &note->listItem);
@ -425,7 +442,10 @@ void seq_channel_layer_decay_release_internal(struct SequenceChannelLayer *seqLa
if (note->parentLayer != seqLayer) { if (note->parentLayer != seqLayer) {
#ifdef VERSION_EU #ifdef VERSION_EU
if (note->parentLayer == NO_LAYER && note->wantedParentLayer == NO_LAYER && note->prevParentLayer == seqLayer && target != ADSR_STATE_DECAY) { if (note->parentLayer == NO_LAYER && note->wantedParentLayer == NO_LAYER &&
note->prevParentLayer == seqLayer && target != ADSR_STATE_DECAY) {
// Just guessing that this printf goes here... it's hard to parse.
eu_stubbed_printf_0("Slow Release Batting\n");
note->adsr.fadeOutVel = gAudioBufferParameters.updatesPerFrameInv; note->adsr.fadeOutVel = gAudioBufferParameters.updatesPerFrameInv;
note->adsr.action |= ADSR_ACTION_RELEASE; note->adsr.action |= ADSR_ACTION_RELEASE;
} }
@ -493,6 +513,7 @@ s32 build_synthetic_wave(struct Note *note, struct SequenceChannelLayer *seqLaye
u8 sampleCountIndex; u8 sampleCountIndex;
if (waveId < 128) { if (waveId < 128) {
stubbed_printf("Audio:Wavemem: Bad voiceno (%d)\n", waveId);
waveId = 128; waveId = 128;
} }
@ -521,6 +542,7 @@ s32 build_synthetic_wave(struct Note *note, struct SequenceChannelLayer *seqLaye
return sampleCountIndex; return sampleCountIndex;
} }
#else #else
void build_synthetic_wave(struct Note *note, struct SequenceChannelLayer *seqLayer) { void build_synthetic_wave(struct Note *note, struct SequenceChannelLayer *seqLayer) {
s32 i; s32 i;
@ -661,7 +683,11 @@ void note_pool_clear(struct NotePool *pool) {
#ifdef VERSION_EU #ifdef VERSION_EU
for (;;) { for (;;) {
cur = source->next; cur = source->next;
if (cur == source || cur == NULL) { if (cur == source) {
break;
}
if (cur == NULL) {
eu_stubbed_printf_0("Audio: C-Alloc : Dealloc voice is NULL\n");
break; break;
} }
audio_list_remove(cur); audio_list_remove(cur);
@ -693,6 +719,7 @@ void note_pool_fill(struct NotePool *pool, s32 count) {
for (i = 0, j = 0; j < count; i++) { for (i = 0, j = 0; j < count; i++) {
if (i == 4) { if (i == 4) {
eu_stubbed_printf_1("Alloc Error:Dim voice-Alloc %d", count);
return; return;
} }
@ -731,7 +758,9 @@ void note_pool_fill(struct NotePool *pool, s32 count) {
void audio_list_push_front(struct AudioListItem *list, struct AudioListItem *item) { void audio_list_push_front(struct AudioListItem *list, struct AudioListItem *item) {
// add 'item' to the front of the list given by 'list', if it's not in any list // add 'item' to the front of the list given by 'list', if it's not in any list
if (item->prev == NULL) { if (item->prev != NULL) {
eu_stubbed_printf_0("Error:Same List Add\n");
} else {
item->prev = list; item->prev = list;
item->next = list->next; item->next = list->next;
list->next->prev = item; list->next->prev = item;
@ -743,14 +772,16 @@ void audio_list_push_front(struct AudioListItem *list, struct AudioListItem *ite
void audio_list_remove(struct AudioListItem *item) { void audio_list_remove(struct AudioListItem *item) {
// remove 'item' from the list it's in, if any // remove 'item' from the list it's in, if any
if (item->prev != NULL) { if (item->prev == NULL) {
eu_stubbed_printf_0("Already Cut\n");
} else {
item->prev->next = item->next; item->prev->next = item->next;
item->next->prev = item->prev; item->next->prev = item->prev;
item->prev = NULL; item->prev = NULL;
} }
} }
struct Note *pop_node_with_value_less_equal(struct AudioListItem *list, s32 limit) { struct Note *pop_node_with_lower_prio(struct AudioListItem *list, s32 limit) {
struct AudioListItem *cur = list->next; struct AudioListItem *cur = list->next;
struct AudioListItem *best; struct AudioListItem *best;
@ -884,8 +915,10 @@ struct Note *alloc_note_from_decaying(struct NotePool *pool, struct SequenceChan
struct Note *alloc_note_from_active(struct NotePool *pool, struct SequenceChannelLayer *seqLayer) { struct Note *alloc_note_from_active(struct NotePool *pool, struct SequenceChannelLayer *seqLayer) {
struct Note *note = struct Note *note =
pop_node_with_value_less_equal(&pool->active, seqLayer->seqChannel->notePriority); pop_node_with_lower_prio(&pool->active, seqLayer->seqChannel->notePriority);
if (note != NULL) { if (note == NULL) {
eu_stubbed_printf_0("Audio: C-Alloc : lowerPrio is NULL\n");
} else {
func_80319728(note, seqLayer); func_80319728(note, seqLayer);
audio_list_push_back(&pool->releasing, &note->listItem); audio_list_push_back(&pool->releasing, &note->listItem);
} }
@ -918,6 +951,7 @@ struct Note *alloc_note(struct SequenceChannelLayer *seqLayer) {
if (!(ret = alloc_note_from_disabled(&seqLayer->seqChannel->notePool, seqLayer)) if (!(ret = alloc_note_from_disabled(&seqLayer->seqChannel->notePool, seqLayer))
&& !(ret = alloc_note_from_decaying(&seqLayer->seqChannel->notePool, seqLayer)) && !(ret = alloc_note_from_decaying(&seqLayer->seqChannel->notePool, seqLayer))
&& !(ret = alloc_note_from_active(&seqLayer->seqChannel->notePool, seqLayer))) { && !(ret = alloc_note_from_active(&seqLayer->seqChannel->notePool, seqLayer))) {
eu_stubbed_printf_0("Sub Limited Warning: Drop Voice");
seqLayer->status = SOUND_LOAD_STATUS_NOT_LOADED; seqLayer->status = SOUND_LOAD_STATUS_NOT_LOADED;
return NULL; return NULL;
} }
@ -931,6 +965,7 @@ struct Note *alloc_note(struct SequenceChannelLayer *seqLayer) {
&& !(ret = alloc_note_from_decaying(&seqLayer->seqChannel->seqPlayer->notePool, seqLayer)) && !(ret = alloc_note_from_decaying(&seqLayer->seqChannel->seqPlayer->notePool, seqLayer))
&& !(ret = alloc_note_from_active(&seqLayer->seqChannel->notePool, seqLayer)) && !(ret = alloc_note_from_active(&seqLayer->seqChannel->notePool, seqLayer))
&& !(ret = alloc_note_from_active(&seqLayer->seqChannel->seqPlayer->notePool, seqLayer))) { && !(ret = alloc_note_from_active(&seqLayer->seqChannel->seqPlayer->notePool, seqLayer))) {
eu_stubbed_printf_0("Warning: Drop Voice");
seqLayer->status = SOUND_LOAD_STATUS_NOT_LOADED; seqLayer->status = SOUND_LOAD_STATUS_NOT_LOADED;
return NULL; return NULL;
} }
@ -941,6 +976,7 @@ struct Note *alloc_note(struct SequenceChannelLayer *seqLayer) {
if (!(ret = alloc_note_from_disabled(&gNoteFreeLists, seqLayer)) if (!(ret = alloc_note_from_disabled(&gNoteFreeLists, seqLayer))
&& !(ret = alloc_note_from_decaying(&gNoteFreeLists, seqLayer)) && !(ret = alloc_note_from_decaying(&gNoteFreeLists, seqLayer))
&& !(ret = alloc_note_from_active(&gNoteFreeLists, seqLayer))) { && !(ret = alloc_note_from_active(&gNoteFreeLists, seqLayer))) {
eu_stubbed_printf_0("Warning: Drop Voice");
seqLayer->status = SOUND_LOAD_STATUS_NOT_LOADED; seqLayer->status = SOUND_LOAD_STATUS_NOT_LOADED;
return NULL; return NULL;
} }
@ -956,6 +992,7 @@ struct Note *alloc_note(struct SequenceChannelLayer *seqLayer) {
&& !(ret = alloc_note_from_active(&seqLayer->seqChannel->notePool, seqLayer)) && !(ret = alloc_note_from_active(&seqLayer->seqChannel->notePool, seqLayer))
&& !(ret = alloc_note_from_active(&seqLayer->seqChannel->seqPlayer->notePool, seqLayer)) && !(ret = alloc_note_from_active(&seqLayer->seqChannel->seqPlayer->notePool, seqLayer))
&& !(ret = alloc_note_from_active(&gNoteFreeLists, seqLayer))) { && !(ret = alloc_note_from_active(&gNoteFreeLists, seqLayer))) {
eu_stubbed_printf_0("Warning: Drop Voice");
seqLayer->status = SOUND_LOAD_STATUS_NOT_LOADED; seqLayer->status = SOUND_LOAD_STATUS_NOT_LOADED;
return NULL; return NULL;
} }
@ -1001,7 +1038,6 @@ void reclaim_notes(void) {
} }
#endif #endif
void note_init_all(void) { void note_init_all(void) {
struct Note *note; struct Note *note;
s32 i; s32 i;

View file

@ -69,7 +69,6 @@ void eu_process_audio_cmd(struct EuAudioCmd *cmd) {
case 0x82: case 0x82:
case 0x88: case 0x88:
// load_sequence(arg1, arg2, 0);
load_sequence(cmd->u.s.arg1, cmd->u.s.arg2, cmd->u.s.arg3); load_sequence(cmd->u.s.arg1, cmd->u.s.arg2, cmd->u.s.arg3);
func_8031D690(cmd->u.s.arg1, cmd->u2.as_s32); func_8031D690(cmd->u.s.arg1, cmd->u2.as_s32);
break; break;

View file

@ -203,6 +203,7 @@ void sequence_player_init_channels(struct SequencePlayer *seqPlayer, u16 channel
} }
seqChannel = allocate_sequence_channel(); seqChannel = allocate_sequence_channel();
if (IS_SEQUENCE_CHANNEL_VALID(seqChannel) == FALSE) { if (IS_SEQUENCE_CHANNEL_VALID(seqChannel) == FALSE) {
eu_stubbed_printf_0("Audio:Track:Warning: No Free Notetrack\n");
gAudioErrorFlags = i + 0x10000; gAudioErrorFlags = i + 0x10000;
seqPlayer->channels[i] = seqChannel; seqPlayer->channels[i] = seqChannel;
} else { } else {
@ -226,6 +227,7 @@ void sequence_player_disable_channels(struct SequencePlayer *seqPlayer, u16 chan
struct SequenceChannel *seqChannel; struct SequenceChannel *seqChannel;
s32 i; s32 i;
eu_stubbed_printf_0("SUBTRACK DIM\n");
for (i = 0; i < CHANNELS_MAX; i++) { for (i = 0; i < CHANNELS_MAX; i++) {
if (channelBits & 1) { if (channelBits & 1) {
seqChannel = seqPlayer->channels[i]; seqChannel = seqPlayer->channels[i];
@ -235,7 +237,9 @@ void sequence_player_disable_channels(struct SequencePlayer *seqPlayer, u16 chan
seqChannel->seqPlayer = NULL; seqChannel->seqPlayer = NULL;
} }
#ifdef VERSION_EU #ifdef VERSION_EU
if (0) {} else {
stubbed_printf("Audio:Track: Warning SUBTRACK PARENT CHANGED\n");
}
#endif #endif
seqPlayer->channels[i] = &gSequenceChannelNone; seqPlayer->channels[i] = &gSequenceChannelNone;
} }
@ -321,27 +325,30 @@ void sequence_player_disable_channels_extended(struct SequencePlayer* seqPlayer,
} }
} }
void sequence_channel_enable(struct SequencePlayer *seqPlayer, u8 channelIndex, void *arg2) { void sequence_channel_enable(struct SequencePlayer *seqPlayer, u8 channelIndex, void *script) {
struct SequenceChannel *seqChannel = seqPlayer->channels[channelIndex]; struct SequenceChannel *seqChannel = seqPlayer->channels[channelIndex];
s32 i; s32 i;
#ifdef VERSION_EU
if (IS_SEQUENCE_CHANNEL_VALID(seqChannel) == FALSE) { if (IS_SEQUENCE_CHANNEL_VALID(seqChannel) == FALSE) {
#ifdef VERSION_EU
struct SequencePlayer *bgMusic = &gSequencePlayers[0]; struct SequencePlayer *bgMusic = &gSequencePlayers[0];
struct SequencePlayer *miscMusic = &gSequencePlayers[1]; struct SequencePlayer *miscMusic = &gSequencePlayers[1];
if (seqPlayer == bgMusic) { if (seqPlayer == bgMusic) {
stubbed_printf("GROUP 0:");
} else if (seqPlayer == miscMusic) { } else if (seqPlayer == miscMusic) {
stubbed_printf("GROUP 1:");
} else { } else {
stubbed_printf("SEQID %d,BANKID %d\n",
seqPlayer->seqId, seqPlayer->defaultBank[0]);
} }
} else { stubbed_printf("ERR:SUBTRACK %d NOT ALLOCATED\n", channelIndex);
#else
if (IS_SEQUENCE_CHANNEL_VALID(seqChannel) != FALSE) {
#endif #endif
} else {
seqChannel->enabled = TRUE; seqChannel->enabled = TRUE;
seqChannel->finished = FALSE; seqChannel->finished = FALSE;
seqChannel->scriptState.depth = 0; seqChannel->scriptState.depth = 0;
seqChannel->scriptState.pc = arg2; seqChannel->scriptState.pc = script;
seqChannel->delay = 0; seqChannel->delay = 0;
for (i = 0; i < LAYERS_MAX; i++) { for (i = 0; i < LAYERS_MAX; i++) {
if (seqChannel->layers[i] != NULL) { if (seqChannel->layers[i] != NULL) {
@ -387,7 +394,9 @@ void sequence_player_disable(struct SequencePlayer *seqPlayer) {
* Add an item to the end of a list, if it's not already in any list. * Add an item to the end of a list, if it's not already in any list.
*/ */
void audio_list_push_back(struct AudioListItem *list, struct AudioListItem *item) { void audio_list_push_back(struct AudioListItem *list, struct AudioListItem *item) {
if (item->prev == NULL) { if (item->prev != NULL) {
eu_stubbed_printf_0("Error:Same List Add\n");
} else {
list->prev->next = item; list->prev->next = item;
item->prev = list->prev; item->prev = list->prev;
item->next = list; item->next = list;
@ -577,12 +586,18 @@ void seq_channel_layer_process_script(struct SequenceChannelLayer *layer) {
break; break;
case 0xfc: // layer_call case 0xfc: // layer_call
if (0 && state->depth >= 4) {
eu_stubbed_printf_0("Macro Level Over Error!\n");
}
sp3A = m64_read_s16(state); sp3A = m64_read_s16(state);
state->stack[state->depth++] = state->pc; state->stack[state->depth++] = state->pc;
state->pc = seqPlayer->seqData + sp3A; state->pc = seqPlayer->seqData + sp3A;
break; break;
case 0xf8: // layer_loop; loop start, N iterations (or 256 if N = 0) case 0xf8: // layer_loop; loop start, N iterations (or 256 if N = 0)
if (0 && state->depth >= 4) {
eu_stubbed_printf_0("Macro Level Over Error!\n");
}
state->remLoopIters[state->depth] = m64_read_u8(state); state->remLoopIters[state->depth] = m64_read_u8(state);
state->stack[state->depth++] = state->pc; state->stack[state->depth++] = state->pc;
break; break;
@ -669,9 +684,8 @@ void seq_channel_layer_process_script(struct SequenceChannelLayer *layer) {
break; break;
} }
cmd = get_instrument(seqChannel, cmd, &layer->instrument, &layer->adsr); if ((layer->instOrWave = get_instrument(seqChannel, cmd, &layer->instrument, &layer->adsr)) == 0) {
layer->instOrWave = cmd; eu_stubbed_printf_1("WARNING: NPRG: cannot change %d\n", cmd);
if (cmd == 0) {
layer->instOrWave = 0xff; layer->instOrWave = 0xff;
} }
#endif #endif
@ -725,6 +739,9 @@ void seq_channel_layer_process_script(struct SequenceChannelLayer *layer) {
case 0xe0: // layer_setshortnotedurationfromtable case 0xe0: // layer_setshortnotedurationfromtable
layer->noteDuration = seqPlayer->shortNoteDurationTable[cmd & 0xf]; layer->noteDuration = seqPlayer->shortNoteDurationTable[cmd & 0xf];
break; break;
default:
eu_stubbed_printf_1("Audio:Track:NOTE:UNDEFINED NOTE COM. %x\n", cmd);
break;
} }
} }
} }
@ -989,6 +1006,10 @@ void seq_channel_layer_process_script(struct SequenceChannelLayer *layer) {
} }
#endif #endif
} }
u8 audioString106[] = "Audio: Note:Velocity Error %d\n";
u8 audioString107[] = "Error: Your assignchannel is stolen.\n";
#elif defined(NON_MATCHING) #elif defined(NON_MATCHING)
// US/JP version with macros to simulate inlining by copt. Edit if you dare. // US/JP version with macros to simulate inlining by copt. Edit if you dare.
#include "seq_channel_layer_process_script.h" #include "seq_channel_layer_process_script.h"
@ -1084,7 +1105,6 @@ void sequence_channel_set_volume(struct SequenceChannel *seqChannel, u8 volume)
} }
#ifdef NON_MATCHING #ifdef NON_MATCHING
//rodata: 0xf3e30
void sequence_channel_process_script(struct SequenceChannel *seqChannel) { void sequence_channel_process_script(struct SequenceChannel *seqChannel) {
struct M64ScriptState *state; struct M64ScriptState *state;
struct SequencePlayer *seqPlayer; struct SequencePlayer *seqPlayer;
@ -1184,6 +1204,9 @@ void sequence_channel_process_script(struct SequenceChannel *seqChannel) {
goto out; goto out;
#endif #endif
case 0xfc: // chan_call case 0xfc: // chan_call
if (0 && state->depth >= 4) {
eu_stubbed_printf_0("Audio:Track :Call Macro Level Over Error!\n");
}
sp5A = m64_read_s16(state); sp5A = m64_read_s16(state);
#ifdef VERSION_EU #ifdef VERSION_EU
state->stack[state->depth++] = state->pc; state->stack[state->depth++] = state->pc;
@ -1194,6 +1217,9 @@ void sequence_channel_process_script(struct SequenceChannel *seqChannel) {
break; break;
case 0xf8: // chan_loop; loop start, N iterations (or 256 if N = 0) case 0xf8: // chan_loop; loop start, N iterations (or 256 if N = 0)
if (0 && state->depth >= 4) {
eu_stubbed_printf_0("Audio:Track :Loops Macro Level Over Error!\n");
}
state->remLoopIters[state->depth] = m64_read_u8(state); state->remLoopIters[state->depth] = m64_read_u8(state);
#ifdef VERSION_EU #ifdef VERSION_EU
state->stack[state->depth++] = state->pc; state->stack[state->depth++] = state->pc;
@ -1230,9 +1256,9 @@ void sequence_channel_process_script(struct SequenceChannel *seqChannel) {
break; break;
#ifdef VERSION_EU #ifdef VERSION_EU
case 0xf4: case 0xf4: // chan_jump_rel
case 0xf3: case 0xf3: // chan_beqz_rel
case 0xf2: case 0xf2: // chan_bltz_rel
tempSigned = m64_read_u8(state); tempSigned = m64_read_u8(state);
if (cmd == 0xf3 && value != 0) if (cmd == 0xf3 && value != 0)
break; break;
@ -1275,7 +1301,7 @@ void sequence_channel_process_script(struct SequenceChannel *seqChannel) {
break; break;
#ifdef VERSION_EU #ifdef VERSION_EU
case 0xeb: case 0xeb: // chan_setbankandinstr
temp = m64_read_u8(state); temp = m64_read_u8(state);
// Switch to the temp's (0-indexed) bank in this sequence's // Switch to the temp's (0-indexed) bank in this sequence's
// bank set. Note that in the binary format (not in the JSON!) // bank set. Note that in the binary format (not in the JSON!)
@ -1286,6 +1312,8 @@ void sequence_channel_process_script(struct SequenceChannel *seqChannel) {
// temp should be in a saved register across this call // temp should be in a saved register across this call
if (get_bank_or_seq(&gBankLoadedPool, 2, temp) != NULL) { if (get_bank_or_seq(&gBankLoadedPool, 2, temp) != NULL) {
seqChannel->bankId = temp; seqChannel->bankId = temp;
} else {
eu_stubbed_printf_1("SUB:ERR:BANK %d NOT CACHED.\n", temp);
} }
// fallthrough // fallthrough
#endif #endif
@ -1420,6 +1448,8 @@ void sequence_channel_process_script(struct SequenceChannel *seqChannel) {
// temp should be in a saved register across this call // temp should be in a saved register across this call
if (get_bank_or_seq(&gBankLoadedPool, 2, temp) != NULL) { if (get_bank_or_seq(&gBankLoadedPool, 2, temp) != NULL) {
seqChannel->bankId = temp; seqChannel->bankId = temp;
} else {
eu_stubbed_printf_1("SUB:ERR:BANK %d NOT CACHED.\n", temp);
} }
} }
break; break;
@ -1479,6 +1509,9 @@ void sequence_channel_process_script(struct SequenceChannel *seqChannel) {
#endif #endif
case 0xe4: // chan_dyncall case 0xe4: // chan_dyncall
if (value != -1) { if (value != -1) {
if (0 && state->depth >= 4) {
eu_stubbed_printf_0("Audio:Track: CTBLCALL Macro Level Over Error!\n");
}
u8(*thingy)[2] = *seqChannel->dynTable; u8(*thingy)[2] = *seqChannel->dynTable;
#ifdef VERSION_EU #ifdef VERSION_EU
state->stack[state->depth++] = state->pc; state->stack[state->depth++] = state->pc;
@ -1487,6 +1520,9 @@ void sequence_channel_process_script(struct SequenceChannel *seqChannel) {
#endif #endif
sp5A = thingy[value][1] + (thingy[value][0] << 8); sp5A = thingy[value][1] + (thingy[value][0] << 8);
state->pc = seqPlayer->seqData + sp5A; state->pc = seqPlayer->seqData + sp5A;
if (0 && sp5A >= gSeqFileHeader->seqArray[seqPlayer->seqId].len) {
eu_stubbed_printf_3("Err :Sub %x ,address %x:Undefined SubTrack Function %x", seqChannel, state->pc, sp5A);
}
} }
break; break;
@ -1531,7 +1567,7 @@ void sequence_channel_process_script(struct SequenceChannel *seqChannel) {
seqChannel->freqScale = 1.0f; seqChannel->freqScale = 1.0f;
break; break;
case 0xe9: case 0xe9: // chan_setnotepriority
seqChannel->notePriority = m64_read_u8(state); seqChannel->notePriority = m64_read_u8(state);
break; break;
#endif #endif
@ -1568,7 +1604,7 @@ void sequence_channel_process_script(struct SequenceChannel *seqChannel) {
break; break;
#ifdef VERSION_EU #ifdef VERSION_EU
case 0x60: case 0x60: // chan_delayshort
seqChannel->delay = loBits; seqChannel->delay = loBits;
goto out; goto out;
#endif #endif
@ -1720,6 +1756,7 @@ void sequence_player_process_sequence(struct SequencePlayer *seqPlayer) {
// If discarded, bail out. // If discarded, bail out.
if (IS_SEQ_LOAD_COMPLETE(seqPlayer->seqId) == FALSE if (IS_SEQ_LOAD_COMPLETE(seqPlayer->seqId) == FALSE
|| IS_BANK_LOAD_COMPLETE(seqPlayer->defaultBank[0]) == FALSE) { || IS_BANK_LOAD_COMPLETE(seqPlayer->defaultBank[0]) == FALSE) {
eu_stubbed_printf_1("Disappear Sequence or Bank %d\n", seqPlayer->seqId);
sequence_player_disable(seqPlayer); sequence_player_disable(seqPlayer);
return; return;
} }
@ -1784,6 +1821,9 @@ void sequence_player_process_sequence(struct SequencePlayer *seqPlayer) {
case 0xfc: // seq_call case 0xfc: // seq_call
u16v = m64_read_s16(state); u16v = m64_read_s16(state);
if (0 && state->depth >= 4) {
eu_stubbed_printf_0("Macro Level Over Error!\n");
}
#ifdef VERSION_EU #ifdef VERSION_EU
state->stack[state->depth++] = state->pc; state->stack[state->depth++] = state->pc;
#else #else
@ -1793,6 +1833,9 @@ void sequence_player_process_sequence(struct SequencePlayer *seqPlayer) {
break; break;
case 0xf8: // seq_loop; loop start, N iterations (or 256 if N = 0) case 0xf8: // seq_loop; loop start, N iterations (or 256 if N = 0)
if (0 && state->depth >= 4) {
eu_stubbed_printf_0("Macro Level Over Error!\n");
}
state->remLoopIters[state->depth] = m64_read_u8(state); state->remLoopIters[state->depth] = m64_read_u8(state);
#ifdef VERSION_EU #ifdef VERSION_EU
state->stack[state->depth++] = state->pc; state->stack[state->depth++] = state->pc;
@ -2022,6 +2065,10 @@ void sequence_player_process_sequence(struct SequencePlayer *seqPlayer) {
case 0xc8: // seq_subtract case 0xc8: // seq_subtract
value = value - m64_read_u8(state); value = value - m64_read_u8(state);
break; break;
default:
eu_stubbed_printf_1("Group:Undefine upper C0h command (%x)\n", cmd);
break;
} }
} else { } else {
loBits = cmd & 0xf; loBits = cmd & 0xf;
@ -2076,6 +2123,10 @@ void sequence_player_process_sequence(struct SequencePlayer *seqPlayer) {
case 0xd9: case 0xd9:
break; break;
#endif #endif
default:
eu_stubbed_printf_0("Group:Undefined Command\n");
break;
} }
} }
} }

View file

@ -72,11 +72,12 @@ f32 gLeftVolRampings[3][1024];
f32 gRightVolRampings[3][1024]; f32 gRightVolRampings[3][1024];
f32 *gCurrentLeftVolRamping; // Points to any of the three left buffers above f32 *gCurrentLeftVolRamping; // Points to any of the three left buffers above
f32 *gCurrentRightVolRamping; // Points to any of the three right buffers above f32 *gCurrentRightVolRamping; // Points to any of the three right buffers above
u8 audioString1[] = "pitch %x: delaybytes %d : olddelay %d\n";
u8 audioString2[] = "cont %x: delaybytes %d : olddelay %d\n";
#else #else
struct SynthesisReverb gSynthesisReverb; struct SynthesisReverb gSynthesisReverb;
#endif
#ifndef VERSION_EU
u8 sAudioSynthesisPad[0x20]; u8 sAudioSynthesisPad[0x20];
#endif #endif
@ -615,8 +616,6 @@ u64 *synthesis_process_notes(s16 *aiBuf, s32 bufLen, u64 *cmd) {
u8 *sampleAddr; // sp120, spF4 u8 *sampleAddr; // sp120, spF4
#endif #endif
// sp6c is a temporary!
#ifdef VERSION_EU #ifdef VERSION_EU
s32 samplesLenAdjusted; // 108, spEC s32 samplesLenAdjusted; // 108, spEC
// Might have been used to store (samplesLenFixedPoint >> 0x10), but doing so causes strange // Might have been used to store (samplesLenFixedPoint >> 0x10), but doing so causes strange

View file

@ -314,12 +314,12 @@ struct GraphNodeObject *init_graph_node_object(struct AllocOnlyPool *pool,
vec3s_copy(graphNode->angle, angle); vec3s_copy(graphNode->angle, angle);
graphNode->sharedChild = sharedChild; graphNode->sharedChild = sharedChild;
graphNode->throwMatrix = NULL; graphNode->throwMatrix = NULL;
graphNode->unk38.animID = 0; graphNode->animInfo.animID = 0;
graphNode->unk38.curAnim = NULL; graphNode->animInfo.curAnim = NULL;
graphNode->unk38.animFrame = 0; graphNode->animInfo.animFrame = 0;
graphNode->unk38.animFrameAccelAssist = 0; graphNode->animInfo.animFrameAccelAssist = 0;
graphNode->unk38.animAccel = 0x10000; graphNode->animInfo.animAccel = 0x10000;
graphNode->unk38.animTimer = 0; graphNode->animInfo.animTimer = 0;
graphNode->node.flags |= GRAPH_RENDER_HAS_ANIMATION; graphNode->node.flags |= GRAPH_RENDER_HAS_ANIMATION;
} }
@ -720,7 +720,7 @@ void geo_obj_init(struct GraphNodeObject *graphNode, void *sharedChild, Vec3f po
graphNode->sharedChild = sharedChild; graphNode->sharedChild = sharedChild;
graphNode->unk4C = 0; graphNode->unk4C = 0;
graphNode->throwMatrix = NULL; graphNode->throwMatrix = NULL;
graphNode->unk38.curAnim = NULL; graphNode->animInfo.curAnim = NULL;
graphNode->node.flags |= GRAPH_RENDER_ACTIVE; graphNode->node.flags |= GRAPH_RENDER_ACTIVE;
graphNode->node.flags &= ~GRAPH_RENDER_INVISIBLE; graphNode->node.flags &= ~GRAPH_RENDER_INVISIBLE;
@ -739,12 +739,12 @@ void geo_obj_init_spawninfo(struct GraphNodeObject *graphNode, struct SpawnInfo
graphNode->pos[1] = (f32) spawn->startPos[1]; graphNode->pos[1] = (f32) spawn->startPos[1];
graphNode->pos[2] = (f32) spawn->startPos[2]; graphNode->pos[2] = (f32) spawn->startPos[2];
graphNode->unk18 = spawn->areaIndex; graphNode->areaIndex = spawn->areaIndex;
graphNode->unk19 = spawn->activeAreaIndex; graphNode->activeAreaIndex = spawn->activeAreaIndex;
graphNode->sharedChild = spawn->unk18; graphNode->sharedChild = spawn->unk18;
graphNode->unk4C = spawn; graphNode->unk4C = spawn;
graphNode->throwMatrix = NULL; graphNode->throwMatrix = NULL;
graphNode->unk38.curAnim = 0; graphNode->animInfo.curAnim = 0;
graphNode->node.flags |= GRAPH_RENDER_ACTIVE; graphNode->node.flags |= GRAPH_RENDER_ACTIVE;
graphNode->node.flags &= ~GRAPH_RENDER_INVISIBLE; graphNode->node.flags &= ~GRAPH_RENDER_INVISIBLE;
@ -763,11 +763,11 @@ void geo_obj_init_animation(struct GraphNodeObject *graphNode, struct Animation
struct Animation **animSegmented = segmented_to_virtual(animPtrAddr); struct Animation **animSegmented = segmented_to_virtual(animPtrAddr);
struct Animation *anim = segmented_to_virtual(*animSegmented); struct Animation *anim = segmented_to_virtual(*animSegmented);
if (graphNode->unk38.curAnim != anim) { if (graphNode->animInfo.curAnim != anim) {
graphNode->unk38.curAnim = anim; graphNode->animInfo.curAnim = anim;
graphNode->unk38.animFrame = anim->unk04 + ((anim->flags & ANIM_FLAG_FORWARD) ? 1 : -1); graphNode->animInfo.animFrame = anim->startFrame + ((anim->flags & ANIM_FLAG_FORWARD) ? 1 : -1);
graphNode->unk38.animAccel = 0; graphNode->animInfo.animAccel = 0;
graphNode->unk38.animYTrans = 0; graphNode->animInfo.animYTrans = 0;
} }
} }
@ -782,15 +782,15 @@ void geo_obj_init_animation_accel(struct GraphNodeObject *graphNode, struct Anim
struct Animation **animSegmented = segmented_to_virtual(animPtrAddr); struct Animation **animSegmented = segmented_to_virtual(animPtrAddr);
struct Animation *anim = segmented_to_virtual(*animSegmented); struct Animation *anim = segmented_to_virtual(*animSegmented);
if (graphNode->unk38.curAnim != anim) { if (graphNode->animInfo.curAnim != anim) {
graphNode->unk38.curAnim = anim; graphNode->animInfo.curAnim = anim;
graphNode->unk38.animYTrans = 0; graphNode->animInfo.animYTrans = 0;
graphNode->unk38.animFrameAccelAssist = graphNode->animInfo.animFrameAccelAssist =
(anim->unk04 << 16) + ((anim->flags & ANIM_FLAG_FORWARD) ? animAccel : -animAccel); (anim->startFrame << 16) + ((anim->flags & ANIM_FLAG_FORWARD) ? animAccel : -animAccel);
graphNode->unk38.animFrame = graphNode->unk38.animFrameAccelAssist >> 16; graphNode->animInfo.animFrame = graphNode->animInfo.animFrameAccelAssist >> 16;
} }
graphNode->unk38.animAccel = animAccel; graphNode->animInfo.animAccel = animAccel;
} }
/** /**
@ -819,7 +819,7 @@ s32 retrieve_animation_index(s32 frame, u16 **attributes) {
* whether it plays forwards or backwards, and whether it stops or loops at * whether it plays forwards or backwards, and whether it stops or loops at
* the end etc. * the end etc.
*/ */
s16 geo_update_animation_frame(struct GraphNodeObject_sub *obj, s32 *accelAssist) { s16 geo_update_animation_frame(struct AnimInfo *obj, s32 *accelAssist) {
s32 result; s32 result;
struct Animation *anim; struct Animation *anim;
@ -841,11 +841,11 @@ s16 geo_update_animation_frame(struct GraphNodeObject_sub *obj, s32 *accelAssist
result = (obj->animFrame - 1) << 16; result = (obj->animFrame - 1) << 16;
} }
if (GET_HIGH_S16_OF_32(result) < anim->unk06) { if (GET_HIGH_S16_OF_32(result) < anim->loopStart) {
if (anim->flags & ANIM_FLAG_NOLOOP) { if (anim->flags & ANIM_FLAG_NOLOOP) {
SET_HIGH_S16_OF_32(result, anim->unk06); SET_HIGH_S16_OF_32(result, anim->loopStart);
} else { } else {
SET_HIGH_S16_OF_32(result, anim->unk08 - 1); SET_HIGH_S16_OF_32(result, anim->loopEnd - 1);
} }
} }
} else { } else {
@ -855,11 +855,11 @@ s16 geo_update_animation_frame(struct GraphNodeObject_sub *obj, s32 *accelAssist
result = (obj->animFrame + 1) << 16; result = (obj->animFrame + 1) << 16;
} }
if (GET_HIGH_S16_OF_32(result) >= anim->unk08) { if (GET_HIGH_S16_OF_32(result) >= anim->loopEnd) {
if (anim->flags & ANIM_FLAG_NOLOOP) { if (anim->flags & ANIM_FLAG_NOLOOP) {
SET_HIGH_S16_OF_32(result, anim->unk08 - 1); SET_HIGH_S16_OF_32(result, anim->loopEnd - 1);
} else { } else {
SET_HIGH_S16_OF_32(result, anim->unk06); SET_HIGH_S16_OF_32(result, anim->loopStart);
} }
} }
} }
@ -880,7 +880,7 @@ s16 geo_update_animation_frame(struct GraphNodeObject_sub *obj, s32 *accelAssist
* animations without lateral translation. * animations without lateral translation.
*/ */
void geo_retreive_animation_translation(struct GraphNodeObject *obj, Vec3f position) { void geo_retreive_animation_translation(struct GraphNodeObject *obj, Vec3f position) {
struct Animation *animation = obj->unk38.curAnim; struct Animation *animation = obj->animInfo.curAnim;
u16 *attribute; u16 *attribute;
s16 *values; s16 *values;
s16 frame; s16 frame;
@ -889,7 +889,7 @@ void geo_retreive_animation_translation(struct GraphNodeObject *obj, Vec3f posit
attribute = segmented_to_virtual((void *) animation->index); attribute = segmented_to_virtual((void *) animation->index);
values = segmented_to_virtual((void *) animation->values); values = segmented_to_virtual((void *) animation->values);
frame = obj->unk38.animFrame; frame = obj->animInfo.animFrame;
if (frame < 0) { if (frame < 0) {
frame = 0; frame = 0;

View file

@ -437,7 +437,7 @@ void geo_obj_init_animation_accel(struct GraphNodeObject *graphNode, struct Anim
s32 retrieve_animation_index(s32 frame, u16 **attributes); s32 retrieve_animation_index(s32 frame, u16 **attributes);
s16 geo_update_animation_frame(struct GraphNodeObject_sub *obj, s32 *accelAssist); s16 geo_update_animation_frame(struct AnimInfo *obj, s32 *accelAssist);
void geo_retreive_animation_translation(struct GraphNodeObject *obj, Vec3f position); void geo_retreive_animation_translation(struct GraphNodeObject *obj, Vec3f position);
struct GraphNodeRoot *geo_find_root(struct GraphNode *graphNode); struct GraphNodeRoot *geo_find_root(struct GraphNode *graphNode);

View file

@ -175,7 +175,8 @@ void mtxf_copy(Mat4 dest, Mat4 src) {
void mtxf_identity(Mat4 mtx) { void mtxf_identity(Mat4 mtx) {
register s32 i; register s32 i;
register f32 *dest; register f32 *dest;
// Note: These loops need to be on one line to match on PAL // These loops must be one line to match on -O2
// initialize everything except the first and last cells to 0 // initialize everything except the first and last cells to 0
for (dest = (f32 *) mtx + 1, i = 0; i < 14; dest++, i++) *dest = 0; for (dest = (f32 *) mtx + 1, i = 0; i < 14; dest++, i++) *dest = 0;

View file

@ -206,8 +206,8 @@ s32 find_wall_collisions(struct WallCollisionData *colData) {
// World (level) consists of a 16x16 grid. Find where the collision is on // World (level) consists of a 16x16 grid. Find where the collision is on
// the grid (round toward -inf) // the grid (round toward -inf)
cellX = ((x + LEVEL_BOUNDARY_MAX) / CELL_SIZE) & 0x0F; cellX = ((x + LEVEL_BOUNDARY_MAX) / CELL_SIZE) & (NUM_CELLS - 1);
cellZ = ((z + LEVEL_BOUNDARY_MAX) / CELL_SIZE) & 0x0F; cellZ = ((z + LEVEL_BOUNDARY_MAX) / CELL_SIZE) & (NUM_CELLS - 1);
// Check for surfaces belonging to objects. // Check for surfaces belonging to objects.
node = gDynamicSurfacePartition[cellZ][cellX][SPATIAL_PARTITION_WALLS].next; node = gDynamicSurfacePartition[cellZ][cellX][SPATIAL_PARTITION_WALLS].next;
@ -314,8 +314,8 @@ f32 find_ceil(f32 posX, f32 posY, f32 posZ, struct Surface **pceil) {
s16 cellZ, cellX; s16 cellZ, cellX;
struct Surface *ceil, *dynamicCeil; struct Surface *ceil, *dynamicCeil;
struct SurfaceNode *surfaceList; struct SurfaceNode *surfaceList;
f32 height = 20000.0f; f32 height = CELL_HEIGHT_LIMIT;
f32 dynamicHeight = 20000.0f; f32 dynamicHeight = CELL_HEIGHT_LIMIT;
s16 x, y, z; s16 x, y, z;
//! (Parallel Universes) Because position is casted to an s16, reaching higher //! (Parallel Universes) Because position is casted to an s16, reaching higher
@ -334,8 +334,8 @@ f32 find_ceil(f32 posX, f32 posY, f32 posZ, struct Surface **pceil) {
} }
// Each level is split into cells to limit load, find the appropriate cell. // Each level is split into cells to limit load, find the appropriate cell.
cellX = ((x + LEVEL_BOUNDARY_MAX) / CELL_SIZE) & 0xF; cellX = ((x + LEVEL_BOUNDARY_MAX) / CELL_SIZE) & (NUM_CELLS - 1);
cellZ = ((z + LEVEL_BOUNDARY_MAX) / CELL_SIZE) & 0xF; cellZ = ((z + LEVEL_BOUNDARY_MAX) / CELL_SIZE) & (NUM_CELLS - 1);
// Check for surfaces belonging to objects. // Check for surfaces belonging to objects.
surfaceList = gDynamicSurfacePartition[cellZ][cellX][SPATIAL_PARTITION_CEILS].next; surfaceList = gDynamicSurfacePartition[cellZ][cellX][SPATIAL_PARTITION_CEILS].next;
@ -550,7 +550,7 @@ f32 find_floor_height(f32 x, f32 y, f32 z) {
f32 unused_find_dynamic_floor(f32 xPos, f32 yPos, f32 zPos, struct Surface **pfloor) { f32 unused_find_dynamic_floor(f32 xPos, f32 yPos, f32 zPos, struct Surface **pfloor) {
struct SurfaceNode *surfaceList; struct SurfaceNode *surfaceList;
struct Surface *floor; struct Surface *floor;
f32 floorHeight = -11000.0f; f32 floorHeight = FLOOR_LOWER_LIMIT;
// Would normally cause PUs, but dynamic floors unload at that range. // Would normally cause PUs, but dynamic floors unload at that range.
s16 x = (s16) xPos; s16 x = (s16) xPos;
@ -558,8 +558,8 @@ f32 unused_find_dynamic_floor(f32 xPos, f32 yPos, f32 zPos, struct Surface **pfl
s16 z = (s16) zPos; s16 z = (s16) zPos;
// Each level is split into cells to limit load, find the appropriate cell. // Each level is split into cells to limit load, find the appropriate cell.
s16 cellX = ((x + LEVEL_BOUNDARY_MAX) / CELL_SIZE) & 0x0F; s16 cellX = ((x + LEVEL_BOUNDARY_MAX) / CELL_SIZE) & (NUM_CELLS - 1);
s16 cellZ = ((z + LEVEL_BOUNDARY_MAX) / CELL_SIZE) & 0x0F; s16 cellZ = ((z + LEVEL_BOUNDARY_MAX) / CELL_SIZE) & (NUM_CELLS - 1);
surfaceList = gDynamicSurfacePartition[cellZ][cellX][SPATIAL_PARTITION_FLOORS].next; surfaceList = gDynamicSurfacePartition[cellZ][cellX][SPATIAL_PARTITION_FLOORS].next;
floor = find_floor_from_list(surfaceList, x, y, z, &floorHeight); floor = find_floor_from_list(surfaceList, x, y, z, &floorHeight);
@ -578,8 +578,8 @@ f32 find_floor(f32 xPos, f32 yPos, f32 zPos, struct Surface **pfloor) {
struct Surface *floor, *dynamicFloor; struct Surface *floor, *dynamicFloor;
struct SurfaceNode *surfaceList; struct SurfaceNode *surfaceList;
f32 height = -11000.0f; f32 height = FLOOR_LOWER_LIMIT;
f32 dynamicHeight = -11000.0f; f32 dynamicHeight = FLOOR_LOWER_LIMIT;
//! (Parallel Universes) Because position is casted to an s16, reaching higher //! (Parallel Universes) Because position is casted to an s16, reaching higher
// float locations can return floors despite them not existing there. // float locations can return floors despite them not existing there.
@ -598,8 +598,8 @@ f32 find_floor(f32 xPos, f32 yPos, f32 zPos, struct Surface **pfloor) {
} }
// Each level is split into cells to limit load, find the appropriate cell. // Each level is split into cells to limit load, find the appropriate cell.
cellX = ((x + LEVEL_BOUNDARY_MAX) / CELL_SIZE) & 0xF; cellX = ((x + LEVEL_BOUNDARY_MAX) / CELL_SIZE) & (NUM_CELLS - 1);
cellZ = ((z + LEVEL_BOUNDARY_MAX) / CELL_SIZE) & 0xF; cellZ = ((z + LEVEL_BOUNDARY_MAX) / CELL_SIZE) & (NUM_CELLS - 1);
// Check for surfaces belonging to objects. // Check for surfaces belonging to objects.
surfaceList = gDynamicSurfacePartition[cellZ][cellX][SPATIAL_PARTITION_FLOORS].next; surfaceList = gDynamicSurfacePartition[cellZ][cellX][SPATIAL_PARTITION_FLOORS].next;
@ -655,7 +655,7 @@ f32 find_water_level(f32 x, f32 z) {
s32 numRegions; s32 numRegions;
s16 val; s16 val;
f32 loX, hiX, loZ, hiZ; f32 loX, hiX, loZ, hiZ;
f32 waterLevel = -11000.0f; f32 waterLevel = FLOOR_LOWER_LIMIT;
s16 *p = gEnvironmentRegions; s16 *p = gEnvironmentRegions;
if (p != NULL) { if (p != NULL) {
@ -691,7 +691,7 @@ f32 find_poison_gas_level(f32 x, f32 z) {
UNUSED s32 unused; UNUSED s32 unused;
s16 val; s16 val;
f32 loX, hiX, loZ, hiZ; f32 loX, hiX, loZ, hiZ;
f32 gasLevel = -11000.0f; f32 gasLevel = FLOOR_LOWER_LIMIT;
s16 *p = gEnvironmentRegions; s16 *p = gEnvironmentRegions;
if (p != NULL) { if (p != NULL) {
@ -753,25 +753,25 @@ void debug_surface_list_info(f32 xPos, f32 zPos) {
s32 cellX = (xPos + LEVEL_BOUNDARY_MAX) / CELL_SIZE; s32 cellX = (xPos + LEVEL_BOUNDARY_MAX) / CELL_SIZE;
s32 cellZ = (zPos + LEVEL_BOUNDARY_MAX) / CELL_SIZE; s32 cellZ = (zPos + LEVEL_BOUNDARY_MAX) / CELL_SIZE;
list = gStaticSurfacePartition[cellZ & 0x0F][cellX & 0x0F][SPATIAL_PARTITION_FLOORS].next; list = gStaticSurfacePartition[cellZ & (NUM_CELLS - 1)][cellX & (NUM_CELLS - 1)][SPATIAL_PARTITION_FLOORS].next;
numFloors += surface_list_length(list); numFloors += surface_list_length(list);
list = gDynamicSurfacePartition[cellZ & 0x0F][cellX & 0x0F][SPATIAL_PARTITION_FLOORS].next; list = gDynamicSurfacePartition[cellZ & (NUM_CELLS - 1)][cellX & (NUM_CELLS - 1)][SPATIAL_PARTITION_FLOORS].next;
numFloors += surface_list_length(list); numFloors += surface_list_length(list);
list = gStaticSurfacePartition[cellZ & 0x0F][cellX & 0x0F][SPATIAL_PARTITION_WALLS].next; list = gStaticSurfacePartition[cellZ & (NUM_CELLS - 1)][cellX & (NUM_CELLS - 1)][SPATIAL_PARTITION_WALLS].next;
numWalls += surface_list_length(list); numWalls += surface_list_length(list);
list = gDynamicSurfacePartition[cellZ & 0x0F][cellX & 0x0F][SPATIAL_PARTITION_WALLS].next; list = gDynamicSurfacePartition[cellZ & (NUM_CELLS - 1)][cellX & (NUM_CELLS - 1)][SPATIAL_PARTITION_WALLS].next;
numWalls += surface_list_length(list); numWalls += surface_list_length(list);
list = gStaticSurfacePartition[cellZ & 0x0F][cellX & 0x0F][SPATIAL_PARTITION_CEILS].next; list = gStaticSurfacePartition[cellZ & (NUM_CELLS - 1)][cellX & (NUM_CELLS - 1)][SPATIAL_PARTITION_CEILS].next;
numCeils += surface_list_length(list); numCeils += surface_list_length(list);
list = gDynamicSurfacePartition[cellZ & 0x0F][cellX & 0x0F][SPATIAL_PARTITION_CEILS].next; list = gDynamicSurfacePartition[cellZ & (NUM_CELLS - 1)][cellX & (NUM_CELLS - 1)][SPATIAL_PARTITION_CEILS].next;
numCeils += surface_list_length(list); numCeils += surface_list_length(list);
print_debug_top_down_mapinfo("area %x", cellZ * 16 + cellX); print_debug_top_down_mapinfo("area %x", cellZ * NUM_CELLS + cellX);
// Names represent ground, walls, and roofs as found in SMS. // Names represent ground, walls, and roofs as found in SMS.
print_debug_top_down_mapinfo("dg %d", numFloors); print_debug_top_down_mapinfo("dg %d", numFloors);

View file

@ -5,8 +5,11 @@
#include "types.h" #include "types.h"
#define LEVEL_BOUNDARY_MAX 0x2000 #define LEVEL_BOUNDARY_MAX 0x2000
#define CELL_SIZE 0x400 #define CELL_SIZE 0x400
#define CELL_HEIGHT_LIMIT 20000.f
#define FLOOR_LOWER_LIMIT -11000.f
struct WallCollisionData struct WallCollisionData
{ {

View file

@ -24,8 +24,8 @@ s32 unused8038BE90;
* Partitions for course and object surfaces. The arrays represent * Partitions for course and object surfaces. The arrays represent
* the 16x16 cells that each level is split into. * the 16x16 cells that each level is split into.
*/ */
SpatialPartitionCell gStaticSurfacePartition[16][16]; SpatialPartitionCell gStaticSurfacePartition[NUM_CELLS][NUM_CELLS];
SpatialPartitionCell gDynamicSurfacePartition[16][16]; SpatialPartitionCell gDynamicSurfacePartition[NUM_CELLS][NUM_CELLS];
/** /**
* Pools of data to contain either surface nodes or surfaces. * Pools of data to contain either surface nodes or surfaces.
@ -86,7 +86,7 @@ static struct Surface *alloc_surface(void) {
* Iterates through the entire partition, clearing the surfaces. * Iterates through the entire partition, clearing the surfaces.
*/ */
static void clear_spatial_partition(SpatialPartitionCell *cells) { static void clear_spatial_partition(SpatialPartitionCell *cells) {
register s32 i = 16 * 16; register s32 i = NUM_CELLS * NUM_CELLS;
while (i--) { while (i--) {
(*cells)[SPATIAL_PARTITION_FLOORS].next = NULL; (*cells)[SPATIAL_PARTITION_FLOORS].next = NULL;
@ -204,18 +204,18 @@ static s16 lower_cell_index(s16 coord) {
s16 index; s16 index;
// Move from range [-0x2000, 0x2000) to [0, 0x4000) // Move from range [-0x2000, 0x2000) to [0, 0x4000)
coord += 0x2000; coord += LEVEL_BOUNDARY_MAX;
if (coord < 0) { if (coord < 0) {
coord = 0; coord = 0;
} }
// [0, 16) // [0, 16)
index = coord / 0x400; index = coord / CELL_SIZE;
// Include extra cell if close to boundary // Include extra cell if close to boundary
//! Some wall checks are larger than the buffer, meaning wall checks can //! Some wall checks are larger than the buffer, meaning wall checks can
// miss walls that are near a cell border. // miss walls that are near a cell border.
if (coord % 0x400 < 50) { if (coord % CELL_SIZE < 50) {
index -= 1; index -= 1;
} }
@ -236,23 +236,23 @@ static s16 upper_cell_index(s16 coord) {
s16 index; s16 index;
// Move from range [-0x2000, 0x2000) to [0, 0x4000) // Move from range [-0x2000, 0x2000) to [0, 0x4000)
coord += 0x2000; coord += LEVEL_BOUNDARY_MAX;
if (coord < 0) { if (coord < 0) {
coord = 0; coord = 0;
} }
// [0, 16) // [0, 16)
index = coord / 0x400; index = coord / CELL_SIZE;
// Include extra cell if close to boundary // Include extra cell if close to boundary
//! Some wall checks are larger than the buffer, meaning wall checks can //! Some wall checks are larger than the buffer, meaning wall checks can
// miss walls that are near a cell border. // miss walls that are near a cell border.
if (coord % 0x400 > 0x400 - 50) { if (coord % CELL_SIZE > CELL_SIZE - 50) {
index += 1; index += 1;
} }
if (index > 15) { if (index > (NUM_CELLS - 1)) {
index = 15; index = (NUM_CELLS - 1);
} }
// Potentially < 0, but since lower index is >= 0, not exploitable // Potentially < 0, but since lower index is >= 0, not exploitable

View file

@ -5,6 +5,10 @@
#include "types.h" #include "types.h"
// NUM_CELLS needs to be a power of 2 so that the bitwise
// in surface_collision.c functions can work properly
#define NUM_CELLS 16
struct SurfaceNode struct SurfaceNode
{ {
struct SurfaceNode *next; struct SurfaceNode *next;
@ -23,8 +27,8 @@ typedef struct SurfaceNode SpatialPartitionCell[3];
// Needed for bs bss reordering memes. // Needed for bs bss reordering memes.
extern s32 unused8038BE90; extern s32 unused8038BE90;
extern SpatialPartitionCell gStaticSurfacePartition[16][16]; extern SpatialPartitionCell gStaticSurfacePartition[NUM_CELLS][NUM_CELLS];
extern SpatialPartitionCell gDynamicSurfacePartition[16][16]; extern SpatialPartitionCell gDynamicSurfacePartition[NUM_CELLS][NUM_CELLS];
extern struct SurfaceNode *sSurfaceNodePool; extern struct SurfaceNode *sSurfaceNodePool;
extern struct Surface *sSurfacePool; extern struct Surface *sSurfacePool;
extern s16 sSurfacePoolSize; extern s16 sSurfacePoolSize;

View file

@ -71,7 +71,6 @@ u8 gSpawnedStarHiddenCount = 0;
* the spawn behavior executed, the index of that behavior is used with sSpawnTypeFromWarpBhv * the spawn behavior executed, the index of that behavior is used with sSpawnTypeFromWarpBhv
*/ */
// D_8032CE9C
const BehaviorScript *sWarpBhvSpawnTable[] = { const BehaviorScript *sWarpBhvSpawnTable[] = {
bhvDoorWarp, bhvStar, bhvExitPodiumWarp, bhvWarp, bhvDoorWarp, bhvStar, bhvExitPodiumWarp, bhvWarp,
bhvWarpPipe, bhvFadingWarp, bhvInstantActiveWarp, bhvAirborneWarp, bhvWarpPipe, bhvFadingWarp, bhvInstantActiveWarp, bhvAirborneWarp,
@ -80,7 +79,6 @@ const BehaviorScript *sWarpBhvSpawnTable[] = {
bhvAirborneStarCollectWarp, bhvAirborneDeathWarp, bhvLaunchStarCollectWarp, bhvLaunchDeathWarp, bhvAirborneStarCollectWarp, bhvAirborneDeathWarp, bhvLaunchStarCollectWarp, bhvLaunchDeathWarp,
}; };
// D_8032CEEC
u8 sSpawnTypeFromWarpBhv[] = { u8 sSpawnTypeFromWarpBhv[] = {
MARIO_SPAWN_DOOR_WARP, MARIO_SPAWN_UNKNOWN_02, MARIO_SPAWN_UNKNOWN_03, MARIO_SPAWN_UNKNOWN_03, MARIO_SPAWN_DOOR_WARP, MARIO_SPAWN_UNKNOWN_02, MARIO_SPAWN_UNKNOWN_03, MARIO_SPAWN_UNKNOWN_03,
MARIO_SPAWN_UNKNOWN_03, MARIO_SPAWN_TELEPORT, MARIO_SPAWN_INSTANT_ACTIVE, MARIO_SPAWN_AIRBORNE, MARIO_SPAWN_UNKNOWN_03, MARIO_SPAWN_TELEPORT, MARIO_SPAWN_INSTANT_ACTIVE, MARIO_SPAWN_AIRBORNE,
@ -126,7 +124,7 @@ static int scale_x_to_correct_aspect_center(int x) {
void print_intro_text(void) { void print_intro_text(void) {
#ifdef VERSION_EU #ifdef VERSION_EU
int language = eu_get_language(); s32 language = eu_get_language();
#endif #endif
if ((gGlobalTimer & 0x1F) < 20) { if ((gGlobalTimer & 0x1F) < 20) {
if (gControllerBits == 0) { if (gControllerBits == 0) {
@ -325,7 +323,7 @@ void change_area(s32 index) {
if (areaFlags & 0x01) { if (areaFlags & 0x01) {
for (int i = 0; i < MAX_PLAYERS; i++) { for (int i = 0; i < MAX_PLAYERS; i++) {
gMarioStates[i].marioObj->header.gfx.unk18 = index; gMarioStates[i].marioObj->header.gfx.areaIndex = index;
gMarioStates[i].spawnInfo->areaIndex = index; gMarioStates[i].spawnInfo->areaIndex = index;
} }
} }
@ -434,7 +432,7 @@ void render_game(void) {
if (gWarpTransition.isActive) { if (gWarpTransition.isActive) {
if (gWarpTransDelay == 0) { if (gWarpTransDelay == 0) {
gWarpTransition.isActive = !render_screen_transition(0, gWarpTransition.type, gWarpTransition.time, gWarpTransition.isActive = !render_screen_transition(0, gWarpTransition.type, gWarpTransition.time,
&gWarpTransition.data); &gWarpTransition.data);
if (!gWarpTransition.isActive) { if (!gWarpTransition.isActive) {
if (gWarpTransition.type & 1) { if (gWarpTransition.type & 1) {
gWarpTransition.pauseRendering = TRUE; gWarpTransition.pauseRendering = TRUE;
@ -448,7 +446,7 @@ void render_game(void) {
} }
} else { } else {
render_text_labels(); render_text_labels();
if (D_8032CE78 != 0) { if (D_8032CE78 != NULL) {
clear_viewport(D_8032CE78, gWarpTransFBSetColor); clear_viewport(D_8032CE78, gWarpTransFBSetColor);
} else { } else {
clear_frame_buffer(gWarpTransFBSetColor); clear_frame_buffer(gWarpTransFBSetColor);
@ -456,7 +454,7 @@ void render_game(void) {
} }
D_8032CE74 = NULL; D_8032CE74 = NULL;
D_8032CE78 = 0; D_8032CE78 = NULL;
} }
void get_area_minimum_y(u8* hasMinY, f32* minY) { void get_area_minimum_y(u8* hasMinY, f32* minY) {

View file

@ -247,7 +247,7 @@ void vec3f_copy_2(Vec3f dest, Vec3f src) {
s32 set_obj_anim_with_accel_and_sound(s16 a0, s16 a1, s32 a2) { s32 set_obj_anim_with_accel_and_sound(s16 a0, s16 a1, s32 a2) {
f32 sp1C; f32 sp1C;
if ((sp1C = o->header.gfx.unk38.animAccel / (f32) 0x10000) == 0) if ((sp1C = o->header.gfx.animInfo.animAccel / (f32) 0x10000) == 0)
sp1C = 1.0f; sp1C = 1.0f;
if (cur_obj_check_anim_frame_in_range(a0, sp1C) || cur_obj_check_anim_frame_in_range(a1, sp1C)) { if (cur_obj_check_anim_frame_in_range(a0, sp1C) || cur_obj_check_anim_frame_in_range(a1, sp1C)) {
cur_obj_play_sound_2(a2); cur_obj_play_sound_2(a2);

View file

@ -152,7 +152,7 @@ static void homing_amp_chase_loop(void) {
check_amp_attack(); check_amp_attack();
// Give up if Mario goes further than 1500 units from the amp's original position // Give up if Mario goes further than 1500 units from the amp's original position
if (is_point_within_radius_of_mario(o->oHomeX, o->oHomeY, o->oHomeZ, 1500) == FALSE) { if (!is_point_within_radius_of_mario(o->oHomeX, o->oHomeY, o->oHomeZ, 1500)) {
o->oAction = HOMING_AMP_ACT_GIVE_UP; o->oAction = HOMING_AMP_ACT_GIVE_UP;
} }
} }
@ -184,7 +184,7 @@ static void homing_amp_give_up_loop(void) {
*/ */
static void amp_attack_cooldown_loop(void) { static void amp_attack_cooldown_loop(void) {
// Turn intangible and wait for 90 frames before chasing Mario again after hitting him. // Turn intangible and wait for 90 frames before chasing Mario again after hitting him.
o->header.gfx.unk38.animFrame += 2; o->header.gfx.animInfo.animFrame += 2;
o->oForwardVel = 0; o->oForwardVel = 0;
cur_obj_become_intangible(); cur_obj_become_intangible();

View file

@ -87,7 +87,7 @@ void bhv_merry_go_round_loop(void) {
} }
// Rotate the merry-go-round and play appropriate music if it's not stopped. // Rotate the merry-go-round and play appropriate music if it's not stopped.
if (o->oMerryGoRoundStopped == FALSE) { if (!o->oMerryGoRoundStopped) {
o->oAngleVelYaw = 0x80; o->oAngleVelYaw = 0x80;
o->oMoveAngleYaw += o->oAngleVelYaw; o->oMoveAngleYaw += o->oAngleVelYaw;
o->oFaceAngleYaw += o->oAngleVelYaw; o->oFaceAngleYaw += o->oAngleVelYaw;

View file

@ -73,13 +73,13 @@ void bobomb_act_patrol(void) {
UNUSED s16 sp22; UNUSED s16 sp22;
s16 collisionFlags; s16 collisionFlags;
sp22 = o->header.gfx.unk38.animFrame; sp22 = o->header.gfx.animInfo.animFrame;
o->oForwardVel = 5.0; o->oForwardVel = 5.0;
collisionFlags = object_step(); collisionFlags = object_step();
struct Object* player = nearest_player_to_object(o); struct Object* player = nearest_player_to_object(o);
if ((obj_return_home_if_safe(o, o->oHomeX, o->oHomeY, o->oHomeZ, 400) == 1) if ((obj_return_home_if_safe(o, o->oHomeX, o->oHomeY, o->oHomeZ, 400) == 1)
&& (obj_check_if_facing_toward_angle(o->oMoveAngleYaw, obj_angle_to_object(o, player), 0x2000) == 1)) { && (obj_check_if_facing_toward_angle(o->oMoveAngleYaw, obj_angle_to_object(o, player), 0x2000) == TRUE)) {
o->oBobombFuseLit = 1; o->oBobombFuseLit = 1;
o->oAction = BOBOMB_ACT_CHASE_MARIO; o->oAction = BOBOMB_ACT_CHASE_MARIO;
} }
@ -90,7 +90,7 @@ void bobomb_act_chase_mario(void) {
UNUSED u8 filler[4]; UNUSED u8 filler[4];
s16 sp1a, collisionFlags; s16 sp1a, collisionFlags;
sp1a = ++o->header.gfx.unk38.animFrame; sp1a = ++o->header.gfx.animInfo.animFrame;
o->oForwardVel = 20.0; o->oForwardVel = 20.0;
collisionFlags = object_step(); collisionFlags = object_step();
@ -300,7 +300,7 @@ void bhv_bobomb_buddy_init(void) {
void bobomb_buddy_act_idle(void) { void bobomb_buddy_act_idle(void) {
UNUSED u8 filler[4]; UNUSED u8 filler[4];
s16 sp1a = o->header.gfx.unk38.animFrame; s16 sp1a = o->header.gfx.animInfo.animFrame;
UNUSED s16 collisionFlags = 0; UNUSED s16 collisionFlags = 0;
o->oBobombBuddyPosXCopy = o->oPosX; o->oBobombBuddyPosXCopy = o->oPosX;
@ -408,7 +408,7 @@ void bobomb_buddy_act_talk(void) {
} }
void bobomb_buddy_act_turn_to_talk(void) { void bobomb_buddy_act_turn_to_talk(void) {
s16 sp1e = o->header.gfx.unk38.animFrame; s16 sp1e = o->header.gfx.animInfo.animFrame;
if ((sp1e == 5) || (sp1e == 16)) if ((sp1e == 5) || (sp1e == 16))
cur_obj_play_sound_2(SOUND_OBJ_BOBOMB_WALK); cur_obj_play_sound_2(SOUND_OBJ_BOBOMB_WALK);

View file

@ -60,7 +60,7 @@ static s32 boo_should_be_stopped(void) {
if (gMarioStates[i].currentRoom == BBH_DYNAMIC_SURFACE_ROOM || gMarioStates[i].currentRoom == BBH_NEAR_MERRY_GO_ROUND_ROOM) { return FALSE; } if (gMarioStates[i].currentRoom == BBH_DYNAMIC_SURFACE_ROOM || gMarioStates[i].currentRoom == BBH_NEAR_MERRY_GO_ROUND_ROOM) { return FALSE; }
} }
return TRUE; return TRUE;
/*if (gMarioOnMerryGoRound == FALSE) { /*if (!gMarioOnMerryGoRound) {
return TRUE; return TRUE;
} else { } else {
return FALSE; return FALSE;
@ -352,7 +352,7 @@ static s32 boo_get_attack_status(void) {
s32 attackStatus = BOO_NOT_ATTACKED; s32 attackStatus = BOO_NOT_ATTACKED;
if (o->oInteractStatus & INT_STATUS_INTERACTED) { if (o->oInteractStatus & INT_STATUS_INTERACTED) {
if ((o->oInteractStatus & INT_STATUS_WAS_ATTACKED) && obj_has_attack_type(ATTACK_FROM_ABOVE) == FALSE) { if ((o->oInteractStatus & INT_STATUS_WAS_ATTACKED) && !obj_has_attack_type(ATTACK_FROM_ABOVE)) {
cur_obj_become_intangible(); cur_obj_become_intangible();
o->oInteractStatus = 0; o->oInteractStatus = 0;
@ -625,7 +625,7 @@ static void big_boo_act_1(void) {
if (gMarioStates[i].currentRoom == BBH_DYNAMIC_SURFACE_ROOM || gMarioStates[i].currentRoom == BBH_NEAR_MERRY_GO_ROUND_ROOM) { inRoom = TRUE; } if (gMarioStates[i].currentRoom == BBH_DYNAMIC_SURFACE_ROOM || gMarioStates[i].currentRoom == BBH_NEAR_MERRY_GO_ROUND_ROOM) { inRoom = TRUE; }
} }
//if (gMarioOnMerryGoRound == FALSE) { //if (!gMarioOnMerryGoRound) {
if (!inRoom) { if (!inRoom) {
o->oAction = 0; o->oAction = 0;
} }

View file

@ -71,8 +71,8 @@ void bhv_bowser_flame_spawn_loop(void) {
f32 sp20 = sins(bowser->oMoveAngleYaw); f32 sp20 = sins(bowser->oMoveAngleYaw);
s16 *sp1C = segmented_to_virtual(bowser_seg6_unkmoveshorts_060576FC); s16 *sp1C = segmented_to_virtual(bowser_seg6_unkmoveshorts_060576FC);
if (bowser->oSoundStateID == 6) { if (bowser->oSoundStateID == 6) {
sp30 = bowser->header.gfx.unk38.animFrame + 1.0f; sp30 = bowser->header.gfx.animInfo.animFrame + 1.0f;
if (bowser->header.gfx.unk38.curAnim->unk08 == sp30) if (bowser->header.gfx.animInfo.curAnim->loopEnd == sp30)
sp30 = 0; sp30 = 0;
if (sp30 > 45 && sp30 < 85) { if (sp30 > 45 && sp30 < 85) {
cur_obj_play_sound_1(SOUND_AIR_BOWSER_SPIT_FIRE); cur_obj_play_sound_1(SOUND_AIR_BOWSER_SPIT_FIRE);
@ -467,7 +467,7 @@ void bowser_act_spit_fire_into_sky(void) // only in sky
{ {
s32 frame; s32 frame;
cur_obj_init_animation_with_sound(11); cur_obj_init_animation_with_sound(11);
frame = o->header.gfx.unk38.animFrame; frame = o->header.gfx.animInfo.animFrame;
if (frame > 24 && frame < 36) { if (frame > 24 && frame < 36) {
cur_obj_play_sound_1(SOUND_AIR_BOWSER_SPIT_FIRE); cur_obj_play_sound_1(SOUND_AIR_BOWSER_SPIT_FIRE);
struct MarioState* marioState = nearest_mario_state_to_object(o); struct MarioState* marioState = nearest_mario_state_to_object(o);
@ -540,7 +540,7 @@ s32 bowser_land(void) {
o->oVelY = 0; o->oVelY = 0;
spawn_mist_particles_variable(0, 0, 60.0f); spawn_mist_particles_variable(0, 0, 60.0f);
cur_obj_init_animation_with_sound(8); cur_obj_init_animation_with_sound(8);
o->header.gfx.unk38.animFrame = 0; o->header.gfx.animInfo.animFrame = 0;
cur_obj_start_cam_event(o, CAM_EVENT_BOWSER_JUMP); cur_obj_start_cam_event(o, CAM_EVENT_BOWSER_JUMP);
if (BITDW) { if (BITDW) {
if (distanceToPlayer < 850.0f) if (distanceToPlayer < 850.0f)
@ -1167,7 +1167,7 @@ void bowser_free_update(void) {
struct Object *platform; struct Object *platform;
UNUSED f32 floorHeight; UNUSED f32 floorHeight;
if ((platform = o->platform) != NULL) if ((platform = o->platform) != NULL)
apply_platform_displacement((u32)-1, platform); apply_platform_displacement(FALSE, platform);
o->oBowserUnk10E = 0; o->oBowserUnk10E = 0;
cur_obj_update_floor_and_walls(); cur_obj_update_floor_and_walls();
@ -1249,7 +1249,7 @@ void bhv_bowser_loop(void) {
struct Animation* anim = NULL; struct Animation* anim = NULL;
if (o->oAnimations != NULL && networkBowserAnimationIndex <= 26) { if (o->oAnimations != NULL && networkBowserAnimationIndex <= 26) {
anim = o->oAnimations[networkBowserAnimationIndex]; anim = o->oAnimations[networkBowserAnimationIndex];
if (anim != NULL && o->header.gfx.unk38.curAnim != anim) { if (anim != NULL && o->header.gfx.animInfo.curAnim != anim) {
geo_obj_init_animation(&o->header.gfx, &anim); geo_obj_init_animation(&o->header.gfx, &anim);
} }
} }
@ -1300,9 +1300,9 @@ void bhv_bowser_loop(void) {
// update animation index // update animation index
anim = o->oAnimations[networkBowserAnimationIndex]; anim = o->oAnimations[networkBowserAnimationIndex];
if (o->header.gfx.unk38.curAnim != anim) { if (o->header.gfx.animInfo.curAnim != anim) {
for (int i = 0; i < 32; i++) { for (int i = 0; i < 32; i++) {
if (o->header.gfx.unk38.curAnim == o->oAnimations[i]) { if (o->header.gfx.animInfo.curAnim == o->oAnimations[i]) {
networkBowserAnimationIndex = i; networkBowserAnimationIndex = i;
} }
} }
@ -1352,7 +1352,7 @@ void bhv_bowser_init(void) {
so->fullObjectSync = TRUE; so->fullObjectSync = TRUE;
network_init_object_field(o, &o->header.gfx.node.flags); network_init_object_field(o, &o->header.gfx.node.flags);
network_init_object_field(o, &networkBowserAnimationIndex); network_init_object_field(o, &networkBowserAnimationIndex);
network_init_object_field(o, &o->header.gfx.unk38.animFrame); network_init_object_field(o, &o->header.gfx.animInfo.animFrame);
} }
#undef BITDW #undef BITDW

View file

@ -11,7 +11,7 @@ Gfx *geo_scale_bowser_key(s32 run, struct GraphNode *node, UNUSED f32 mtx[4][4])
void bhv_bowser_key_unlock_door_loop(void) { void bhv_bowser_key_unlock_door_loop(void) {
s32 animTimer; s32 animTimer;
animTimer = o->header.gfx.unk38.animFrame; animTimer = o->header.gfx.animInfo.animFrame;
cur_obj_init_animation_with_sound(0); cur_obj_init_animation_with_sound(0);
if (animTimer < 38) if (animTimer < 38)
o->oBowserKeyScale = 0.0f; o->oBowserKeyScale = 0.0f;
@ -30,7 +30,7 @@ void bhv_bowser_key_unlock_door_loop(void) {
} }
void bhv_bowser_key_course_exit_loop(void) { void bhv_bowser_key_course_exit_loop(void) {
s32 animTimer = o->header.gfx.unk38.animFrame; s32 animTimer = o->header.gfx.animInfo.animFrame;
cur_obj_init_animation_with_sound(1); cur_obj_init_animation_with_sound(1);
if (animTimer < 38) if (animTimer < 38)
o->oBowserKeyScale = 0.2f; o->oBowserKeyScale = 0.2f;

View file

@ -136,7 +136,7 @@ void bully_act_knockback(void) {
o->oMoveAngleYaw = o->oFaceAngleYaw; o->oMoveAngleYaw = o->oFaceAngleYaw;
obj_turn_toward_object(o, player, 16, 1280); obj_turn_toward_object(o, player, 16, 1280);
} else } else
o->header.gfx.unk38.animFrame = 0; o->header.gfx.animInfo.animFrame = 0;
if (o->oBullyKBTimerAndMinionKOCounter == 18) { if (o->oBullyKBTimerAndMinionKOCounter == 18) {
o->oAction = BULLY_ACT_CHASE_MARIO; o->oAction = BULLY_ACT_CHASE_MARIO;
@ -177,7 +177,7 @@ void bully_backup_check(s16 collisionFlags) {
} }
void bully_play_stomping_sound(void) { void bully_play_stomping_sound(void) {
s16 sp26 = o->header.gfx.unk38.animFrame; s16 sp26 = o->header.gfx.animInfo.animFrame;
switch (o->oAction) { switch (o->oAction) {
case BULLY_ACT_PATROL: case BULLY_ACT_PATROL:
if (sp26 == 0 || sp26 == 12) { if (sp26 == 0 || sp26 == 12) {

View file

@ -4,7 +4,7 @@ void bhv_butterfly_init(void) {
cur_obj_init_animation(1); cur_obj_init_animation(1);
o->oButterflyYPhase = random_float() * 100.0f; o->oButterflyYPhase = random_float() * 100.0f;
o->header.gfx.unk38.animFrame = random_float() * 7.0f; o->header.gfx.animInfo.animFrame = random_float() * 7.0f;
o->oHomeX = o->oPosX; o->oHomeX = o->oPosX;
o->oHomeY = o->oPosY; o->oHomeY = o->oPosY;
o->oHomeZ = o->oPosZ; o->oHomeZ = o->oPosZ;

View file

@ -30,7 +30,7 @@ static void bhv_camera_lakitu_on_received_post(u8 localIndex) {
void bhv_camera_lakitu_init(void) { void bhv_camera_lakitu_init(void) {
if (o->oBehParams2ndByte != CAMERA_LAKITU_BP_FOLLOW_CAMERA) { if (o->oBehParams2ndByte != CAMERA_LAKITU_BP_FOLLOW_CAMERA) {
// Despawn unless this is the very beginning of the game // Despawn unless this is the very beginning of the game
if (gShouldNotPlayCastleMusic != TRUE) { if (gNeverEnteredCastle != TRUE) {
obj_mark_for_deletion(o); obj_mark_for_deletion(o);
return; return;
} }

View file

@ -1,6 +1,7 @@
// castle_cannon_grate.inc.c // castle_cannon_grate.inc.c
void bhv_castle_cannon_grate_init(void) { void bhv_castle_cannon_grate_init(void) {
if (save_file_get_total_star_count(gCurrSaveFileNum - 1, 0, 24) >= 120) if (save_file_get_total_star_count(gCurrSaveFileNum - 1, COURSE_MIN - 1, COURSE_MAX - 1) >= 120) {
o->activeFlags = ACTIVE_FLAG_DEACTIVATED; o->activeFlags = ACTIVE_FLAG_DEACTIVATED;
}
} }

View file

@ -1,5 +1,5 @@
// castle_flag.inc.c // castle_flag.inc.c
void bhv_castle_flag_init(void) { void bhv_castle_flag_init(void) {
o->header.gfx.unk38.animFrame = random_float() * 28.0f; o->header.gfx.animInfo.animFrame = random_float() * 28.0f;
} }

View file

@ -466,7 +466,7 @@ void bhv_chain_chomp_update(void) {
struct SyncObject* so = network_init_object(o, 1000.0f); struct SyncObject* so = network_init_object(o, 1000.0f);
so->syncDeathEvent = FALSE; so->syncDeathEvent = FALSE;
network_init_object_field(o, &o->oChainChompUnk104); network_init_object_field(o, &o->oChainChompUnk104);
network_init_object_field(o, &o->header.gfx.unk38.animFrame); network_init_object_field(o, &o->header.gfx.animInfo.animFrame);
} }
switch (o->oAction) { switch (o->oAction) {

View file

@ -140,9 +140,7 @@ void spawn_coin_in_formation(s32 sp50, s32 sp54) {
Vec3i sp40; Vec3i sp40;
s32 sp3C = 1; s32 sp3C = 1;
s32 sp38 = 1; s32 sp38 = 1;
UNUSED s32 unused; sp40[0] = sp40[1] = sp40[2] = 0;
sp40[2] = 0;
sp40[0] = (sp40[1] = sp40[2]);
switch (sp54 & 7) { switch (sp54 & 7) {
case 0: case 0:
sp40[2] = 160 * (sp50 - 2); sp40[2] = 160 * (sp50 - 2);

View file

@ -29,8 +29,8 @@ u8 door_allow_walk_through(void) {
if (gCamera->mode != CAMERA_MODE_NEWCAM) { return FALSE; } if (gCamera->mode != CAMERA_MODE_NEWCAM) { return FALSE; }
} }
s32 cur = o->header.gfx.unk38.animFrame; s32 cur = o->header.gfx.animInfo.animFrame;
s32 max = o->header.gfx.unk38.curAnim->unk08 - 2; s32 max = o->header.gfx.animInfo.curAnim->loopEnd - 2;
s32 min = max / 4; s32 min = max / 4;
// make non-solid immediately for local actions so the camera doesn't glitch out // make non-solid immediately for local actions so the camera doesn't glitch out

View file

@ -132,7 +132,7 @@ void dorrie_act_raise_head(void) {
if (cur_obj_check_if_near_animation_end()) { if (cur_obj_check_if_near_animation_end()) {
o->oAction = DORRIE_ACT_MOVE; o->oAction = DORRIE_ACT_MOVE;
for (int i = 0; i < MAX_PLAYERS; i++) { dorrieLiftingPlayer[i] = FALSE; } for (int i = 0; i < MAX_PLAYERS; i++) { dorrieLiftingPlayer[i] = FALSE; }
} else if (o->oDorrieLiftingMario && o->header.gfx.unk38.animFrame < 74) { } else if (o->oDorrieLiftingMario && o->header.gfx.animInfo.animFrame < 74) {
for (int i = 0; i < MAX_PLAYERS; i++) { for (int i = 0; i < MAX_PLAYERS; i++) {
if (!is_player_active(&gMarioStates[i])) { continue; } if (!is_player_active(&gMarioStates[i])) { continue; }

View file

@ -235,7 +235,7 @@ void fish_group_act_move(void) {
*/ */
void fish_group_act_animate(void) { void fish_group_act_animate(void) {
cur_obj_init_animation_with_accel_and_sound(0, 1.0f); cur_obj_init_animation_with_accel_and_sound(0, 1.0f);
o->header.gfx.unk38.animFrame = (s16)(random_float() * 28.0f); o->header.gfx.animInfo.animFrame = (s16)(random_float() * 28.0f);
o->oFishDepthDistance = random_float() * 300.0f; o->oFishDepthDistance = random_float() * 300.0f;
cur_obj_scale(random_float() * 0.4 + 0.8); cur_obj_scale(random_float() * 0.4 + 0.8);
o->oAction = FISH_ACT_ACTIVE; o->oAction = FISH_ACT_ACTIVE;

View file

@ -18,24 +18,24 @@ void bhv_small_piranha_flame_loop(void) {
} }
} else { } else {
cur_obj_update_floor_and_walls(); cur_obj_update_floor_and_walls();
if (approach_f32_ptr(&o->oSmallPiranhaFlameUnkF4, o->oSmallPiranhaFlameUnkF8, 0.6f)) { if (approach_f32_ptr(&o->oSmallPiranhaFlameStartSpeed, o->oSmallPiranhaFlameEndSpeed, 0.6f)) {
cur_obj_rotate_yaw_toward(angleToPlayer, 0x200); cur_obj_rotate_yaw_toward(angleToPlayer, 0x200);
} }
obj_compute_vel_from_move_pitch(o->oSmallPiranhaFlameUnkF4); obj_compute_vel_from_move_pitch(o->oSmallPiranhaFlameStartSpeed);
cur_obj_move_standard(-78); cur_obj_move_standard(-78);
spawn_object_with_scale(o, o->oSmallPiranhaFlameUnkFC, bhvSmallPiranhaFlame, spawn_object_with_scale(o, o->oSmallPiranhaFlameModel, bhvSmallPiranhaFlame,
0.4f * o->header.gfx.scale[0]); 0.4f * o->header.gfx.scale[0]);
if (o->oTimer > o->oSmallPiranhaFlameUnk100) { if (o->oTimer > o->oSmallPiranhaFlameUnk100) {
spawn_object_relative_with_scale(1, 0, o->oGraphYOffset, 0, o->header.gfx.scale[0], o, spawn_object_relative_with_scale(1, 0, o->oGraphYOffset, 0, o->header.gfx.scale[0], o,
o->oSmallPiranhaFlameUnkFC, bhvFlyguyFlame); o->oSmallPiranhaFlameModel, bhvFlyguyFlame);
o->oSmallPiranhaFlameUnk100 = random_linear_offset(8, 15); o->oSmallPiranhaFlameUnk100 = random_linear_offset(8, 15);
o->oTimer = 0; o->oTimer = 0;
} }
obj_check_attacks(&sPiranhaPlantFireHitbox, o->oAction); obj_check_attacks(&sPiranhaPlantFireHitbox, o->oAction);
o->oSmallPiranhaFlameUnk104 += o->oSmallPiranhaFlameUnkF4; o->oSmallPiranhaFlameUnk104 += o->oSmallPiranhaFlameStartSpeed;
if (o->oSmallPiranhaFlameUnk104 > 1500.0f || (o->oMoveFlags & (OBJ_MOVE_HIT_WALL | OBJ_MOVE_MASK_IN_WATER))) { if (o->oSmallPiranhaFlameUnk104 > 1500.0f || (o->oMoveFlags & (OBJ_MOVE_HIT_WALL | OBJ_MOVE_MASK_IN_WATER))) {
obj_die_if_health_non_positive(); obj_die_if_health_non_positive();

View file

@ -50,7 +50,7 @@ void bhv_flamethrower_loop(void) {
s32 model; s32 model;
UNUSED u8 pad[8]; UNUSED u8 pad[8];
if (o->oAction == 0) { if (o->oAction == 0) {
if (gCurrLevelNum != LEVEL_BBH || gMarioOnMerryGoRound == 1) { if (gCurrLevelNum != LEVEL_BBH || gMarioOnMerryGoRound == TRUE) {
if (marioState->playerIndex == 0 && distanceToPlayer < 2000.0f) { if (marioState->playerIndex == 0 && distanceToPlayer < 2000.0f) {
o->oAction++; o->oAction++;
network_send_object(o); network_send_object(o);

View file

@ -29,7 +29,7 @@ void heave_ho_act_1(void) {
s32 sp1C = 0; s32 sp1C = 0;
o->oForwardVel = 0.0f; o->oForwardVel = 0.0f;
cur_obj_reverse_animation(); cur_obj_reverse_animation();
while (1) { while (TRUE) {
if (D_8032F460[sp1C][0] == -1) { if (D_8032F460[sp1C][0] == -1) {
o->oAction = 2; o->oAction = 2;
break; break;

View file

@ -21,7 +21,7 @@ void bhv_hoot_init(void) {
so->ignore_if_true = bhv_hoot_ignore_if_true; so->ignore_if_true = bhv_hoot_ignore_if_true;
network_init_object_field(o, &o->oHootAvailability); network_init_object_field(o, &o->oHootAvailability);
network_init_object_field(o, &o->oMoveAnglePitch); network_init_object_field(o, &o->oMoveAnglePitch);
network_init_object_field(o, &o->header.gfx.unk38.animFrame); network_init_object_field(o, &o->header.gfx.animInfo.animFrame);
} }
// sp28 = arg0 // sp28 = arg0
@ -62,7 +62,7 @@ void hoot_free_step(s16 fastOscY, s32 speed) {
struct FloorGeometry *sp2c; struct FloorGeometry *sp2c;
s16 yaw = o->oMoveAngleYaw; s16 yaw = o->oMoveAngleYaw;
s16 pitch = o->oMoveAnglePitch; s16 pitch = o->oMoveAnglePitch;
s16 sp26 = o->header.gfx.unk38.animFrame; s16 sp26 = o->header.gfx.animInfo.animFrame;
f32 xPrev = o->oPosX; f32 xPrev = o->oPosX;
f32 zPrev = o->oPosZ; f32 zPrev = o->oPosZ;
f32 hSpeed; f32 hSpeed;
@ -109,7 +109,7 @@ void hoot_player_set_yaw(void) {
void hoot_carry_step(s32 speed, UNUSED f32 xPrev, UNUSED f32 zPrev) { void hoot_carry_step(s32 speed, UNUSED f32 xPrev, UNUSED f32 zPrev) {
s16 yaw = o->oMoveAngleYaw; s16 yaw = o->oMoveAngleYaw;
s16 pitch = o->oMoveAnglePitch; s16 pitch = o->oMoveAnglePitch;
s16 sp22 = o->header.gfx.unk38.animFrame; s16 sp22 = o->header.gfx.animInfo.animFrame;
f32 hSpeed; f32 hSpeed;
o->oVelY = sins(pitch) * speed; o->oVelY = sins(pitch) * speed;
@ -176,7 +176,7 @@ void hoot_act_ascent(f32 xPrev, f32 zPrev) {
if (o->oTimer >= 29) { if (o->oTimer >= 29) {
cur_obj_play_sound_1(SOUND_ENV_WIND2); cur_obj_play_sound_1(SOUND_ENV_WIND2);
o->header.gfx.unk38.animFrame = 1; o->header.gfx.animInfo.animFrame = 1;
} }
if (o->oPosY > 6500.0f) if (o->oPosY > 6500.0f)

View file

@ -29,7 +29,7 @@ void bhv_intro_peach_loop(void) {
gCurrentObject->oIntroPeachPitchFromFocus = -9984.f; gCurrentObject->oIntroPeachPitchFromFocus = -9984.f;
gCurrentObject->oIntroPeachYawFromFocus = -768.f; gCurrentObject->oIntroPeachYawFromFocus = -768.f;
gCurrentObject->oOpacity = 255; gCurrentObject->oOpacity = 255;
gCurrentObject->header.gfx.unk38.animFrame = 100; gCurrentObject->header.gfx.animInfo.animFrame = 100;
break; break;
case 1: case 1:
intro_peach_set_pos_and_opacity(gCurrentObject, 0.f, 0.f); intro_peach_set_pos_and_opacity(gCurrentObject, 0.f, 0.f);

View file

@ -5,7 +5,7 @@ void spawn_child_obj_relative(struct Object *parent, s16 xOffset, s16 yOffset, s
s32 model, const BehaviorScript *behavior) { s32 model, const BehaviorScript *behavior) {
struct Object *sp1C = spawn_object(parent, model, behavior); struct Object *sp1C = spawn_object(parent, model, behavior);
sp1C->header.gfx.unk38.animFrame = random_float() * 6.f; sp1C->header.gfx.animInfo.animFrame = random_float() * 6.f;
sp1C->oEndBirdUnk104 = sCutsceneVars[9].point[0]; sp1C->oEndBirdUnk104 = sCutsceneVars[9].point[0];
sCutsceneVars[9].point[0] += 1.f; sCutsceneVars[9].point[0] += 1.f;
sp1C->oPosX += xOffset; sp1C->oPosX += xOffset;

View file

@ -47,8 +47,8 @@ u8 king_bobomb_act_0_continue_dialog(void) { return o->oAction == 0 && o->oSubAc
void king_bobomb_act_0(void) { void king_bobomb_act_0(void) {
#ifndef VERSION_JP #ifndef VERSION_JP
o->oForwardVel = 0; o->oForwardVel = 0.0f;
o->oVelY = 0; o->oVelY = 0.0f;
#endif #endif
struct MarioState* marioState = nearest_mario_state_to_object(o); struct MarioState* marioState = nearest_mario_state_to_object(o);
if (o->oSubAction == 0) { if (o->oSubAction == 0) {
@ -67,7 +67,7 @@ void king_bobomb_act_0(void) {
} }
} }
int mario_is_far_below_object(f32 arg0) { s32 mario_is_far_below_object(f32 arg0) {
for (int i = 0; i < MAX_PLAYERS; i++) { for (int i = 0; i < MAX_PLAYERS; i++) {
if (!is_player_active(&gMarioStates[i])) { continue; } if (!is_player_active(&gMarioStates[i])) { continue; }
if (arg0 >= o->oPosY - gMarioStates[i].marioObj->oPosY) { return FALSE; } if (arg0 >= o->oPosY - gMarioStates[i].marioObj->oPosY) { return FALSE; }

View file

@ -34,7 +34,7 @@ static s32 klepto_set_and_check_if_anim_at_end(void) {
} else if (o->oSoundStateID == 5) { } else if (o->oSoundStateID == 5) {
if (cur_obj_set_anim_if_at_end(0)) { if (cur_obj_set_anim_if_at_end(0)) {
cur_obj_play_sound_2(SOUND_GENERAL_SWISH_WATER); cur_obj_play_sound_2(SOUND_GENERAL_SWISH_WATER);
o->header.gfx.unk38.animFrame = 9; o->header.gfx.animInfo.animFrame = 9;
} }
} else { } else {
if (cur_obj_check_anim_frame(9)) { if (cur_obj_check_anim_frame(9)) {

View file

@ -44,7 +44,7 @@ void manta_ray_move(void) {
s16 sp1E; s16 sp1E;
s32 sp18; s32 sp18;
sp1E = o->header.gfx.unk38.animFrame; sp1E = o->header.gfx.animInfo.animFrame;
gCurrentObject->oPathedStartWaypoint = (struct Waypoint *) sMantaRayTraj; gCurrentObject->oPathedStartWaypoint = (struct Waypoint *) sMantaRayTraj;
sp18 = cur_obj_follow_path(sp18); sp18 = cur_obj_follow_path(sp18);
o->oMantaUnkF8 = o->oPathedTargetYaw; o->oMantaUnkF8 = o->oPathedTargetYaw;

View file

@ -37,7 +37,7 @@ void bhv_pushable_loop(void) {
s16 sp1C; s16 sp1C;
obj_set_hitbox(o, &sMetalBoxHitbox); obj_set_hitbox(o, &sMetalBoxHitbox);
o->oForwardVel = 0.0f; o->oForwardVel = 0.0f;
if (obj_check_if_collided_with_object(o, player) && marioState->flags & 0x80000000) { if (obj_check_if_collided_with_object(o, player) && marioState->flags & MARIO_UNKNOWN_31) {
sp1C = obj_angle_to_object(o, player); sp1C = obj_angle_to_object(o, player);
if (abs_angle_diff(sp1C, player->oMoveAngleYaw) > 0x4000) { if (abs_angle_diff(sp1C, player->oMoveAngleYaw) > 0x4000) {
o->oMoveAngleYaw = (s16)((player->oMoveAngleYaw + 0x2000) & 0xc000); o->oMoveAngleYaw = (s16)((player->oMoveAngleYaw + 0x2000) & 0xc000);

View file

@ -20,19 +20,19 @@ static void bhv_mips_on_received_post(UNUSED u8 fromLocalIndex) {
*/ */
void bhv_mips_init(void) { void bhv_mips_init(void) {
// Retrieve star flags for Castle Secret Stars on current save file. // Retrieve star flags for Castle Secret Stars on current save file.
u8 starFlags; u8 starFlags = save_file_get_star_flags(gCurrSaveFileNum - 1, -1);
starFlags = save_file_get_star_flags(gCurrSaveFileNum - 1, -1);
// If the player has >= 15 stars and hasn't collected first MIPS star... // If the player has >= 15 stars and hasn't collected first MIPS star...
if (save_file_get_total_star_count(gCurrSaveFileNum - 1, 0, 24) >= 15 && (starFlags & 0x08) == 0) { if (save_file_get_total_star_count(gCurrSaveFileNum - 1, COURSE_MIN - 1, COURSE_MAX - 1) >= 15
&& !(starFlags & SAVE_FLAG_TO_STAR_FLAG(SAVE_FLAG_COLLECTED_MIPS_STAR_1))) {
o->oBehParams2ndByte = 0; o->oBehParams2ndByte = 0;
#ifndef VERSION_JP #ifndef VERSION_JP
o->oMipsForwardVelocity = 40.0f; o->oMipsForwardVelocity = 40.0f;
#endif #endif
} }
// If the player has >= 50 stars and hasn't collected second MIPS star... // If the player has >= 50 stars and hasn't collected second MIPS star...
else if (save_file_get_total_star_count(gCurrSaveFileNum - 1, 0, 24) >= 50 else if (save_file_get_total_star_count(gCurrSaveFileNum - 1, COURSE_MIN - 1, COURSE_MAX - 1) >= 50
&& (starFlags & 0x10) == 0) { && !(starFlags & SAVE_FLAG_TO_STAR_FLAG(SAVE_FLAG_COLLECTED_MIPS_STAR_2))) {
o->oBehParams2ndByte = 1; o->oBehParams2ndByte = 1;
#ifndef VERSION_JP #ifndef VERSION_JP
o->oMipsForwardVelocity = 45.0f; o->oMipsForwardVelocity = 45.0f;
@ -187,7 +187,7 @@ void bhv_mips_act_fall_down(void) {
s16 collisionFlags = 0; s16 collisionFlags = 0;
collisionFlags = object_step(); collisionFlags = object_step();
o->header.gfx.unk38.animFrame = 0; o->header.gfx.animInfo.animFrame = 0;
if ((collisionFlags & OBJ_COL_FLAG_GROUNDED) == 1) { if ((collisionFlags & OBJ_COL_FLAG_GROUNDED) == 1) {
o->oAction = MIPS_ACT_WAIT_FOR_ANIMATION_DONE; o->oAction = MIPS_ACT_WAIT_FOR_ANIMATION_DONE;

View file

@ -65,7 +65,7 @@ void moneybag_check_mario_collision(void) {
// sp20 = collisionFlags // sp20 = collisionFlags
void moneybag_jump(s8 collisionFlags) { void moneybag_jump(s8 collisionFlags) {
s16 animFrame = o->header.gfx.unk38.animFrame; s16 animFrame = o->header.gfx.animInfo.animFrame;
switch (o->oMoneybagJumpState) { switch (o->oMoneybagJumpState) {
case MONEYBAG_JUMP_PREPARE: case MONEYBAG_JUMP_PREPARE:
@ -106,7 +106,7 @@ void moneybag_jump(s8 collisionFlags) {
if (o->oTimer >= 61) { if (o->oTimer >= 61) {
o->oMoneybagJumpState = MONEYBAG_JUMP_LANDING; o->oMoneybagJumpState = MONEYBAG_JUMP_LANDING;
o->oForwardVel = 0; o->oForwardVel = 0;
o->header.gfx.unk38.animFrame = 0; o->header.gfx.animInfo.animFrame = 0;
} }
break; break;

View file

@ -20,11 +20,13 @@ void bhv_1up_common_init(void) {
void bhv_1up_init(void) { void bhv_1up_init(void) {
bhv_1up_common_init(); bhv_1up_common_init();
if (o->oBehParams2ndByte == 1) { if (o->oBehParams2ndByte == 1) {
if ((save_file_get_flags() & 0x50) == 0) if (!(save_file_get_flags() & (SAVE_FLAG_HAVE_KEY_1 | SAVE_FLAG_UNLOCKED_BASEMENT_DOOR))) {
o->activeFlags = ACTIVE_FLAG_DEACTIVATED; o->activeFlags = ACTIVE_FLAG_DEACTIVATED;
}
} else if (o->oBehParams2ndByte == 2) { } else if (o->oBehParams2ndByte == 2) {
if ((save_file_get_flags() & 0xa0) == 0) if (!(save_file_get_flags() & (SAVE_FLAG_HAVE_KEY_2 | SAVE_FLAG_UNLOCKED_UPSTAIRS_DOOR))) {
o->activeFlags = ACTIVE_FLAG_DEACTIVATED; o->activeFlags = ACTIVE_FLAG_DEACTIVATED;
}
} }
} }

View file

@ -30,9 +30,9 @@ void bhv_piranha_plant_bubble_loop(void) {
struct Object *parent = o->parentObj; // the Piranha Plant struct Object *parent = o->parentObj; // the Piranha Plant
f32 scale = 0; f32 scale = 0;
s32 i; s32 i;
s32 frame = parent->header.gfx.unk38.animFrame; s32 frame = parent->header.gfx.animInfo.animFrame;
// TODO: rename lastFrame if it is inaccurate // TODO: rename lastFrame if it is inaccurate
s32 lastFrame = parent->header.gfx.unk38.curAnim->unk08 - 2; s32 lastFrame = parent->header.gfx.animInfo.curAnim->loopEnd - 2;
s32 UNUSED unused; s32 UNUSED unused;
f32 doneShrinkingFrame; // the first frame after shrinking is done f32 doneShrinkingFrame; // the first frame after shrinking is done
f32 beginGrowingFrame; // the frame just before growing begins f32 beginGrowingFrame; // the frame just before growing begins

View file

@ -260,7 +260,7 @@ void piranha_plant_act_biting(void) {
int distanceToPlayer = dist_between_objects(o, player); int distanceToPlayer = dist_between_objects(o, player);
int angleToPlayer = obj_angle_to_object(o, player); int angleToPlayer = obj_angle_to_object(o, player);
s32 frame = o->header.gfx.unk38.animFrame; s32 frame = o->header.gfx.animInfo.animFrame;
cur_obj_become_tangible(); cur_obj_become_tangible();

View file

@ -1,7 +1,7 @@
// seaweed.c.inc // seaweed.c.inc
void bhv_seaweed_init(void) { void bhv_seaweed_init(void) {
o->header.gfx.unk38.animFrame = random_float() * 80.0f; o->header.gfx.animInfo.animFrame = random_float() * 80.0f;
} }
void bhv_seaweed_bundle_init(void) { void bhv_seaweed_bundle_init(void) {
@ -23,7 +23,7 @@ void bhv_seaweed_bundle_init(void) {
seaweed->header.gfx.scale[0] = 0.8; seaweed->header.gfx.scale[0] = 0.8;
seaweed->header.gfx.scale[1] = 0.9; seaweed->header.gfx.scale[1] = 0.9;
seaweed->header.gfx.scale[2] = 0.8; seaweed->header.gfx.scale[2] = 0.8;
seaweed->header.gfx.unk38.animFrame = random_float() * 80.0f; seaweed->header.gfx.animInfo.animFrame = random_float() * 80.0f;
seaweed = spawn_object(o, MODEL_SEAWEED, bhvSeaweed); seaweed = spawn_object(o, MODEL_SEAWEED, bhvSeaweed);
seaweed->oFaceAngleYaw = 40500; seaweed->oFaceAngleYaw = 40500;
@ -32,7 +32,7 @@ void bhv_seaweed_bundle_init(void) {
seaweed->header.gfx.scale[0] = 0.8; seaweed->header.gfx.scale[0] = 0.8;
seaweed->header.gfx.scale[1] = 0.8; seaweed->header.gfx.scale[1] = 0.8;
seaweed->header.gfx.scale[2] = 0.8; seaweed->header.gfx.scale[2] = 0.8;
seaweed->header.gfx.unk38.animFrame = random_float() * 80.0f; seaweed->header.gfx.animInfo.animFrame = random_float() * 80.0f;
seaweed = spawn_object(o, MODEL_SEAWEED, bhvSeaweed); seaweed = spawn_object(o, MODEL_SEAWEED, bhvSeaweed);
seaweed->oFaceAngleYaw = 57236; seaweed->oFaceAngleYaw = 57236;
@ -41,5 +41,5 @@ void bhv_seaweed_bundle_init(void) {
seaweed->header.gfx.scale[0] = 1.2; seaweed->header.gfx.scale[0] = 1.2;
seaweed->header.gfx.scale[1] = 1.2; seaweed->header.gfx.scale[1] = 1.2;
seaweed->header.gfx.scale[2] = 1.2; seaweed->header.gfx.scale[2] = 1.2;
seaweed->header.gfx.unk38.animFrame = random_float() * 80.0f; seaweed->header.gfx.animInfo.animFrame = random_float() * 80.0f;
} }

View file

@ -20,7 +20,6 @@ void bhv_bowser_shock_wave_loop(void) {
sp20 = o->oBowserShockWaveUnkF4 * D_8032F420[3]; sp20 = o->oBowserShockWaveUnkF4 * D_8032F420[3];
if ((sp2C < o->oDistanceToMario && o->oDistanceToMario < sp28) if ((sp2C < o->oDistanceToMario && o->oDistanceToMario < sp28)
|| (sp24 < o->oDistanceToMario && o->oDistanceToMario < sp20)) || (sp24 < o->oDistanceToMario && o->oDistanceToMario < sp20))
gMarioStates[0].marioObj->oInteractStatus |= gMarioStates[0].marioObj->oInteractStatus |= INT_STATUS_HIT_BY_SHOCKWAVE;
0x10; // This is interact_coin, but the name sounds wrong in this behiavor
} }
} }

View file

@ -73,7 +73,8 @@ void snowmans_bottom_act_1(void) {
if (sp20 == -1) { if (sp20 == -1) {
sp1E = (u16)angleToPlayer - (u16) o->oMoveAngleYaw; sp1E = (u16)angleToPlayer - (u16) o->oMoveAngleYaw;
if (obj_check_if_facing_toward_angle(o->oMoveAngleYaw, angleToPlayer, 0x2000) == 1 && o->oSnowmansBottomUnk1AC == 1) { if (obj_check_if_facing_toward_angle(o->oMoveAngleYaw, angleToPlayer, 0x2000) == TRUE
&& o->oSnowmansBottomUnk1AC == 1) {
o->oSnowmansBottomUnkF8 = angleToPlayer; o->oSnowmansBottomUnkF8 = angleToPlayer;
} else { } else {
o->oSnowmansBottomUnkF8 = o->oMoveAngleYaw; o->oSnowmansBottomUnkF8 = o->oMoveAngleYaw;

View file

@ -3,16 +3,16 @@
/** /**
* @file Contains behavior for the ukiki objects. * @file Contains behavior for the ukiki objects.
* *
* Hat ukiki is the ukiki that steals Mario's hat. * Cap ukiki is the ukiki that steals Mario's cap.
* Cage ukiki is the ukiki that triggers the cage star. * Cage ukiki is the ukiki that triggers the cage star.
*/ */
/** /**
* Sets the hat ukiki to its home if Mario is far away * Sets the cap ukiki to its home if Mario is far away
* or makes him wait to respawn if in water. * or makes him wait to respawn if in water.
*/ */
void handle_hat_ukiki_reset(void) { void handle_cap_ukiki_reset(void) {
if (o->oBehParams2ndByte == UKIKI_HAT) { if (o->oBehParams2ndByte == UKIKI_CAP) {
if (cur_obj_mario_far_away()) { if (cur_obj_mario_far_away()) {
cur_obj_set_pos_to_home_and_stop(); cur_obj_set_pos_to_home_and_stop();
o->oAction = UKIKI_ACT_IDLE; o->oAction = UKIKI_ACT_IDLE;
@ -23,14 +23,14 @@ void handle_hat_ukiki_reset(void) {
} }
/** /**
* Returns TRUE if Mario has his hat and ukiki is * Returns TRUE if Mario has his cap and ukiki is
* the hat ukiki. * the cap ukiki.
*/ */
s32 is_hat_ukiki_and_mario_has_hat(void) { s32 is_cap_ukiki_and_mario_has_normal_cap_on_head(void) {
if (o->oBehParams2ndByte == UKIKI_HAT) { if (o->oBehParams2ndByte == UKIKI_CAP) {
for (int i = 0; i < MAX_PLAYERS; i++) { for (int i = 0; i < MAX_PLAYERS; i++) {
if (!is_player_active(&gMarioStates[i])) { continue; } if (!is_player_active(&gMarioStates[i])) { continue; }
if (!does_mario_have_hat(&gMarioStates[i])) { return FALSE; } if (!does_mario_have_normal_cap_on_head(&gMarioStates[i])) { return FALSE; }
} }
return TRUE; return TRUE;
} }
@ -130,7 +130,7 @@ void ukiki_act_idle(void) {
idle_ukiki_taunt(); idle_ukiki_taunt();
if (is_hat_ukiki_and_mario_has_hat()) { if (is_cap_ukiki_and_mario_has_normal_cap_on_head()) {
if (distanceToPlayer > 700.0f && distanceToPlayer < 1000.0f) { if (distanceToPlayer > 700.0f && distanceToPlayer < 1000.0f) {
o->oAction = UKIKI_ACT_RUN; o->oAction = UKIKI_ACT_RUN;
} else if (distanceToPlayer <= 700.0f && 200.0f < distanceToPlayer) { } else if (distanceToPlayer <= 700.0f && 200.0f < distanceToPlayer) {
@ -146,8 +146,8 @@ void ukiki_act_idle(void) {
o->oAction = UKIKI_ACT_GO_TO_CAGE; o->oAction = UKIKI_ACT_GO_TO_CAGE;
} }
// Jump away from Mario after stealing his hat. // Jump away from Mario after stealing his cap.
if (o->oUkikiTextState == UKIKI_TEXT_STOLE_HAT) { if (o->oUkikiTextState == UKIKI_TEXT_STOLE_CAP) {
o->oMoveAngleYaw = player->oMoveAngleYaw + 0x8000; o->oMoveAngleYaw = player->oMoveAngleYaw + 0x8000;
if (check_if_moving_over_floor(50.0f, 150.0f)) { if (check_if_moving_over_floor(50.0f, 150.0f)) {
@ -165,10 +165,10 @@ void ukiki_act_idle(void) {
} }
} }
o->oUkikiTextState = UKIKI_TEXT_HAS_HAT; o->oUkikiTextState = UKIKI_TEXT_HAS_CAP;
} }
if (o->oBehParams2ndByte == UKIKI_HAT) { if (o->oBehParams2ndByte == UKIKI_CAP) {
if (o->oPosY < -1550.0f) { if (o->oPosY < -1550.0f) {
o->oAction = UKIKI_ACT_RETURN_HOME; o->oAction = UKIKI_ACT_RETURN_HOME;
} }
@ -177,7 +177,7 @@ void ukiki_act_idle(void) {
/** /**
* Ukiki attempts to run home, which is often impossible depending on terrain. * Ukiki attempts to run home, which is often impossible depending on terrain.
* Only used for the hat ukiki. * Only used for the cap ukiki.
*/ */
void ukiki_act_return_home(void) { void ukiki_act_return_home(void) {
UNUSED s32 unused; UNUSED s32 unused;
@ -243,7 +243,7 @@ void ukiki_act_turn_to_mario(void) {
o->oAction = UKIKI_ACT_IDLE; o->oAction = UKIKI_ACT_IDLE;
} }
if (is_hat_ukiki_and_mario_has_hat()){ if (is_cap_ukiki_and_mario_has_normal_cap_on_head()){
if (distanceToPlayer > 500.0f) { if (distanceToPlayer > 500.0f) {
o->oAction = UKIKI_ACT_RUN; o->oAction = UKIKI_ACT_RUN;
} }
@ -264,7 +264,7 @@ void ukiki_act_run(void) {
s32 fleeMario = TRUE; s32 fleeMario = TRUE;
s16 goalYaw = angleToPlayer + 0x8000; s16 goalYaw = angleToPlayer + 0x8000;
if (is_hat_ukiki_and_mario_has_hat()) { if (is_cap_ukiki_and_mario_has_normal_cap_on_head()) {
fleeMario = FALSE; fleeMario = FALSE;
goalYaw = angleToPlayer; goalYaw = angleToPlayer;
} }
@ -511,7 +511,7 @@ void ukiki_free_loop(void) {
} }
cur_obj_move_standard(steepSlopeAngleDegrees); cur_obj_move_standard(steepSlopeAngleDegrees);
handle_hat_ukiki_reset(); handle_cap_ukiki_reset();
if(!(o->oMoveFlags & OBJ_MOVE_MASK_IN_WATER)) { if(!(o->oMoveFlags & OBJ_MOVE_MASK_IN_WATER)) {
exec_anim_sound_state(sUkikiSoundStates); exec_anim_sound_state(sUkikiSoundStates);
@ -522,7 +522,7 @@ void ukiki_free_loop(void) {
* Unused function for timing ukiki's blinking. * Unused function for timing ukiki's blinking.
* Image still present in Ukiki's actor graphics. * Image still present in Ukiki's actor graphics.
* *
* Possibly unused so AnimState could be used for wearing a hat? * Possibly unused so AnimState could be used for wearing a cap?
*/ */
static void ukiki_blink_timer(void) { static void ukiki_blink_timer(void) {
if (gGlobalTimer % 50 < 7) { if (gGlobalTimer % 50 < 7) {
@ -584,18 +584,18 @@ void cage_ukiki_held_loop(void) {
} }
} }
u8 hat_ukiki_held_loop_1(void) { return o->oHeldState == HELD_HELD && o->oUkikiTextState == UKIKI_TEXT_STEAL_HAT; } u8 hat_ukiki_held_loop_1(void) { return o->oHeldState == HELD_HELD && o->oUkikiTextState == UKIKI_TEXT_STEAL_CAP; }
u8 hat_ukiki_held_loop_2(void) { return o->oHeldState == HELD_HELD && o->oUkikiTextState == UKIKI_TEXT_HAS_HAT; } u8 hat_ukiki_held_loop_2(void) { return o->oHeldState == HELD_HELD && o->oUkikiTextState == UKIKI_TEXT_HAS_CAP; }
/** /**
* Called by the main behavior function for the hat ukiki whenever it is held. * Called by the main behavior function for the cap ukiki whenever it is held.
*/ */
void hat_ukiki_held_loop(void) { void cap_ukiki_held_loop(void) {
struct MarioState* heldByMario = &gMarioStates[o->heldByPlayerIndex]; struct MarioState* heldByMario = &gMarioStates[o->heldByPlayerIndex];
if (heldByMario->playerIndex != 0) { return; } if (heldByMario->playerIndex != 0) { return; }
// other player must catch ukiki // other player must catch ukiki
if ((o->oUkikiHasHat & UKIKI_HAT_ON) && does_mario_have_hat(heldByMario)) { if ((o->oUkikiHasCap & UKIKI_CAP_ON) && does_mario_have_normal_cap_on_head(heldByMario)) {
o->oInteractionSubtype |= INT_SUBTYPE_DROP_IMMEDIATELY; o->oInteractionSubtype |= INT_SUBTYPE_DROP_IMMEDIATELY;
return; return;
} }
@ -603,35 +603,35 @@ void hat_ukiki_held_loop(void) {
switch(o->oUkikiTextState) { switch(o->oUkikiTextState) {
case UKIKI_TEXT_DEFAULT: case UKIKI_TEXT_DEFAULT:
if (mario_lose_cap_to_enemy(heldByMario, 2)) { if (mario_lose_cap_to_enemy(heldByMario, 2)) {
o->oUkikiTextState = UKIKI_TEXT_STEAL_HAT; o->oUkikiTextState = UKIKI_TEXT_STEAL_CAP;
o->oUkikiHasHat |= UKIKI_HAT_ON; o->oUkikiHasCap |= UKIKI_CAP_ON;
o->globalPlayerIndex = gNetworkPlayers[heldByMario->playerIndex].globalIndex; o->globalPlayerIndex = gNetworkPlayers[heldByMario->playerIndex].globalIndex;
network_send_object(o); network_send_object(o);
} else {} } else {}
break; break;
case UKIKI_TEXT_STEAL_HAT: case UKIKI_TEXT_STEAL_CAP:
if (should_start_or_continue_dialog(heldByMario, o) && cur_obj_update_dialog(heldByMario, 2, 2, DIALOG_100, 0, hat_ukiki_held_loop_1)) { if (should_start_or_continue_dialog(heldByMario, o) && cur_obj_update_dialog(heldByMario, 2, 2, DIALOG_100, 0, hat_ukiki_held_loop_1)) {
o->oInteractionSubtype |= INT_SUBTYPE_DROP_IMMEDIATELY; o->oInteractionSubtype |= INT_SUBTYPE_DROP_IMMEDIATELY;
o->oUkikiTextState = UKIKI_TEXT_STOLE_HAT; o->oUkikiTextState = UKIKI_TEXT_STOLE_CAP;
network_send_object(o); network_send_object(o);
} }
break; break;
case UKIKI_TEXT_STOLE_HAT: case UKIKI_TEXT_STOLE_CAP:
break; break;
case UKIKI_TEXT_HAS_HAT: case UKIKI_TEXT_HAS_CAP:
if (should_start_or_continue_dialog(heldByMario, o) && cur_obj_update_dialog(heldByMario, 2, 18, DIALOG_101, 0, hat_ukiki_held_loop_2)) { if (should_start_or_continue_dialog(heldByMario, o) && cur_obj_update_dialog(heldByMario, 2, 18, DIALOG_101, 0, hat_ukiki_held_loop_2)) {
mario_retrieve_cap(heldByMario); mario_retrieve_cap(heldByMario);
set_mario_npc_dialog(heldByMario, 0, NULL); set_mario_npc_dialog(heldByMario, 0, NULL);
o->oUkikiHasHat &= ~UKIKI_HAT_ON; o->oUkikiHasCap &= ~UKIKI_CAP_ON;
o->oUkikiTextState = UKIKI_TEXT_GAVE_HAT_BACK; o->oUkikiTextState = UKIKI_TEXT_GAVE_CAP_BACK;
network_send_object(o); network_send_object(o);
} }
break; break;
case UKIKI_TEXT_GAVE_HAT_BACK: case UKIKI_TEXT_GAVE_CAP_BACK:
o->oUkikiTextState = UKIKI_TEXT_DEFAULT; o->oUkikiTextState = UKIKI_TEXT_DEFAULT;
o->oAction = UKIKI_ACT_IDLE; o->oAction = UKIKI_ACT_IDLE;
break; break;
@ -639,14 +639,14 @@ void hat_ukiki_held_loop(void) {
} }
/** /**
* Initializatation for ukiki, determines if it has Mario's hat. * Initializatation for ukiki, determines if it has Mario's cap.
*/ */
void bhv_ukiki_init(void) { void bhv_ukiki_init(void) {
// skip hat save flags // skip hat save flags
//if (o->oBehParams2ndByte == UKIKI_HAT) { //if (o->oBehParams2ndByte == UKIKI_CAP) {
// if (save_file_get_flags() & SAVE_FLAG_CAP_ON_UKIKI) { // if (save_file_get_flags() & SAVE_FLAG_CAP_ON_UKIKI) {
// o->oUkikiTextState = UKIKI_TEXT_HAS_HAT; // o->oUkikiTextState = UKIKI_TEXT_HAS_CAP;
// o->oUkikiHasHat |= UKIKI_HAT_ON; // o->oUkikiHasCap |= UKIKI_CAP_ON;
// } // }
//} //}
@ -660,7 +660,7 @@ void bhv_ukiki_init(void) {
/** /**
* The main behavior function for ukiki. Chooses which behavior to use * The main behavior function for ukiki. Chooses which behavior to use
* dependent on the held state and whick ukiki it is (cage or hat). * dependent on the held state and whick ukiki it is (cage or cap).
*/ */
void bhv_ukiki_loop(void) { void bhv_ukiki_loop(void) {
struct Object* heldByPlayer = gMarioStates[o->heldByPlayerIndex].marioObj; struct Object* heldByPlayer = gMarioStates[o->heldByPlayerIndex].marioObj;
@ -676,8 +676,8 @@ void bhv_ukiki_loop(void) {
cur_obj_unrender_and_reset_state(UKIKI_ANIM_HELD, 0); cur_obj_unrender_and_reset_state(UKIKI_ANIM_HELD, 0);
obj_copy_pos(o, heldByPlayer); obj_copy_pos(o, heldByPlayer);
if (o->oBehParams2ndByte == UKIKI_HAT) { if (o->oBehParams2ndByte == UKIKI_CAP) {
hat_ukiki_held_loop(); cap_ukiki_held_loop();
} else { } else {
cage_ukiki_held_loop(); cage_ukiki_held_loop();
} }
@ -689,11 +689,11 @@ void bhv_ukiki_loop(void) {
break; break;
} }
if (o->oUkikiHasHat & UKIKI_HAT_ON) { if (o->oUkikiHasCap & UKIKI_CAP_ON) {
for (int i = 0; i < MAX_PLAYERS; i++) { for (int i = 0; i < MAX_PLAYERS; i++) {
if (!is_player_active(&gMarioStates[i])) { continue; } if (!is_player_active(&gMarioStates[i])) { continue; }
if (!does_mario_have_hat(&gMarioStates[i])) { if (!does_mario_have_normal_cap_on_head(&gMarioStates[i])) {
o->oAnimState = UKIKI_ANIM_STATE_HAT_ON; o->oAnimState = UKIKI_ANIM_STATE_CAP_ON;
break; break;
} }
} }

View file

@ -59,23 +59,23 @@ void water_level_pillar_drained(void) {
} }
static u8 bhv_water_level_pillar_ignore_if_true(void) { static u8 bhv_water_level_pillar_ignore_if_true(void) {
return (o->oWaterLevelPillarUnkF8) || (o->oAction != 0); return (o->oWaterLevelPillarDrained) || (o->oAction != 0);
} }
void bhv_water_level_pillar_init(void) { void bhv_water_level_pillar_init(void) {
if (save_file_get_flags() & SAVE_FLAG_MOAT_DRAINED) if (save_file_get_flags() & SAVE_FLAG_MOAT_DRAINED)
o->oWaterLevelPillarUnkF8 = 1; o->oWaterLevelPillarDrained = 1;
struct SyncObject* so = network_init_object(o, SYNC_DISTANCE_ONLY_EVENTS); struct SyncObject* so = network_init_object(o, SYNC_DISTANCE_ONLY_EVENTS);
so->ignore_if_true = bhv_water_level_pillar_ignore_if_true; so->ignore_if_true = bhv_water_level_pillar_ignore_if_true;
network_init_object_field(o, &o->oAction); network_init_object_field(o, &o->oAction);
network_init_object_field(o, &o->oPrevAction); network_init_object_field(o, &o->oPrevAction);
network_init_object_field(o, &o->oTimer); network_init_object_field(o, &o->oTimer);
network_init_object_field(o, &o->oWaterLevelPillarUnkF8); network_init_object_field(o, &o->oWaterLevelPillarDrained);
} }
void bhv_water_level_pillar_loop(void) { void bhv_water_level_pillar_loop(void) {
if (o->oWaterLevelPillarUnkF8) if (o->oWaterLevelPillarDrained)
water_level_pillar_drained(); water_level_pillar_drained();
else else
water_level_pillar_undrained(); water_level_pillar_undrained();

View file

@ -1,7 +1,7 @@
// whomp.c.inc // whomp.c.inc
void whomp_play_sfx_from_pound_animation(void) { void whomp_play_sfx_from_pound_animation(void) {
UNUSED s32 sp2C = o->header.gfx.unk38.animFrame; UNUSED s32 sp2C = o->header.gfx.animInfo.animFrame;
s32 sp28 = 0; s32 sp28 = 0;
if (o->oForwardVel < 5.0f) { if (o->oForwardVel < 5.0f) {
sp28 = cur_obj_check_anim_frame(0); sp28 = cur_obj_check_anim_frame(0);

View file

@ -138,7 +138,7 @@ void wiggler_init_segments(void) {
(segments + i)->yaw = o->oFaceAngleYaw; (segments + i)->yaw = o->oFaceAngleYaw;
} }
o->header.gfx.unk38.animFrame = -1; o->header.gfx.animInfo.animFrame = -1;
// Spawn each body part // Spawn each body part
for (i = 1; i <= 3; i++) { for (i = 1; i <= 3; i++) {
@ -146,7 +146,7 @@ void wiggler_init_segments(void) {
spawn_object_relative(i, 0, 0, 0, o, MODEL_WIGGLER_BODY, bhvWigglerBody); spawn_object_relative(i, 0, 0, 0, o, MODEL_WIGGLER_BODY, bhvWigglerBody);
if (bodyPart != NULL) { if (bodyPart != NULL) {
obj_init_animation_with_sound(bodyPart, wiggler_seg5_anims_0500C874, 0); obj_init_animation_with_sound(bodyPart, wiggler_seg5_anims_0500C874, 0);
bodyPart->header.gfx.unk38.animFrame = (23 * i) % 26 - 1; bodyPart->header.gfx.animInfo.animFrame = (23 * i) % 26 - 1;
} }
} }

View file

@ -17,7 +17,8 @@ void bhv_yoshi_init(void) {
o->oBuoyancy = 1.3f; o->oBuoyancy = 1.3f;
o->oInteractionSubtype = INT_SUBTYPE_NPC; o->oInteractionSubtype = INT_SUBTYPE_NPC;
if (save_file_get_total_star_count(gCurrSaveFileNum - 1, 0, 24) < 120 || sYoshiDead == TRUE) { if (save_file_get_total_star_count(gCurrSaveFileNum - 1, COURSE_MIN - 1, COURSE_MAX - 1) < 120
|| sYoshiDead == TRUE) {
o->activeFlags = ACTIVE_FLAG_DEACTIVATED; o->activeFlags = ACTIVE_FLAG_DEACTIVATED;
} }
@ -32,7 +33,7 @@ void bhv_yoshi_init(void) {
void yoshi_walk_loop(void) { void yoshi_walk_loop(void) {
UNUSED s16 sp26; UNUSED s16 sp26;
s16 sp24 = o->header.gfx.unk38.animFrame; s16 sp24 = o->header.gfx.animInfo.animFrame;
o->oForwardVel = 10.0f; o->oForwardVel = 10.0f;
sp26 = object_step(); sp26 = object_step();
@ -56,7 +57,7 @@ void yoshi_walk_loop(void) {
void yoshi_idle_loop(void) { void yoshi_idle_loop(void) {
s16 chosenHome; s16 chosenHome;
UNUSED s16 sp1C = o->header.gfx.unk38.animFrame; UNUSED s16 sp1C = o->header.gfx.animInfo.animFrame;
if (o->oTimer > 90) { if (o->oTimer > 90) {
chosenHome = random_float() * 3.99; chosenHome = random_float() * 3.99;
@ -109,7 +110,7 @@ void yoshi_talk_loop(void) {
} }
void yoshi_walk_and_jump_off_roof_loop(void) { void yoshi_walk_and_jump_off_roof_loop(void) {
s16 sp26 = o->header.gfx.unk38.animFrame; s16 sp26 = o->header.gfx.animInfo.animFrame;
o->oForwardVel = 10.0f; o->oForwardVel = 10.0f;
object_step(); object_step();
@ -139,7 +140,7 @@ void yoshi_finish_jumping_and_despawn_loop(void) {
if (o->oPosY < 2100.0f) { if (o->oPosY < 2100.0f) {
set_mario_npc_dialog(&gMarioStates[0], 0, yoshi_talk_loop_continue_dialog); set_mario_npc_dialog(&gMarioStates[0], 0, yoshi_talk_loop_continue_dialog);
gObjCutsceneDone = TRUE; gObjCutsceneDone = TRUE;
sYoshiDead = 1; sYoshiDead = TRUE;
o->activeFlags = ACTIVE_FLAG_DEACTIVATED; o->activeFlags = ACTIVE_FLAG_DEACTIVATED;
} }
} }
@ -149,7 +150,7 @@ void yoshi_give_present_loop(void) {
if (gHudDisplay.lives == 100) { if (gHudDisplay.lives == 100) {
play_sound(SOUND_GENERAL_COLLECT_1UP, gDefaultSoundArgs); play_sound(SOUND_GENERAL_COLLECT_1UP, gDefaultSoundArgs);
gSpecialTripleJump = 1; gSpecialTripleJump = TRUE;
o->oAction = YOSHI_ACT_WALK_JUMP_OFF_ROOF; o->oAction = YOSHI_ACT_WALK_JUMP_OFF_ROOF;
return; return;
} }

View file

@ -666,9 +666,9 @@ void unused_set_camera_pitch_shake_env(s16 shake) {
* both ranges are always 200.f * both ranges are always 200.f
* Since focMul is 0.9, `focOff` is closer to the floor than `posOff` * Since focMul is 0.9, `focOff` is closer to the floor than `posOff`
* posOff and focOff are sometimes the same address, which just ignores the pos calculation * posOff and focOff are sometimes the same address, which just ignores the pos calculation
*! Doesn't return anything, but required to match EU *! Doesn't return anything, but required to match on -O2
*/ */
f32 calc_y_to_curr_floor(f32 *posOff, f32 posMul, f32 posBound, f32 *focOff, f32 focMul, f32 focBound) { BAD_RETURN(f32) calc_y_to_curr_floor(f32 *posOff, f32 posMul, f32 posBound, f32 *focOff, f32 focMul, f32 focBound) {
f32 floorHeight = sMarioGeometry.currFloorHeight; f32 floorHeight = sMarioGeometry.currFloorHeight;
f32 waterHeight; f32 waterHeight;
UNUSED s32 filler; UNUSED s32 filler;
@ -797,10 +797,10 @@ void set_camera_height(struct Camera *c, f32 goalHeight) {
} }
} }
approach_camera_height(c, goalHeight, 20.f); approach_camera_height(c, goalHeight, 20.f);
if (camCeilHeight != 20000.f) { if (camCeilHeight != CELL_HEIGHT_LIMIT) {
camCeilHeight -= baseOff; camCeilHeight -= baseOff;
if ((c->pos[1] > camCeilHeight && sMarioGeometry.currFloorHeight + baseOff < camCeilHeight) if ((c->pos[1] > camCeilHeight && sMarioGeometry.currFloorHeight + baseOff < camCeilHeight)
|| (sMarioGeometry.currCeilHeight != 20000.f || (sMarioGeometry.currCeilHeight != CELL_HEIGHT_LIMIT
&& sMarioGeometry.currCeilHeight > camCeilHeight && c->pos[1] > camCeilHeight)) { && sMarioGeometry.currCeilHeight > camCeilHeight && c->pos[1] > camCeilHeight)) {
c->pos[1] = camCeilHeight; c->pos[1] = camCeilHeight;
} }
@ -1495,7 +1495,7 @@ s32 update_fixed_camera(struct Camera *c, Vec3f focus, UNUSED Vec3f pos) {
vec3f_add(basePos, sCastleEntranceOffset); vec3f_add(basePos, sCastleEntranceOffset);
if (sMarioGeometry.currFloorType != SURFACE_DEATH_PLANE if (sMarioGeometry.currFloorType != SURFACE_DEATH_PLANE
&& sMarioGeometry.currFloorHeight != -11000.f) { && sMarioGeometry.currFloorHeight != FLOOR_LOWER_LIMIT) {
goalHeight = sMarioGeometry.currFloorHeight + basePos[1] + heightOffset; goalHeight = sMarioGeometry.currFloorHeight + basePos[1] + heightOffset;
} else { } else {
goalHeight = gLakituState.goalPos[1]; goalHeight = gLakituState.goalPos[1];
@ -1506,7 +1506,7 @@ s32 update_fixed_camera(struct Camera *c, Vec3f focus, UNUSED Vec3f pos) {
} }
ceilHeight = find_ceil(c->pos[0], goalHeight - 100.f, c->pos[2], &ceiling); ceilHeight = find_ceil(c->pos[0], goalHeight - 100.f, c->pos[2], &ceiling);
if (ceilHeight != 20000.f) { if (ceilHeight != CELL_HEIGHT_LIMIT) {
if (goalHeight > (ceilHeight -= 125.f)) { if (goalHeight > (ceilHeight -= 125.f)) {
goalHeight = ceilHeight; goalHeight = ceilHeight;
} }
@ -1605,7 +1605,7 @@ s32 update_boss_fight_camera(struct Camera *c, Vec3f focus, Vec3f pos) {
// When C-Down is not active, this // When C-Down is not active, this
vec3f_set_dist_and_angle(focus, pos, focusDistance, 0x1000, yaw); vec3f_set_dist_and_angle(focus, pos, focusDistance, 0x1000, yaw);
// Find the floor of the arena // Find the floor of the arena
pos[1] = find_floor(c->areaCenX, 20000.f, c->areaCenZ, &floor); pos[1] = find_floor(c->areaCenX, CELL_HEIGHT_LIMIT, c->areaCenZ, &floor);
if (floor != NULL) { if (floor != NULL) {
nx = floor->normal.x; nx = floor->normal.x;
ny = floor->normal.y; ny = floor->normal.y;
@ -1621,7 +1621,7 @@ s32 update_boss_fight_camera(struct Camera *c, Vec3f focus, Vec3f pos) {
} }
} }
//! Must be same line to match EU //! Must be same line to match on -O2
// Prevent the camera from going to the ground in the outside boss fight // Prevent the camera from going to the ground in the outside boss fight
if (gCurrLevelNum == LEVEL_BBH) { pos[1] = 2047.f; } if (gCurrLevelNum == LEVEL_BBH) { pos[1] = 2047.f; }
@ -2279,7 +2279,7 @@ s16 update_default_camera(struct Camera *c) {
// If there's water below the camera, decide whether to keep the camera above the water surface // If there's water below the camera, decide whether to keep the camera above the water surface
waterHeight = find_water_level(cPos[0], cPos[2]); waterHeight = find_water_level(cPos[0], cPos[2]);
if (waterHeight != -11000.f) { if (waterHeight != FLOOR_LOWER_LIMIT) {
waterHeight += 125.f; waterHeight += 125.f;
distFromWater = waterHeight - marioFloorHeight; distFromWater = waterHeight - marioFloorHeight;
if (!(gCameraMovementFlags & CAM_MOVE_METAL_BELOW_WATER)) { if (!(gCameraMovementFlags & CAM_MOVE_METAL_BELOW_WATER)) {
@ -2329,7 +2329,7 @@ s16 update_default_camera(struct Camera *c) {
// Make Lakitu fly above the gas // Make Lakitu fly above the gas
gasHeight = find_poison_gas_level(cPos[0], cPos[2]); gasHeight = find_poison_gas_level(cPos[0], cPos[2]);
if (gasHeight != -11000.f) { if (gasHeight != FLOOR_LOWER_LIMIT) {
if ((gasHeight += 130.f) > c->pos[1]) { if ((gasHeight += 130.f) > c->pos[1]) {
c->pos[1] = gasHeight; c->pos[1] = gasHeight;
} }
@ -2340,7 +2340,7 @@ s16 update_default_camera(struct Camera *c) {
if (c->mode == CAMERA_MODE_FREE_ROAM) { if (c->mode == CAMERA_MODE_FREE_ROAM) {
camFloorHeight -= 100.f; camFloorHeight -= 100.f;
} }
ceilHeight = 20000.f; ceilHeight = CELL_HEIGHT_LIMIT;
vec3f_copy(c->focus, sMarioCamState->pos); vec3f_copy(c->focus, sMarioCamState->pos);
} }
@ -2349,10 +2349,10 @@ s16 update_default_camera(struct Camera *c) {
if (sMarioCamState->pos[1] - 100.f > camFloorHeight) { if (sMarioCamState->pos[1] - 100.f > camFloorHeight) {
camFloorHeight = sMarioCamState->pos[1] - 100.f; camFloorHeight = sMarioCamState->pos[1] - 100.f;
} }
ceilHeight = 20000.f; ceilHeight = CELL_HEIGHT_LIMIT;
vec3f_copy(c->focus, sMarioCamState->pos); vec3f_copy(c->focus, sMarioCamState->pos);
} }
if (camFloorHeight != -11000.f) { if (camFloorHeight != FLOOR_LOWER_LIMIT) {
camFloorHeight += posHeight; camFloorHeight += posHeight;
approach_camera_height(c, camFloorHeight, 20.f); approach_camera_height(c, camFloorHeight, 20.f);
} }
@ -2374,7 +2374,7 @@ s16 update_default_camera(struct Camera *c) {
vec3f_set_dist_and_angle(c->focus, c->pos, dist, tempPitch, tempYaw); vec3f_set_dist_and_angle(c->focus, c->pos, dist, tempPitch, tempYaw);
} }
} }
if (ceilHeight != 20000.f) { if (ceilHeight != CELL_HEIGHT_LIMIT) {
if (c->pos[1] > (ceilHeight -= 150.f) if (c->pos[1] > (ceilHeight -= 150.f)
&& (avoidStatus = is_range_behind_surface(c->pos, sMarioCamState->pos, ceil, 0, -1)) == 1) { && (avoidStatus = is_range_behind_surface(c->pos, sMarioCamState->pos, ceil, 0, -1)) == 1) {
c->pos[1] = ceilHeight; c->pos[1] = ceilHeight;
@ -2472,7 +2472,7 @@ s32 update_spiral_stairs_camera(struct Camera *c, Vec3f focus, Vec3f pos) {
checkPos[2] = focus[2] + (cPos[2] - focus[2]) * 0.7f; checkPos[2] = focus[2] + (cPos[2] - focus[2]) * 0.7f;
floorHeight = find_floor(checkPos[0], checkPos[1] + 50.f, checkPos[2], &floor); floorHeight = find_floor(checkPos[0], checkPos[1] + 50.f, checkPos[2], &floor);
if (floorHeight != -11000.f) { if (floorHeight != FLOOR_LOWER_LIMIT) {
if (floorHeight < sMarioGeometry.currFloorHeight) { if (floorHeight < sMarioGeometry.currFloorHeight) {
floorHeight = sMarioGeometry.currFloorHeight; floorHeight = sMarioGeometry.currFloorHeight;
} }
@ -3013,7 +3013,7 @@ void update_lakitu(struct Camera *c) {
distToFloor = find_floor(gLakituState.pos[0], distToFloor = find_floor(gLakituState.pos[0],
gLakituState.pos[1] + 20.0f, gLakituState.pos[1] + 20.0f,
gLakituState.pos[2], &floor); gLakituState.pos[2], &floor);
if (distToFloor != -11000.f) { if (distToFloor != FLOOR_LOWER_LIMIT) {
if (gLakituState.pos[1] < (distToFloor += 100.0f)) { if (gLakituState.pos[1] < (distToFloor += 100.0f)) {
gLakituState.pos[1] = distToFloor; gLakituState.pos[1] = distToFloor;
} else { } else {
@ -4347,7 +4347,7 @@ s16 reduce_by_dist_from_camera(s16 value, f32 maxDist, f32 posX, f32 posY, f32 p
vec3f_get_dist_and_angle(gLakituState.goalPos, pos, &dist, &pitch, &yaw); vec3f_get_dist_and_angle(gLakituState.goalPos, pos, &dist, &pitch, &yaw);
if (dist < maxDist) { if (dist < maxDist) {
calculate_angles(gLakituState.goalPos, gLakituState.goalFocus, &goalPitch, &goalYaw); calculate_angles(gLakituState.goalPos, gLakituState.goalFocus, &goalPitch, &goalYaw);
//! Must be same line to match EU //! Must be same line to match on -O2
pitch -= goalPitch; yaw -= goalYaw; pitch -= goalPitch; yaw -= goalYaw;
dist -= 2000.f; dist -= 2000.f;
if (dist < 0.f) { if (dist < 0.f) {
@ -5527,7 +5527,7 @@ s16 next_lakitu_state(Vec3f newPos, Vec3f newFoc, Vec3f curPos, Vec3f curFoc,
if (gCamera->cutscene != 0 || !(gCameraMovementFlags & CAM_MOVE_C_UP_MODE)) { if (gCamera->cutscene != 0 || !(gCameraMovementFlags & CAM_MOVE_C_UP_MODE)) {
floorHeight = find_floor(newPos[0], newPos[1], newPos[2], &floor); floorHeight = find_floor(newPos[0], newPos[1], newPos[2], &floor);
if (floorHeight != -11000.f) { if (floorHeight != FLOOR_LOWER_LIMIT) {
if ((floorHeight += 125.f) > newPos[1]) { if ((floorHeight += 125.f) > newPos[1]) {
newPos[1] = floorHeight; newPos[1] = floorHeight;
} }
@ -6773,19 +6773,19 @@ void resolve_geometry_collisions(Vec3f pos, UNUSED Vec3f lastGood) {
floorY = find_floor(pos[0], pos[1] + 50.f, pos[2], &surf); floorY = find_floor(pos[0], pos[1] + 50.f, pos[2], &surf);
ceilY = find_ceil(pos[0], pos[1] - 50.f, pos[2], &surf); ceilY = find_ceil(pos[0], pos[1] - 50.f, pos[2], &surf);
if ((-11000.f != floorY) && (20000.f == ceilY)) { if ((FLOOR_LOWER_LIMIT != floorY) && (CELL_HEIGHT_LIMIT == ceilY)) {
if (pos[1] < (floorY += 125.f)) { if (pos[1] < (floorY += 125.f)) {
pos[1] = floorY; pos[1] = floorY;
} }
} }
if ((-11000.f == floorY) && (20000.f != ceilY)) { if ((FLOOR_LOWER_LIMIT == floorY) && (CELL_HEIGHT_LIMIT != ceilY)) {
if (pos[1] > (ceilY -= 125.f)) { if (pos[1] > (ceilY -= 125.f)) {
pos[1] = ceilY; pos[1] = ceilY;
} }
} }
if ((-11000.f != floorY) && (20000.f != ceilY)) { if ((FLOOR_LOWER_LIMIT != floorY) && (CELL_HEIGHT_LIMIT != ceilY)) {
floorY += 125.f; floorY += 125.f;
ceilY -= 125.f; ceilY -= 125.f;
@ -6912,14 +6912,14 @@ void find_mario_floor_and_ceil(struct PlayerGeometry *pg) {
gCheckingSurfaceCollisionsForCamera = TRUE; gCheckingSurfaceCollisionsForCamera = TRUE;
if (find_floor(sMarioCamState->pos[0], sMarioCamState->pos[1] + 10.f, if (find_floor(sMarioCamState->pos[0], sMarioCamState->pos[1] + 10.f,
sMarioCamState->pos[2], &surf) != -11000.f) { sMarioCamState->pos[2], &surf) != FLOOR_LOWER_LIMIT) {
pg->currFloorType = surf->type; pg->currFloorType = surf->type;
} else { } else {
pg->currFloorType = 0; pg->currFloorType = 0;
} }
if (find_ceil(sMarioCamState->pos[0], sMarioCamState->pos[1] - 10.f, if (find_ceil(sMarioCamState->pos[0], sMarioCamState->pos[1] - 10.f,
sMarioCamState->pos[2], &surf) != 20000.f) { sMarioCamState->pos[2], &surf) != CELL_HEIGHT_LIMIT) {
pg->currCeilType = surf->type; pg->currCeilType = surf->type;
} else { } else {
pg->currCeilType = 0; pg->currCeilType = 0;
@ -7453,7 +7453,7 @@ BAD_RETURN(s32) cutscene_ending_peach_descends(struct Camera *c) {
} }
/** /**
* Mario runs across the bridge to peach, and takes off his hat. * Mario runs across the bridge to peach, and takes off his cap.
* Follow the sEndingMarioToPeach* splines while Mario runs across. * Follow the sEndingMarioToPeach* splines while Mario runs across.
*/ */
BAD_RETURN(s32) cutscene_ending_mario_to_peach(struct Camera *c) { BAD_RETURN(s32) cutscene_ending_mario_to_peach(struct Camera *c) {
@ -8791,7 +8791,7 @@ BAD_RETURN(s32) cutscene_suffocation_stay_above_gas(struct Camera *c) {
cutscene_goto_cvar_pos(c, 400.f, 0x2800, 0x200, 0); cutscene_goto_cvar_pos(c, 400.f, 0x2800, 0x200, 0);
gasLevel = find_poison_gas_level(sMarioCamState->pos[0], sMarioCamState->pos[2]); gasLevel = find_poison_gas_level(sMarioCamState->pos[0], sMarioCamState->pos[2]);
if (gasLevel != -11000.f) { if (gasLevel != FLOOR_LOWER_LIMIT) {
if ((gasLevel += 130.f) > c->pos[1]) { if ((gasLevel += 130.f) > c->pos[1]) {
c->pos[1] = gasLevel; c->pos[1] = gasLevel;
} }
@ -10178,7 +10178,7 @@ BAD_RETURN(s32) cutscene_exit_painting_start(struct Camera *c) {
offset_rotated(c->pos, sCutsceneVars[0].point, sCutsceneVars[2].point, sCutsceneVars[0].angle); offset_rotated(c->pos, sCutsceneVars[0].point, sCutsceneVars[2].point, sCutsceneVars[0].angle);
floorHeight = find_floor(c->pos[0], c->pos[1] + 10.f, c->pos[2], &floor); floorHeight = find_floor(c->pos[0], c->pos[1] + 10.f, c->pos[2], &floor);
if (floorHeight != -11000.f) { if (floorHeight != FLOOR_LOWER_LIMIT) {
if (c->pos[1] < (floorHeight += 60.f)) { if (c->pos[1] < (floorHeight += 60.f)) {
c->pos[1] = floorHeight; c->pos[1] = floorHeight;
} }

View file

@ -480,7 +480,7 @@ f32 get_character_anim_offset(struct MarioState* m) {
struct Object* marioObj = m->marioObj; struct Object* marioObj = m->marioObj;
struct Character* c = get_character(m); struct Character* c = get_character(m);
if (!c->animOffsetEnabled) { return 0; } if (!c->animOffsetEnabled) { return 0; }
s32 animID = marioObj->header.gfx.unk38.animID; s32 animID = marioObj->header.gfx.animInfo.animID;
if (animID < 0 || animID >= ANIM_TYPE_MAX) { return 0; } if (animID < 0 || animID >= ANIM_TYPE_MAX) { return 0; }
switch (sAnimTypes[animID]) { switch (sAnimTypes[animID]) {
@ -515,7 +515,7 @@ void update_character_anim_offset(struct MarioState* m) {
if (m->curAnimOffset > 40) { m->curAnimOffset = 40; } if (m->curAnimOffset > 40) { m->curAnimOffset = 40; }
if (m->curAnimOffset < -40) { m->curAnimOffset = -40; } if (m->curAnimOffset < -40) { m->curAnimOffset = -40; }
//s32 animID = marioObj->header.gfx.unk38.animID; //s32 animID = marioObj->header.gfx.animInfo.animID;
//LOG_INFO(">>> [%d] : %d :: %f, %f", animID, sAnimTypes[animID], m->curAnimOffset, m->minimumBoneY); //LOG_INFO(">>> [%d] : %d :: %f, %f", animID, sAnimTypes[animID], m->curAnimOffset, m->minimumBoneY);
marioObj->header.gfx.pos[1] = m->pos[1] + m->curAnimOffset; marioObj->header.gfx.pos[1] = m->pos[1] + m->curAnimOffset;

View file

@ -256,7 +256,7 @@ void print_stageinfo(void) {
void print_string_array_info(const char **strArr) { void print_string_array_info(const char **strArr) {
s32 i; s32 i;
if (sDebugStringArrPrinted == FALSE) { if (!sDebugStringArrPrinted) {
sDebugStringArrPrinted += 1; // again, why not = TRUE... sDebugStringArrPrinted += 1; // again, why not = TRUE...
for (i = 0; i < 8; i++) { for (i = 0; i < 8; i++) {
// sDebugPage is assumed to be 4 or 5 here. // sDebugPage is assumed to be 4 or 5 here.
@ -401,7 +401,7 @@ void try_modify_debug_controls(void) {
if (gPlayer1Controller->buttonPressed & Z_TRIG) { if (gPlayer1Controller->buttonPressed & Z_TRIG) {
sNoExtraDebug ^= 1; sNoExtraDebug ^= 1;
} }
if (!(gPlayer1Controller->buttonDown & (L_TRIG | R_TRIG)) && sNoExtraDebug == FALSE) { if (!(gPlayer1Controller->buttonDown & (L_TRIG | R_TRIG)) && !sNoExtraDebug) {
sp4 = 1; sp4 = 1;
if (gPlayer1Controller->buttonDown & B_BUTTON) { if (gPlayer1Controller->buttonDown & B_BUTTON) {
sp4 = 100; sp4 = 100;

View file

@ -56,7 +56,7 @@ struct MarioAnimation D_80339D10[MAX_PLAYERS];
struct MarioAnimation gDemo; struct MarioAnimation gDemo;
UNUSED u8 filler80339D30[0x90]; UNUSED u8 filler80339D30[0x90];
int unused8032C690 = 0; s32 unused8032C690 = 0;
u32 gGlobalTimer = 0; u32 gGlobalTimer = 0;
static u16 sCurrFBNum = 0; static u16 sCurrFBNum = 0;

View file

@ -82,7 +82,7 @@ Gfx *geo_exec_inside_castle_light(s32 callContext, struct GraphNode *node, UNUSE
if (callContext == GEO_CONTEXT_RENDER) { if (callContext == GEO_CONTEXT_RENDER) {
flags = save_file_get_flags(); flags = save_file_get_flags();
if (gHudDisplay.stars >= 10 && (flags & SAVE_FLAG_HAVE_WING_CAP) == 0) { if (gHudDisplay.stars >= 10 && !(flags & SAVE_FLAG_HAVE_WING_CAP)) {
displayList = alloc_display_list(2 * sizeof(*displayList)); displayList = alloc_display_list(2 * sizeof(*displayList));
if (displayList == NULL) { if (displayList == NULL) {

View file

@ -25,7 +25,6 @@ enum CameraHUDLut {
GLYPH_CAM_WARIO_HEAD, GLYPH_CAM_WARIO_HEAD,
}; };
// Functions
void set_hud_camera_status(s16 status); void set_hud_camera_status(s16 status);
void render_hud(void); void render_hud(void);

View file

@ -1045,7 +1045,7 @@ void create_dialog_box_with_response(s16 dialog) {
} }
void reset_dialog_render_state(void) { void reset_dialog_render_state(void) {
level_set_transition(0, 0); level_set_transition(0, NULL);
if (gDialogBoxType == DIALOG_TYPE_ZOOM) { if (gDialogBoxType == DIALOG_TYPE_ZOOM) {
trigger_cutscene_dialog(2); trigger_cutscene_dialog(2);
@ -1908,7 +1908,7 @@ void render_dialog_entries(void) {
break; break;
case DIALOG_STATE_CLOSING: case DIALOG_STATE_CLOSING:
if (gDialogBoxOpenTimer == 20.0f) { if (gDialogBoxOpenTimer == 20.0f) {
level_set_transition(0, 0); level_set_transition(0, NULL);
play_sound(SOUND_MENU_MESSAGE_DISAPPEAR, gDefaultSoundArgs); play_sound(SOUND_MENU_MESSAGE_DISAPPEAR, gDefaultSoundArgs);
if (gDialogBoxType == DIALOG_TYPE_ZOOM) { if (gDialogBoxType == DIALOG_TYPE_ZOOM) {
@ -2742,7 +2742,7 @@ s16 render_pause_courses_and_castle(void) {
case DIALOG_STATE_OPENING: case DIALOG_STATE_OPENING:
gDialogLineNum = 1; gDialogLineNum = 1;
gDialogTextAlpha = 0; gDialogTextAlpha = 0;
//level_set_transition(-1, 0); //level_set_transition(-1, NULL);
#if defined(VERSION_JP) || defined(VERSION_SH) #if defined(VERSION_JP) || defined(VERSION_SH)
play_sound(SOUND_MENU_PAUSE, gDefaultSoundArgs); play_sound(SOUND_MENU_PAUSE, gDefaultSoundArgs);
#else #else
@ -2774,7 +2774,7 @@ s16 render_pause_courses_and_castle(void) {
|| gPlayer1Controller->buttonPressed & START_BUTTON) || gPlayer1Controller->buttonPressed & START_BUTTON)
#endif #endif
{ {
level_set_transition(0, 0); level_set_transition(0, NULL);
play_sound(SOUND_MENU_PAUSE_2, gDefaultSoundArgs); play_sound(SOUND_MENU_PAUSE_2, gDefaultSoundArgs);
gDialogBoxState = DIALOG_STATE_OPENING; gDialogBoxState = DIALOG_STATE_OPENING;
gMenuMode = -1; gMenuMode = -1;
@ -2801,7 +2801,7 @@ s16 render_pause_courses_and_castle(void) {
|| gPlayer1Controller->buttonPressed & START_BUTTON) || gPlayer1Controller->buttonPressed & START_BUTTON)
#endif #endif
{ {
level_set_transition(0, 0); level_set_transition(0, NULL);
play_sound(SOUND_MENU_PAUSE_2, gDefaultSoundArgs); play_sound(SOUND_MENU_PAUSE_2, gDefaultSoundArgs);
gMenuMode = -1; gMenuMode = -1;
gDialogBoxState = DIALOG_STATE_OPENING; gDialogBoxState = DIALOG_STATE_OPENING;
@ -2896,7 +2896,7 @@ void print_hud_course_complete_coins(s16 x, s16 y) {
gCourseCompleteCoinsEqual = 1; gCourseCompleteCoinsEqual = 1;
gCourseCompleteCoins = gHudDisplay.coins; gCourseCompleteCoins = gHudDisplay.coins;
if (gGotFileCoinHiScore != 0) { if (gGotFileCoinHiScore) {
print_hud_course_complete_string(HUD_PRINT_HISCORE); print_hud_course_complete_string(HUD_PRINT_HISCORE);
} }
} else { } else {
@ -2910,7 +2910,7 @@ void print_hud_course_complete_coins(s16 x, s16 y) {
} }
} }
if (gHudDisplay.coins == gCourseCompleteCoins && gGotFileCoinHiScore != 0) { if (gHudDisplay.coins == gCourseCompleteCoins && gGotFileCoinHiScore) {
play_sound(SOUND_MENU_MARIO_CASTLE_WARP2, gDefaultSoundArgs); play_sound(SOUND_MENU_MARIO_CASTLE_WARP2, gDefaultSoundArgs);
} }
} }
@ -3144,7 +3144,7 @@ s16 render_course_complete_screen(void) {
render_course_complete_lvl_info_and_hud_str(); render_course_complete_lvl_info_and_hud_str();
if (gCourseDoneMenuTimer > 100 && gCourseCompleteCoinsEqual == 1) { if (gCourseDoneMenuTimer > 100 && gCourseCompleteCoinsEqual == 1) {
gDialogBoxState = DIALOG_STATE_VERTICAL; gDialogBoxState = DIALOG_STATE_VERTICAL;
//level_set_transition(-1, 0); //level_set_transition(-1, NULL);
gDialogTextAlpha = 0; gDialogTextAlpha = 0;
gDialogLineNum = 1; gDialogLineNum = 1;
} }
@ -3164,7 +3164,7 @@ s16 render_course_complete_screen(void) {
|| gPlayer1Controller->buttonPressed & Z_TRIG || gPlayer1Controller->buttonPressed & Z_TRIG
#endif #endif
)) { )) {
level_set_transition(0, 0); level_set_transition(0, NULL);
play_sound(SOUND_MENU_STAR_SOUND, gDefaultSoundArgs); play_sound(SOUND_MENU_STAR_SOUND, gDefaultSoundArgs);
gDialogBoxState = DIALOG_STATE_OPENING; gDialogBoxState = DIALOG_STATE_OPENING;
gMenuMode = -1; gMenuMode = -1;

View file

@ -144,10 +144,10 @@ static u8 sJustTeleported = FALSE;
u8 gPssSlideStarted = FALSE; u8 gPssSlideStarted = FALSE;
/** /**
* Returns the type of hat Mario is wearing. * Returns the type of cap Mario is wearing.
*/ */
u32 get_mario_cap_flag(struct Object *capObject) { u32 get_mario_cap_flag(struct Object *capObject) {
void *script = virtual_to_segmented(0x13, capObject->behavior); const BehaviorScript *script = virtual_to_segmented(0x13, capObject->behavior);
if (script == bhvNormalCap) { if (script == bhvNormalCap) {
return MARIO_NORMAL_CAP; return MARIO_NORMAL_CAP;
@ -161,6 +161,7 @@ u32 get_mario_cap_flag(struct Object *capObject) {
return 0; return 0;
} }
/** /**
* Returns true if the passed in object has a moving angle yaw * Returns true if the passed in object has a moving angle yaw
* in the angular range given towards Mario. * in the angular range given towards Mario.
@ -381,15 +382,15 @@ void mario_stop_riding_and_holding(struct MarioState *m) {
} }
} }
u32 does_mario_have_hat(struct MarioState *m) { u32 does_mario_have_normal_cap_on_head(struct MarioState *m) {
return (m->flags & MARIO_CAP_FLAGS) == (MARIO_NORMAL_CAP | MARIO_CAP_ON_HEAD); return (m->flags & (MARIO_CAPS | MARIO_CAP_ON_HEAD)) == (MARIO_NORMAL_CAP | MARIO_CAP_ON_HEAD);
} }
void mario_blow_off_cap(struct MarioState *m, f32 capSpeed) { void mario_blow_off_cap(struct MarioState *m, f32 capSpeed) {
if (m->playerIndex != 0) { return; } if (m->playerIndex != 0) { return; }
struct Object *capObject; struct Object *capObject;
if (does_mario_have_hat(m)) { if (does_mario_have_normal_cap_on_head(m)) {
save_file_set_cap_pos(m->pos[0], m->pos[1], m->pos[2]); save_file_set_cap_pos(m->pos[0], m->pos[1], m->pos[2]);
m->flags &= ~(MARIO_NORMAL_CAP | MARIO_CAP_ON_HEAD); m->flags &= ~(MARIO_NORMAL_CAP | MARIO_CAP_ON_HEAD);
@ -420,7 +421,7 @@ u32 mario_lose_cap_to_enemy(struct MarioState* m, u32 arg) {
if (m->playerIndex != 0) { return FALSE; } if (m->playerIndex != 0) { return FALSE; }
u32 wasWearingCap = FALSE; u32 wasWearingCap = FALSE;
if (does_mario_have_hat(m)) { if (does_mario_have_normal_cap_on_head(m)) {
save_file_set_flags(arg == 1 ? SAVE_FLAG_CAP_ON_KLEPTO : SAVE_FLAG_CAP_ON_UKIKI); save_file_set_flags(arg == 1 ? SAVE_FLAG_CAP_ON_KLEPTO : SAVE_FLAG_CAP_ON_UKIKI);
m->flags &= ~(MARIO_NORMAL_CAP | MARIO_CAP_ON_HEAD); m->flags &= ~(MARIO_NORMAL_CAP | MARIO_CAP_ON_HEAD);
wasWearingCap = TRUE; wasWearingCap = TRUE;
@ -469,7 +470,7 @@ struct Object *mario_get_collided_object(struct MarioState *m, u32 interactType)
u32 mario_check_object_grab(struct MarioState *m) { u32 mario_check_object_grab(struct MarioState *m) {
u32 result = FALSE; u32 result = FALSE;
void *script; const BehaviorScript *script;
if (m->playerIndex != 0) { return FALSE; } if (m->playerIndex != 0) { return FALSE; }
if (m->interactObj == NULL || m->interactObj->oHeldState == HELD_HELD) { return FALSE; } if (m->interactObj == NULL || m->interactObj->oHeldState == HELD_HELD) { return FALSE; }
@ -937,7 +938,6 @@ u32 interact_star_or_key(struct MarioState *m, UNUSED u32 interactType, struct O
play_sound(SOUND_MENU_STAR_SOUND, m->marioObj->header.gfx.cameraToObject); play_sound(SOUND_MENU_STAR_SOUND, m->marioObj->header.gfx.cameraToObject);
#ifndef VERSION_JP #ifndef VERSION_JP
update_mario_sound_and_camera(m); update_mario_sound_and_camera(m);
// func_802521A0
#endif #endif
if (grandStar) { if (grandStar) {
@ -1551,6 +1551,7 @@ u32 interact_clam_or_bubba(struct MarioState *m, UNUSED u32 interactType, struct
if (!(o->oInteractionSubtype & INT_SUBTYPE_DELAY_INVINCIBILITY)) { if (!(o->oInteractionSubtype & INT_SUBTYPE_DELAY_INVINCIBILITY)) {
sDelayInvincTimer = TRUE; sDelayInvincTimer = TRUE;
} }
return TRUE; return TRUE;
} }
@ -1621,6 +1622,7 @@ u32 interact_shock(struct MarioState *m, UNUSED u32 interactType, struct Object
if (!(o->oInteractionSubtype & INT_SUBTYPE_DELAY_INVINCIBILITY)) { if (!(o->oInteractionSubtype & INT_SUBTYPE_DELAY_INVINCIBILITY)) {
sDelayInvincTimer = TRUE; sDelayInvincTimer = TRUE;
} }
return FALSE; return FALSE;
} }
@ -1681,6 +1683,7 @@ u32 interact_hit_from_below(struct MarioState *m, UNUSED u32 interactType, struc
if (!(o->oInteractionSubtype & INT_SUBTYPE_DELAY_INVINCIBILITY)) { if (!(o->oInteractionSubtype & INT_SUBTYPE_DELAY_INVINCIBILITY)) {
sDelayInvincTimer = TRUE; sDelayInvincTimer = TRUE;
} }
return FALSE; return FALSE;
} }
@ -1716,6 +1719,7 @@ u32 interact_bounce_top(struct MarioState *m, UNUSED u32 interactType, struct Ob
if (!(o->oInteractionSubtype & INT_SUBTYPE_DELAY_INVINCIBILITY)) { if (!(o->oInteractionSubtype & INT_SUBTYPE_DELAY_INVINCIBILITY)) {
sDelayInvincTimer = TRUE; sDelayInvincTimer = TRUE;
} }
return FALSE; return FALSE;
} }
@ -1732,6 +1736,7 @@ u32 interact_unknown_08(struct MarioState *m, UNUSED u32 interactType, struct Ob
if (!(o->oInteractionSubtype & INT_SUBTYPE_DELAY_INVINCIBILITY)) { if (!(o->oInteractionSubtype & INT_SUBTYPE_DELAY_INVINCIBILITY)) {
sDelayInvincTimer = TRUE; sDelayInvincTimer = TRUE;
} }
return FALSE; return FALSE;
} }
@ -1743,6 +1748,7 @@ u32 interact_damage(struct MarioState *m, UNUSED u32 interactType, struct Object
if (!(o->oInteractionSubtype & INT_SUBTYPE_DELAY_INVINCIBILITY)) { if (!(o->oInteractionSubtype & INT_SUBTYPE_DELAY_INVINCIBILITY)) {
sDelayInvincTimer = TRUE; sDelayInvincTimer = TRUE;
} }
return FALSE; return FALSE;
} }
@ -1963,7 +1969,7 @@ u32 interact_cap(struct MarioState *m, UNUSED u32 interactType, struct Object *o
} }
u32 interact_grabbable(struct MarioState *m, u32 interactType, struct Object *o) { u32 interact_grabbable(struct MarioState *m, u32 interactType, struct Object *o) {
void *script = virtual_to_segmented(0x13, o->behavior); const BehaviorScript *script = virtual_to_segmented(0x13, o->behavior);
if (m->playerIndex != 0) { return FALSE; } if (m->playerIndex != 0) { return FALSE; }
@ -1995,6 +2001,7 @@ u32 interact_grabbable(struct MarioState *m, u32 interactType, struct Object *o)
if (script != bhvBowser) { if (script != bhvBowser) {
push_mario_out_of_object(m, o, -5.0f); push_mario_out_of_object(m, o, -5.0f);
} }
return FALSE; return FALSE;
} }
@ -2010,7 +2017,7 @@ u32 mario_can_talk(struct MarioState *m, u32 arg) {
return TRUE; return TRUE;
} }
val6 = m->marioObj->header.gfx.unk38.animID; val6 = m->marioObj->header.gfx.animInfo.animID;
if (val6 == 0x0080 || val6 == 0x007F || val6 == 0x006C) { if (val6 == 0x0080 || val6 == 0x007F || val6 == 0x006C) {
return TRUE; return TRUE;

View file

@ -85,7 +85,7 @@ enum InteractionType {
#define INT_STATUS_MARIO_UNK1 (1 << 1) /* 0x00000002 */ #define INT_STATUS_MARIO_UNK1 (1 << 1) /* 0x00000002 */
#define INT_STATUS_MARIO_UNK2 (1 << 2) /* 0x00000004 */ #define INT_STATUS_MARIO_UNK2 (1 << 2) /* 0x00000004 */
#define INT_STATUS_MARIO_DROP_OBJECT (1 << 3) /* 0x00000008 */ #define INT_STATUS_MARIO_DROP_OBJECT (1 << 3) /* 0x00000008 */
#define INT_STATUS_MARIO_UNK4 (1 << 4) /* 0x00000010 */ #define INT_STATUS_HIT_BY_SHOCKWAVE (1 << 4) /* 0x00000010 */
#define INT_STATUS_MARIO_UNK5 (1 << 5) /* 0x00000020 */ #define INT_STATUS_MARIO_UNK5 (1 << 5) /* 0x00000020 */
#define INT_STATUS_MARIO_UNK6 (1 << 6) /* 0x00000040 */ #define INT_STATUS_MARIO_UNK6 (1 << 6) /* 0x00000040 */
#define INT_STATUS_MARIO_UNK7 (1 << 7) /* 0x00000080 */ #define INT_STATUS_MARIO_UNK7 (1 << 7) /* 0x00000080 */
@ -106,7 +106,7 @@ void mario_grab_used_object(struct MarioState *m);
void mario_drop_held_object(struct MarioState *m); void mario_drop_held_object(struct MarioState *m);
void mario_throw_held_object(struct MarioState *m); void mario_throw_held_object(struct MarioState *m);
void mario_stop_riding_and_holding(struct MarioState *m); void mario_stop_riding_and_holding(struct MarioState *m);
u32 does_mario_have_hat(struct MarioState *m); u32 does_mario_have_normal_cap_on_head(struct MarioState *m);
void mario_blow_off_cap(struct MarioState *m, f32 capSpeed); void mario_blow_off_cap(struct MarioState *m, f32 capSpeed);
u32 mario_lose_cap_to_enemy(struct MarioState* m, u32 arg); u32 mario_lose_cap_to_enemy(struct MarioState* m, u32 arg);
void mario_retrieve_cap(struct MarioState* m); void mario_retrieve_cap(struct MarioState* m);

View file

@ -55,6 +55,7 @@ Gfx *geo_envfx_main(s32 callContext, struct GraphNode *node, UNUSED Mat4 mtxf) {
vec3s_copy(marioPos, gVec3sZero); vec3s_copy(marioPos, gVec3sZero);
envfx_update_particles(ENVFX_MODE_NONE, marioPos, camTo, camFrom); envfx_update_particles(ENVFX_MODE_NONE, marioPos, camTo, camFrom);
} }
return gfx; return gfx;
} }
@ -77,5 +78,6 @@ Gfx *geo_skybox_main(s32 callContext, struct GraphNode *node, UNUSED Mat4 *mtx)
gLakituState.pos[1], gLakituState.pos[2], gLakituState.focus[0], gLakituState.pos[1], gLakituState.pos[2], gLakituState.focus[0],
gLakituState.focus[1], gLakituState.focus[2]); gLakituState.focus[1], gLakituState.focus[2]);
} }
return gfx; return gfx;
} }

View file

@ -173,11 +173,11 @@ s32 sDelayedWarpArg;
s16 unusedEULevelUpdateBss1; s16 unusedEULevelUpdateBss1;
#endif #endif
s8 sTimerRunning; s8 sTimerRunning;
s8 gShouldNotPlayCastleMusic; s8 gNeverEnteredCastle;
struct MarioState *gMarioState = &gMarioStates[0]; struct MarioState *gMarioState = &gMarioStates[0];
u8 unused1[4] = { 0 }; u8 unused1[4] = { 0 };
s8 gInWarpCheckpoint = 0; s8 sWarpCheckpointActive = FALSE;
u8 unused3[4]; u8 unused3[4];
u8 unused4[2]; u8 unused4[2];
@ -491,7 +491,7 @@ void init_mario_after_warp(void) {
#ifndef VERSION_JP #ifndef VERSION_JP
if (gCurrLevelNum == LEVEL_BOB if (gCurrLevelNum == LEVEL_BOB
&& get_current_background_music() != SEQUENCE_ARGS(4, SEQ_LEVEL_SLIDE) && get_current_background_music() != SEQUENCE_ARGS(4, SEQ_LEVEL_SLIDE)
&& sTimerRunning != 0) { && sTimerRunning) {
play_music(SEQ_PLAYER_LEVEL, SEQUENCE_ARGS(4, SEQ_LEVEL_SLIDE), 0); play_music(SEQ_PLAYER_LEVEL, SEQUENCE_ARGS(4, SEQ_LEVEL_SLIDE), 0);
} }
#endif #endif
@ -737,7 +737,7 @@ static void initiate_painting_warp_node(struct WarpNode *pWarpNode) {
struct WarpNode warpNode = *pWarpNode; struct WarpNode warpNode = *pWarpNode;
if (!(warpNode.destLevel & 0x80)) { if (!(warpNode.destLevel & 0x80)) {
gInWarpCheckpoint = check_warp_checkpoint(&warpNode); sWarpCheckpointActive = check_warp_checkpoint(&warpNode);
} }
initiate_warp(warpNode.destLevel & 0x7F, warpNode.destArea, warpNode.destNode, 0); initiate_warp(warpNode.destLevel & 0x7F, warpNode.destArea, warpNode.destNode, 0);
@ -764,6 +764,7 @@ void initiate_painting_warp(void) {
play_painting_eject_sound(); play_painting_eject_sound();
} else if (pWarpNode->id != 0) { } else if (pWarpNode->id != 0) {
initiate_painting_warp_node(pWarpNode); initiate_painting_warp_node(pWarpNode);
set_mario_action(gMarioState, ACT_DISAPPEARED, 0); set_mario_action(gMarioState, ACT_DISAPPEARED, 0);
gMarioState->marioObj->header.gfx.node.flags &= ~GRAPH_RENDER_ACTIVE; gMarioState->marioObj->header.gfx.node.flags &= ~GRAPH_RENDER_ACTIVE;
} }
@ -790,8 +791,7 @@ s16 level_trigger_warp(struct MarioState *m, s32 warpOp) {
switch (warpOp) { switch (warpOp) {
case WARP_OP_DEMO_NEXT: case WARP_OP_DEMO_NEXT:
case WARP_OP_DEMO_END: case WARP_OP_DEMO_END: sDelayedWarpTimer = 20; // Must be one line to match on -O2
do {sDelayedWarpTimer = 20;} while (0);
sSourceWarpNodeId = WARP_NODE_F0; sSourceWarpNodeId = WARP_NODE_F0;
gSavedCourseNum = COURSE_NONE; gSavedCourseNum = COURSE_NONE;
val04 = FALSE; val04 = FALSE;
@ -987,7 +987,7 @@ void update_hud_values(void) {
if (gCurrCreditsEntry == NULL) { if (gCurrCreditsEntry == NULL) {
s16 numHealthWedges = gMarioState->health > 0 ? gMarioState->health >> 8 : 0; s16 numHealthWedges = gMarioState->health > 0 ? gMarioState->health >> 8 : 0;
if (gCurrCourseNum > 0) { if (gCurrCourseNum >= COURSE_MIN) {
gHudDisplay.flags |= HUD_DISPLAY_FLAG_COIN_COUNT; gHudDisplay.flags |= HUD_DISPLAY_FLAG_COIN_COUNT;
} else { } else {
gHudDisplay.flags &= ~HUD_DISPLAY_FLAG_COIN_COUNT; gHudDisplay.flags &= ~HUD_DISPLAY_FLAG_COIN_COUNT;
@ -1206,7 +1206,6 @@ s32 play_mode_change_area(void) {
sTransitionTimer -= 1; sTransitionTimer -= 1;
} }
//! If sTransitionTimer is -1, this will miss.
if (sTransitionTimer == 0) { if (sTransitionTimer == 0) {
sTransitionUpdate = NULL; sTransitionUpdate = NULL;
set_play_mode(PLAY_MODE_NORMAL); set_play_mode(PLAY_MODE_NORMAL);
@ -1228,7 +1227,6 @@ s32 play_mode_change_level(void) {
sTransitionUpdate(&sTransitionTimer); sTransitionUpdate(&sTransitionTimer);
} }
//! If sTransitionTimer is -1, this will miss.
if (--sTransitionTimer == -1) { if (--sTransitionTimer == -1) {
gHudDisplay.flags = HUD_DISPLAY_NONE; gHudDisplay.flags = HUD_DISPLAY_NONE;
sTransitionTimer = 0; sTransitionTimer = 0;
@ -1344,7 +1342,7 @@ s32 init_level(void) {
gHudDisplay.flags = HUD_DISPLAY_NONE; gHudDisplay.flags = HUD_DISPLAY_NONE;
} }
sTimerRunning = 0; sTimerRunning = FALSE;
if (sWarpDest.type != WARP_TYPE_NOT_WARPING) { if (sWarpDest.type != WARP_TYPE_NOT_WARPING) {
if (sWarpDest.nodeId >= WARP_NODE_CREDITS_MIN) { if (sWarpDest.nodeId >= WARP_NODE_CREDITS_MIN) {
@ -1363,7 +1361,7 @@ s32 init_level(void) {
if (gCurrDemoInput != NULL) { if (gCurrDemoInput != NULL) {
set_mario_action(gMarioState, ACT_IDLE, 0); set_mario_action(gMarioState, ACT_IDLE, 0);
} else if (gDebugLevelSelect == 0) { } else if (!gDebugLevelSelect) {
if (gMarioState->action != ACT_UNINITIALIZED) { if (gMarioState->action != ACT_UNINITIALIZED) {
bool skipIntro = (gNetworkType == NT_NONE || gServerSettings.skipIntro != 0); bool skipIntro = (gNetworkType == NT_NONE || gServerSettings.skipIntro != 0);
if (gDjuiInMainMenu && (gNetworkType == NT_NONE)) { if (gDjuiInMainMenu && (gNetworkType == NT_NONE)) {
@ -1445,14 +1443,14 @@ s32 lvl_init_from_save_file(UNUSED s16 arg0, s32 levelNum) {
#endif #endif
sWarpDest.type = WARP_TYPE_NOT_WARPING; sWarpDest.type = WARP_TYPE_NOT_WARPING;
sDelayedWarpOp = WARP_OP_NONE; sDelayedWarpOp = WARP_OP_NONE;
gShouldNotPlayCastleMusic = !save_file_exists(gCurrSaveFileNum - 1) && gCLIOpts.SkipIntro == 0 && configSkipIntro == 0; gNeverEnteredCastle = !save_file_exists(gCurrSaveFileNum - 1) && gCLIOpts.SkipIntro == 0 && configSkipIntro == 0;
if (gNetworkType == NT_NONE) { gShouldNotPlayCastleMusic = true; } if (gNetworkType == NT_NONE) { gNeverEnteredCastle = true; }
gCurrLevelNum = levelNum; gCurrLevelNum = levelNum;
gCurrCourseNum = COURSE_NONE; gCurrCourseNum = COURSE_NONE;
gSavedCourseNum = COURSE_NONE; gSavedCourseNum = COURSE_NONE;
gCurrCreditsEntry = NULL; gCurrCreditsEntry = NULL;
gSpecialTripleJump = 0; gSpecialTripleJump = FALSE;
init_mario_from_save_file(); init_mario_from_save_file();
disable_warp_checkpoint(); disable_warp_checkpoint();
@ -1464,9 +1462,9 @@ s32 lvl_init_from_save_file(UNUSED s16 arg0, s32 levelNum) {
} }
s32 lvl_set_current_level(UNUSED s16 arg0, s32 levelNum) { s32 lvl_set_current_level(UNUSED s16 arg0, s32 levelNum) {
s32 val4 = gInWarpCheckpoint; s32 warpCheckpointActive = sWarpCheckpointActive;
gInWarpCheckpoint = 0; sWarpCheckpointActive = FALSE;
gCurrLevelNum = levelNum; gCurrLevelNum = levelNum;
gCurrCourseNum = gLevelToCourseNumTable[levelNum - 1]; gCurrCourseNum = gLevelToCourseNumTable[levelNum - 1];
@ -1487,11 +1485,11 @@ s32 lvl_set_current_level(UNUSED s16 arg0, s32 levelNum) {
disable_warp_checkpoint(); disable_warp_checkpoint();
} }
if (gCurrCourseNum > COURSE_STAGES_MAX || val4 != 0) { if (gCurrCourseNum > COURSE_STAGES_MAX || warpCheckpointActive) {
return 0; return 0;
} }
if (gDebugLevelSelect != 0 && gShowProfiler == 0) { if (gDebugLevelSelect && !gShowProfiler) {
return 0; return 0;
} }
@ -1515,8 +1513,8 @@ s32 lvl_exiting_credits(UNUSED s16 arg0, UNUSED s32 arg1) {
void fake_lvl_init_from_save_file(void) { void fake_lvl_init_from_save_file(void) {
sWarpDest.type = WARP_TYPE_NOT_WARPING; sWarpDest.type = WARP_TYPE_NOT_WARPING;
sDelayedWarpOp = WARP_OP_NONE; sDelayedWarpOp = WARP_OP_NONE;
gShouldNotPlayCastleMusic = !save_file_exists(gCurrSaveFileNum - 1) && gServerSettings.skipIntro; gNeverEnteredCastle = !save_file_exists(gCurrSaveFileNum - 1) && gServerSettings.skipIntro;
if (gNetworkType == NT_NONE) { gShouldNotPlayCastleMusic = true; } if (gNetworkType == NT_NONE) { gNeverEnteredCastle = true; }
gCurrCreditsEntry = NULL; gCurrCreditsEntry = NULL;
gSpecialTripleJump = 0; gSpecialTripleJump = 0;

View file

@ -99,7 +99,7 @@ struct SavedWarpValues {
}; };
extern struct WarpDest sWarpDest; extern struct WarpDest sWarpDest;
extern s8 gInWarpCheckpoint; extern s8 sWarpCheckpointActive;
extern u8 gRejectInstantWarp; extern u8 gRejectInstantWarp;
extern s16 D_80339EE0; extern s16 D_80339EE0;
@ -121,7 +121,7 @@ struct HudDisplay {
}; };
extern struct HudDisplay gHudDisplay; extern struct HudDisplay gHudDisplay;
extern s8 gShouldNotPlayCastleMusic; extern s8 gNeverEnteredCastle;
extern u32 gControlTimerStartNat; extern u32 gControlTimerStartNat;
extern u32 gControlTimerStopNat; extern u32 gControlTimerStopNat;

View file

@ -112,8 +112,8 @@ void spawn_macro_objects(s16 areaIndex, s16 *macroObjList) {
struct Object *newObj; struct Object *newObj;
struct LoadedPreset preset; struct LoadedPreset preset;
gMacroObjectDefaultParent.header.gfx.unk18 = areaIndex; gMacroObjectDefaultParent.header.gfx.areaIndex = areaIndex;
gMacroObjectDefaultParent.header.gfx.unk19 = areaIndex; gMacroObjectDefaultParent.header.gfx.activeAreaIndex = areaIndex;
while (TRUE) { while (TRUE) {
if (*macroObjList == -1) { // An encountered value of -1 means the list has ended. if (*macroObjList == -1) { // An encountered value of -1 means the list has ended.
@ -184,8 +184,8 @@ void spawn_macro_objects_hardcoded(s16 areaIndex, s16 *macroObjList) {
UNUSED u8 pad2[10]; UNUSED u8 pad2[10];
gMacroObjectDefaultParent.header.gfx.unk18 = areaIndex; gMacroObjectDefaultParent.header.gfx.areaIndex = areaIndex;
gMacroObjectDefaultParent.header.gfx.unk19 = areaIndex; gMacroObjectDefaultParent.header.gfx.activeAreaIndex = areaIndex;
while (TRUE) { while (TRUE) {
macroObjPreset = *macroObjList++; macroObjPreset = *macroObjList++;
@ -258,8 +258,8 @@ void spawn_special_objects(s16 areaIndex, s16 **specialObjList) {
numOfSpecialObjects = **specialObjList; numOfSpecialObjects = **specialObjList;
(*specialObjList)++; (*specialObjList)++;
gMacroObjectDefaultParent.header.gfx.unk18 = areaIndex; gMacroObjectDefaultParent.header.gfx.areaIndex = areaIndex;
gMacroObjectDefaultParent.header.gfx.unk19 = areaIndex; gMacroObjectDefaultParent.header.gfx.activeAreaIndex = areaIndex;
for (i = 0; i < numOfSpecialObjects; i++) { for (i = 0; i < numOfSpecialObjects; i++) {
presetID = (u8) * *specialObjList; presetID = (u8) * *specialObjList;

View file

@ -5,7 +5,6 @@
#include "types.h" #include "types.h"
/* Functions */
s16 convert_rotation(s16 inRotation); s16 convert_rotation(s16 inRotation);
void spawn_macro_abs_yrot_2params(u32 model, const BehaviorScript *behavior, s16 x, s16 y, s16 z, s16 ry, s16 params); void spawn_macro_abs_yrot_2params(u32 model, const BehaviorScript *behavior, s16 x, s16 y, s16 z, s16 ry, s16 params);

View file

@ -63,11 +63,11 @@ struct SPTask *sCurrentAudioSPTask = NULL;
struct SPTask *sCurrentDisplaySPTask = NULL; struct SPTask *sCurrentDisplaySPTask = NULL;
struct SPTask *sNextAudioSPTask = NULL; struct SPTask *sNextAudioSPTask = NULL;
struct SPTask *sNextDisplaySPTask = NULL; struct SPTask *sNextDisplaySPTask = NULL;
s8 sAudioEnabled = 1; s8 sAudioEnabled = TRUE;
u32 sNumVblanks = 0; u32 sNumVblanks = 0;
s8 gResetTimer = 0; s8 gResetTimer = 0;
s8 D_8032C648 = 0; s8 D_8032C648 = 0;
s8 gDebugLevelSelect = 0; s8 gDebugLevelSelect = FALSE;
s8 D_8032C650 = 0; s8 D_8032C650 = 0;
s8 gShowProfiler = FALSE; s8 gShowProfiler = FALSE;
@ -256,7 +256,7 @@ void handle_vblank(void) {
interrupt_gfx_sptask(); interrupt_gfx_sptask();
} else { } else {
profiler_log_vblank_time(); profiler_log_vblank_time();
if (sAudioEnabled != 0) { if (sAudioEnabled) {
start_sptask(M_AUDTASK); start_sptask(M_AUDTASK);
} else { } else {
pretend_audio_sptask_done(); pretend_audio_sptask_done();
@ -299,7 +299,7 @@ void handle_sp_complete(void) {
// Start the audio task, as expected by handle_vblank. // Start the audio task, as expected by handle_vblank.
profiler_log_vblank_time(); profiler_log_vblank_time();
if (sAudioEnabled != 0) { if (sAudioEnabled) {
start_sptask(M_AUDTASK); start_sptask(M_AUDTASK);
} else { } else {
pretend_audio_sptask_done(); pretend_audio_sptask_done();
@ -350,7 +350,7 @@ void thread3_main(UNUSED void *arg) {
create_thread(&gGameLoopThread, 5, thread5_game_loop, NULL, gThread5Stack + 0x2000, 10); create_thread(&gGameLoopThread, 5, thread5_game_loop, NULL, gThread5Stack + 0x2000, 10);
osStartThread(&gGameLoopThread); osStartThread(&gGameLoopThread);
while (1) { while (TRUE) {
OSMesg msg; OSMesg msg;
osRecvMesg(&gIntrMesgQueue, &msg, OS_MESG_BLOCK); osRecvMesg(&gIntrMesgQueue, &msg, OS_MESG_BLOCK);
@ -395,7 +395,7 @@ void send_sp_task_message(OSMesg *msg) {
} }
void dispatch_audio_sptask(struct SPTask *spTask) { void dispatch_audio_sptask(struct SPTask *spTask) {
if (sAudioEnabled != 0 && spTask != NULL) { if (sAudioEnabled && spTask != NULL) {
osWritebackDCacheAll(); osWritebackDCacheAll();
osSendMesg(&gSPTaskMesgQueue, spTask, OS_MESG_NOBLOCK); osSendMesg(&gSPTaskMesgQueue, spTask, OS_MESG_NOBLOCK);
} }
@ -416,11 +416,11 @@ void send_display_list(struct SPTask *spTask) {
} }
void turn_on_audio(void) { void turn_on_audio(void) {
sAudioEnabled = 1; sAudioEnabled = TRUE;
} }
void turn_off_audio(void) { void turn_off_audio(void) {
sAudioEnabled = 0; sAudioEnabled = FALSE;
while (sCurrentAudioSPTask != NULL) { while (sCurrentAudioSPTask != NULL) {
; ;
} }
@ -457,7 +457,7 @@ void thread1_idle(UNUSED void *arg) {
osSetThreadPri(NULL, 0); osSetThreadPri(NULL, 0);
// halt // halt
while (1) { while (TRUE) {
; ;
} }
} }

View file

@ -6,7 +6,6 @@
#include "sm64.h" #include "sm64.h"
#include "area.h" #include "area.h"
#include "audio/data.h"
#include "audio/external.h" #include "audio/external.h"
#include "behavior_actions.h" #include "behavior_actions.h"
#include "behavior_data.h" #include "behavior_data.h"
@ -62,8 +61,9 @@ u16 gLocalBubbleCounter = 0;
*/ */
s32 is_anim_at_end(struct MarioState *m) { s32 is_anim_at_end(struct MarioState *m) {
struct Object *o = m->marioObj; struct Object *o = m->marioObj;
if (o->header.gfx.unk38.curAnim == NULL) { return TRUE; }
return (o->header.gfx.unk38.animFrame + 1) == o->header.gfx.unk38.curAnim->unk08; if (o->header.gfx.animInfo.curAnim == NULL) { return TRUE; }
return (o->header.gfx.animInfo.animFrame + 1) == o->header.gfx.animInfo.curAnim->loopEnd;
} }
/** /**
@ -72,7 +72,7 @@ s32 is_anim_at_end(struct MarioState *m) {
s32 is_anim_past_end(struct MarioState *m) { s32 is_anim_past_end(struct MarioState *m) {
struct Object *o = m->marioObj; struct Object *o = m->marioObj;
return o->header.gfx.unk38.animFrame >= (o->header.gfx.unk38.curAnim->unk08 - 2); return o->header.gfx.animInfo.animFrame >= (o->header.gfx.animInfo.curAnim->loopEnd - 2);
} }
/** /**
@ -87,24 +87,24 @@ s16 set_mario_animation(struct MarioState *m, s32 targetAnimID) {
targetAnim->index = (void *) VIRTUAL_TO_PHYSICAL((u8 *) targetAnim + (uintptr_t) targetAnim->index); targetAnim->index = (void *) VIRTUAL_TO_PHYSICAL((u8 *) targetAnim + (uintptr_t) targetAnim->index);
} }
if (o->header.gfx.unk38.animID != targetAnimID) { if (o->header.gfx.animInfo.animID != targetAnimID) {
o->header.gfx.unk38.animID = targetAnimID; o->header.gfx.animInfo.animID = targetAnimID;
o->header.gfx.unk38.curAnim = targetAnim; o->header.gfx.animInfo.curAnim = targetAnim;
o->header.gfx.unk38.animAccel = 0; o->header.gfx.animInfo.animAccel = 0;
o->header.gfx.unk38.animYTrans = m->unkB0; o->header.gfx.animInfo.animYTrans = m->unkB0;
if (targetAnim->flags & ANIM_FLAG_2) { if (targetAnim->flags & ANIM_FLAG_2) {
o->header.gfx.unk38.animFrame = targetAnim->unk04; o->header.gfx.animInfo.animFrame = targetAnim->startFrame;
} else { } else {
if (targetAnim->flags & ANIM_FLAG_FORWARD) { if (targetAnim->flags & ANIM_FLAG_FORWARD) {
o->header.gfx.unk38.animFrame = targetAnim->unk04 + 1; o->header.gfx.animInfo.animFrame = targetAnim->startFrame + 1;
} else { } else {
o->header.gfx.unk38.animFrame = targetAnim->unk04 - 1; o->header.gfx.animInfo.animFrame = targetAnim->startFrame - 1;
} }
} }
} }
return o->header.gfx.unk38.animFrame; return o->header.gfx.animInfo.animFrame;
} }
/** /**
@ -120,34 +120,34 @@ s16 set_mario_anim_with_accel(struct MarioState *m, s32 targetAnimID, s32 accel)
targetAnim->index = (void *) VIRTUAL_TO_PHYSICAL((u8 *) targetAnim + (uintptr_t) targetAnim->index); targetAnim->index = (void *) VIRTUAL_TO_PHYSICAL((u8 *) targetAnim + (uintptr_t) targetAnim->index);
} }
if (o->header.gfx.unk38.animID != targetAnimID) { if (o->header.gfx.animInfo.animID != targetAnimID) {
o->header.gfx.unk38.animID = targetAnimID; o->header.gfx.animInfo.animID = targetAnimID;
o->header.gfx.unk38.curAnim = targetAnim; o->header.gfx.animInfo.curAnim = targetAnim;
o->header.gfx.unk38.animYTrans = m->unkB0; o->header.gfx.animInfo.animYTrans = m->unkB0;
if (targetAnim->flags & ANIM_FLAG_2) { if (targetAnim->flags & ANIM_FLAG_2) {
o->header.gfx.unk38.animFrameAccelAssist = (targetAnim->unk04 << 0x10); o->header.gfx.animInfo.animFrameAccelAssist = (targetAnim->startFrame << 0x10);
} else { } else {
if (targetAnim->flags & ANIM_FLAG_FORWARD) { if (targetAnim->flags & ANIM_FLAG_FORWARD) {
o->header.gfx.unk38.animFrameAccelAssist = (targetAnim->unk04 << 0x10) + accel; o->header.gfx.animInfo.animFrameAccelAssist = (targetAnim->startFrame << 0x10) + accel;
} else { } else {
o->header.gfx.unk38.animFrameAccelAssist = (targetAnim->unk04 << 0x10) - accel; o->header.gfx.animInfo.animFrameAccelAssist = (targetAnim->startFrame << 0x10) - accel;
} }
} }
o->header.gfx.unk38.animFrame = (o->header.gfx.unk38.animFrameAccelAssist >> 0x10); o->header.gfx.animInfo.animFrame = (o->header.gfx.animInfo.animFrameAccelAssist >> 0x10);
} }
o->header.gfx.unk38.animAccel = accel; o->header.gfx.animInfo.animAccel = accel;
return o->header.gfx.unk38.animFrame; return o->header.gfx.animInfo.animFrame;
} }
/** /**
* Sets the animation to a specific "next" frame from the frame given. * Sets the animation to a specific "next" frame from the frame given.
*/ */
void set_anim_to_frame(struct MarioState *m, s16 animFrame) { void set_anim_to_frame(struct MarioState *m, s16 animFrame) {
struct GraphNodeObject_sub *animInfo = &m->marioObj->header.gfx.unk38; struct AnimInfo *animInfo = &m->marioObj->header.gfx.animInfo;
struct Animation *curAnim = animInfo->curAnim; struct Animation *curAnim = animInfo->curAnim;
if (animInfo->animAccel) { if (animInfo->animAccel) {
@ -168,7 +168,7 @@ void set_anim_to_frame(struct MarioState *m, s16 animFrame) {
s32 is_anim_past_frame(struct MarioState *m, s16 animFrame) { s32 is_anim_past_frame(struct MarioState *m, s16 animFrame) {
s32 isPastFrame; s32 isPastFrame;
s32 acceleratedFrame = animFrame << 0x10; s32 acceleratedFrame = animFrame << 0x10;
struct GraphNodeObject_sub *animInfo = &m->marioObj->header.gfx.unk38; struct AnimInfo *animInfo = &m->marioObj->header.gfx.animInfo;
struct Animation *curAnim = animInfo->curAnim; struct Animation *curAnim = animInfo->curAnim;
if (animInfo->animAccel) { if (animInfo->animAccel) {
@ -200,9 +200,9 @@ s16 find_mario_anim_flags_and_translation(struct Object *obj, s32 yaw, Vec3s tra
f32 dx; f32 dx;
f32 dz; f32 dz;
struct Animation *curAnim = (void *) obj->header.gfx.unk38.curAnim; struct Animation *curAnim = (void *) obj->header.gfx.animInfo.curAnim;
if (curAnim == NULL) { return 0; } if (curAnim == NULL) { return 0; }
s16 animFrame = geo_update_animation_frame(&obj->header.gfx.unk38, NULL); s16 animFrame = geo_update_animation_frame(&obj->header.gfx.animInfo, NULL);
u16 *animIndex = segmented_to_virtual((void *) curAnim->index); u16 *animIndex = segmented_to_virtual((void *) curAnim->index);
s16 *animValues = segmented_to_virtual((void *) curAnim->values); s16 *animValues = segmented_to_virtual((void *) curAnim->values);
@ -256,7 +256,7 @@ s16 return_mario_anim_y_translation(struct MarioState *m) {
* Plays a sound if if Mario doesn't have the flag being checked. * Plays a sound if if Mario doesn't have the flag being checked.
*/ */
void play_sound_if_no_flag(struct MarioState *m, u32 soundBits, u32 flags) { void play_sound_if_no_flag(struct MarioState *m, u32 soundBits, u32 flags) {
if ((m->flags & flags) == 0) { if (!(m->flags & flags)) {
play_sound(soundBits, m->marioObj->header.gfx.cameraToObject); play_sound(soundBits, m->marioObj->header.gfx.cameraToObject);
m->flags |= flags; m->flags |= flags;
} }
@ -276,7 +276,6 @@ void play_mario_jump_sound(struct MarioState *m) {
#ifndef VERSION_JP #ifndef VERSION_JP
} }
#endif #endif
m->flags |= MARIO_MARIO_SOUND_PLAYED; m->flags |= MARIO_MARIO_SOUND_PLAYED;
} }
} }
@ -324,7 +323,7 @@ void play_sound_and_spawn_particles(struct MarioState *m, u32 soundBits, u32 wav
* Plays an environmental sound if one has not been played since the last action change. * Plays an environmental sound if one has not been played since the last action change.
*/ */
void play_mario_action_sound(struct MarioState *m, u32 soundBits, u32 waveParticleType) { void play_mario_action_sound(struct MarioState *m, u32 soundBits, u32 waveParticleType) {
if ((m->flags & MARIO_ACTION_SOUND_PLAYED) == 0) { if (!(m->flags & MARIO_ACTION_SOUND_PLAYED)) {
play_sound_and_spawn_particles(m, soundBits, waveParticleType); play_sound_and_spawn_particles(m, soundBits, waveParticleType);
m->flags |= MARIO_ACTION_SOUND_PLAYED; m->flags |= MARIO_ACTION_SOUND_PLAYED;
} }
@ -344,8 +343,8 @@ void play_mario_landing_sound(struct MarioState *m, u32 soundBits) {
* played once per action. * played once per action.
*/ */
void play_mario_landing_sound_once(struct MarioState *m, u32 soundBits) { void play_mario_landing_sound_once(struct MarioState *m, u32 soundBits) {
play_mario_action_sound(m, (m->flags & MARIO_METAL_CAP) ? SOUND_ACTION_METAL_LANDING : soundBits, play_mario_action_sound(
1); m, (m->flags & MARIO_METAL_CAP) ? SOUND_ACTION_METAL_LANDING : soundBits, 1);
} }
/** /**
@ -371,9 +370,8 @@ void play_mario_heavy_landing_sound_once(struct MarioState *m, u32 soundBits) {
*/ */
void play_mario_sound(struct MarioState *m, s32 actionSound, s32 marioSound) { void play_mario_sound(struct MarioState *m, s32 actionSound, s32 marioSound) {
if (actionSound == SOUND_ACTION_TERRAIN_JUMP) { if (actionSound == SOUND_ACTION_TERRAIN_JUMP) {
play_mario_action_sound( play_mario_action_sound(m, (m->flags & MARIO_METAL_CAP) ? (s32) SOUND_ACTION_METAL_JUMP
m, (m->flags & MARIO_METAL_CAP) ? (s32)SOUND_ACTION_METAL_JUMP : (s32) SOUND_ACTION_TERRAIN_JUMP, 1);
: (s32)SOUND_ACTION_TERRAIN_JUMP, 1);
} else { } else {
play_sound_if_no_flag(m, actionSound, MARIO_ACTION_SOUND_PLAYED); play_sound_if_no_flag(m, actionSound, MARIO_ACTION_SOUND_PLAYED);
} }
@ -447,7 +445,7 @@ s32 mario_get_floor_class(struct MarioState *m) {
floorClass = SURFACE_CLASS_DEFAULT; floorClass = SURFACE_CLASS_DEFAULT;
} }
if (m->floor) { if (m->floor != NULL) {
switch (m->floor->type) { switch (m->floor->type) {
case SURFACE_NOT_SLIPPERY: case SURFACE_NOT_SLIPPERY:
case SURFACE_HARD_NOT_SLIPPERY: case SURFACE_HARD_NOT_SLIPPERY:
@ -513,7 +511,7 @@ u32 mario_get_terrain_sound_addend(struct MarioState *m) {
s32 ret = SOUND_TERRAIN_DEFAULT << 16; s32 ret = SOUND_TERRAIN_DEFAULT << 16;
s32 floorType; s32 floorType;
if (m->floor) { if (m->floor != NULL) {
floorType = m->floor->type; floorType = m->floor->type;
if ((gCurrLevelNum != LEVEL_LLL) && (m->floorHeight < (m->waterLevel - 10))) { if ((gCurrLevelNum != LEVEL_LLL) && (m->floorHeight < (m->waterLevel - 10))) {
@ -658,26 +656,25 @@ s32 mario_floor_is_slope(struct MarioState *m) {
f32 normY; f32 normY;
if ((m->area->terrainType & TERRAIN_MASK) == TERRAIN_SLIDE if ((m->area->terrainType & TERRAIN_MASK) == TERRAIN_SLIDE
&& m->floor->normal.y < 0.9998477f //~cos(1 deg) && m->floor->normal.y < 0.9998477f) { // ~cos(1 deg)
) {
return TRUE; return TRUE;
} }
switch (mario_get_floor_class(m)) { switch (mario_get_floor_class(m)) {
case SURFACE_VERY_SLIPPERY: case SURFACE_VERY_SLIPPERY:
normY = 0.9961947f; //~cos(5 deg) normY = 0.9961947f; // ~cos(5 deg)
break; break;
case SURFACE_SLIPPERY: case SURFACE_SLIPPERY:
normY = 0.9848077f; //~cos(10 deg) normY = 0.9848077f; // ~cos(10 deg)
break; break;
default: default:
normY = 0.9659258f; //~cos(15 deg) normY = 0.9659258f; // ~cos(15 deg)
break; break;
case SURFACE_NOT_SLIPPERY: case SURFACE_NOT_SLIPPERY:
normY = 0.9396926f; //~cos(20 deg) normY = 0.9396926f; // ~cos(20 deg)
break; break;
} }
@ -698,19 +695,19 @@ s32 mario_floor_is_steep(struct MarioState *m) {
if (!mario_facing_downhill(m, FALSE)) { if (!mario_facing_downhill(m, FALSE)) {
switch (mario_get_floor_class(m)) { switch (mario_get_floor_class(m)) {
case SURFACE_VERY_SLIPPERY: case SURFACE_VERY_SLIPPERY:
normY = 0.9659258f; //~cos(15 deg) normY = 0.9659258f; // ~cos(15 deg)
break; break;
case SURFACE_SLIPPERY: case SURFACE_SLIPPERY:
normY = 0.9396926f; //~cos(20 deg) normY = 0.9396926f; // ~cos(20 deg)
break; break;
default: default:
normY = 0.8660254f; //~cos(30 deg) normY = 0.8660254f; // ~cos(30 deg)
break; break;
case SURFACE_NOT_SLIPPERY: case SURFACE_NOT_SLIPPERY:
normY = 0.8660254f; //~cos(30 deg) normY = 0.8660254f; // ~cos(30 deg)
break; break;
} }
@ -837,10 +834,9 @@ static void set_mario_y_vel_based_on_fspeed(struct MarioState *m, f32 initialVel
static u32 set_mario_action_airborne(struct MarioState *m, u32 action, u32 actionArg) { static u32 set_mario_action_airborne(struct MarioState *m, u32 action, u32 actionArg) {
f32 fowardVel; f32 fowardVel;
if (m->squishTimer != 0 || m->quicksandDepth >= 1.0f) { if ((m->squishTimer != 0 || m->quicksandDepth >= 1.0f)
if (action == ACT_DOUBLE_JUMP || action == ACT_TWIRLING) { && (action == ACT_DOUBLE_JUMP || action == ACT_TWIRLING)) {
action = ACT_JUMP; action = ACT_JUMP;
}
} }
switch (action) { switch (action) {
@ -850,7 +846,7 @@ static u32 set_mario_action_airborne(struct MarioState *m, u32 action, u32 actio
break; break;
case ACT_BACKFLIP: case ACT_BACKFLIP:
m->marioObj->header.gfx.unk38.animID = -1; m->marioObj->header.gfx.animInfo.animID = -1;
m->forwardVel = -16.0f; m->forwardVel = -16.0f;
set_mario_y_vel_based_on_fspeed(m, 62.0f, 0.0f); set_mario_y_vel_based_on_fspeed(m, 62.0f, 0.0f);
break; break;
@ -882,7 +878,7 @@ static u32 set_mario_action_airborne(struct MarioState *m, u32 action, u32 actio
case ACT_JUMP: case ACT_JUMP:
case ACT_HOLD_JUMP: case ACT_HOLD_JUMP:
m->marioObj->header.gfx.unk38.animID = -1; m->marioObj->header.gfx.animInfo.animID = -1;
set_mario_y_vel_based_on_fspeed(m, 42.0f, 0.25f); set_mario_y_vel_based_on_fspeed(m, 42.0f, 0.25f);
m->forwardVel *= 0.8f; m->forwardVel *= 0.8f;
break; break;
@ -903,7 +899,7 @@ static u32 set_mario_action_airborne(struct MarioState *m, u32 action, u32 actio
break; break;
case ACT_STEEP_JUMP: case ACT_STEEP_JUMP:
m->marioObj->header.gfx.unk38.animID = -1; m->marioObj->header.gfx.animInfo.animID = -1;
set_mario_y_vel_based_on_fspeed(m, 42.0f, 0.25f); set_mario_y_vel_based_on_fspeed(m, 42.0f, 0.25f);
m->faceAngle[0] = -0x2000; m->faceAngle[0] = -0x2000;
break; break;
@ -923,7 +919,7 @@ static u32 set_mario_action_airborne(struct MarioState *m, u32 action, u32 actio
break; break;
case ACT_LONG_JUMP: case ACT_LONG_JUMP:
m->marioObj->header.gfx.unk38.animID = -1; m->marioObj->header.gfx.animInfo.animID = -1;
set_mario_y_vel_based_on_fspeed(m, 30.0f, 0.0f); set_mario_y_vel_based_on_fspeed(m, 30.0f, 0.0f);
m->marioObj->oMarioLongJumpIsSlow = m->forwardVel > 16.0f ? FALSE : TRUE; m->marioObj->oMarioLongJumpIsSlow = m->forwardVel > 16.0f ? FALSE : TRUE;
@ -1249,7 +1245,7 @@ s32 set_water_plunge_action(struct MarioState *m) {
vec3s_set(m->angleVel, 0, 0, 0); vec3s_set(m->angleVel, 0, 0, 0);
if ((m->action & ACT_FLAG_DIVING) == 0) { if (!(m->action & ACT_FLAG_DIVING)) {
m->faceAngle[0] = 0; m->faceAngle[0] = 0;
} }
@ -1354,7 +1350,7 @@ void update_mario_button_inputs(struct MarioState *m) {
if (m->input & INPUT_B_PRESSED) { if (m->input & INPUT_B_PRESSED) {
m->framesSinceB = 0; m->framesSinceB = 0;
} else if (m->framesSinceB < 0xff) { } else if (m->framesSinceB < 0xFF) {
m->framesSinceB += 1; m->framesSinceB += 1;
} }
} }
@ -1418,7 +1414,7 @@ copyPlayerGoto:;
gasLevel = find_poison_gas_level(m->pos[0], m->pos[2]); gasLevel = find_poison_gas_level(m->pos[0], m->pos[2]);
m->waterLevel = find_water_level(m->pos[0], m->pos[2]); m->waterLevel = find_water_level(m->pos[0], m->pos[2]);
if (m->floor) { if (m->floor != NULL) {
m->floorAngle = atan2s(m->floor->normal.z, m->floor->normal.x); m->floorAngle = atan2s(m->floor->normal.z, m->floor->normal.x);
m->terrainSoundAddend = mario_get_terrain_sound_addend(m); m->terrainSoundAddend = mario_get_terrain_sound_addend(m);
@ -1522,7 +1518,7 @@ void update_mario_inputs(struct MarioState *m) {
} }
if (m->marioObj->oInteractStatus if (m->marioObj->oInteractStatus
& (INT_STATUS_HOOT_GRABBED_BY_MARIO | INT_STATUS_MARIO_UNK1 | INT_STATUS_MARIO_UNK4)) { & (INT_STATUS_HOOT_GRABBED_BY_MARIO | INT_STATUS_MARIO_UNK1 | INT_STATUS_HIT_BY_SHOCKWAVE)) {
m->input |= INPUT_UNKNOWN_10; m->input |= INPUT_UNKNOWN_10;
} }
if (m->heldObj != NULL) { if (m->heldObj != NULL) {
@ -1554,7 +1550,7 @@ void set_submerged_cam_preset_and_spawn_bubbles(struct MarioState *m) {
heightBelowWater = (f32)(m->waterLevel - 80) - m->pos[1]; heightBelowWater = (f32)(m->waterLevel - 80) - m->pos[1];
camPreset = m->area->camera->mode; camPreset = m->area->camera->mode;
if ((m->action & ACT_FLAG_METAL_WATER)) { if (m->action & ACT_FLAG_METAL_WATER) {
if (m->playerIndex == 0 && camPreset != CAMERA_MODE_CLOSE) { if (m->playerIndex == 0 && camPreset != CAMERA_MODE_CLOSE) {
set_camera_mode(m->area->camera, CAMERA_MODE_CLOSE, 1); set_camera_mode(m->area->camera, CAMERA_MODE_CLOSE, 1);
} }
@ -1569,7 +1565,7 @@ void set_submerged_cam_preset_and_spawn_bubbles(struct MarioState *m) {
// As long as Mario isn't drowning or at the top // As long as Mario isn't drowning or at the top
// of the water with his head out, spawn bubbles. // of the water with his head out, spawn bubbles.
if ((m->action & ACT_FLAG_INTANGIBLE) == 0) { if (!(m->action & ACT_FLAG_INTANGIBLE)) {
if ((m->pos[1] < (f32)(m->waterLevel - 160)) || (m->faceAngle[0] < -0x800)) { if ((m->pos[1] < (f32)(m->waterLevel - 160)) || (m->faceAngle[0] < -0x800)) {
m->particleFlags |= PARTICLE_BUBBLE; m->particleFlags |= PARTICLE_BUBBLE;
} }
@ -1587,12 +1583,12 @@ void update_mario_health(struct MarioState *m) {
if (m->health >= 0x100) { if (m->health >= 0x100) {
// When already healing or hurting Mario, Mario's HP is not changed any more here. // When already healing or hurting Mario, Mario's HP is not changed any more here.
if (((u32) m->healCounter | (u32) m->hurtCounter) == 0) { if (((u32) m->healCounter | (u32) m->hurtCounter) == 0) {
if ((m->input & INPUT_IN_POISON_GAS) && ((m->action & ACT_FLAG_INTANGIBLE) == 0)) { if ((m->input & INPUT_IN_POISON_GAS) && !(m->action & ACT_FLAG_INTANGIBLE)) {
if (((m->flags & MARIO_METAL_CAP) == 0) && (gDebugLevelSelect == 0)) { if (!(m->flags & MARIO_METAL_CAP) && !gDebugLevelSelect) {
m->health -= 4; m->health -= 4;
} }
} else { } else {
if ((m->action & ACT_FLAG_SWIMMING) && ((m->action & ACT_FLAG_INTANGIBLE) == 0)) { if ((m->action & ACT_FLAG_SWIMMING) && !(m->action & ACT_FLAG_INTANGIBLE)) {
terrainIsSnow = (m->area->terrainType & TERRAIN_MASK) == TERRAIN_SNOW; terrainIsSnow = (m->area->terrainType & TERRAIN_MASK) == TERRAIN_SNOW;
// When Mario is near the water surface, recover health (unless in snow), // When Mario is near the water surface, recover health (unless in snow),
@ -1600,7 +1596,7 @@ void update_mario_health(struct MarioState *m) {
// If using the debug level select, do not lose any HP to water. // If using the debug level select, do not lose any HP to water.
if ((m->pos[1] >= (m->waterLevel - 140)) && !terrainIsSnow) { if ((m->pos[1] >= (m->waterLevel - 140)) && !terrainIsSnow) {
m->health += 0x1A; m->health += 0x1A;
} else if (gDebugLevelSelect == 0) { } else if (!gDebugLevelSelect) {
m->health -= (terrainIsSnow ? 3 : 1); m->health -= (terrainIsSnow ? 3 : 1);
} }
} }
@ -1616,7 +1612,7 @@ void update_mario_health(struct MarioState *m) {
m->hurtCounter--; m->hurtCounter--;
} }
if (m->health >= 0x881) { if (m->health > 0x880) {
m->health = 0x880; m->health = 0x880;
} }
if (m->health < 0x100) { if (m->health < 0x100) {
@ -1655,7 +1651,7 @@ void update_mario_info_for_cam(struct MarioState *m) {
vec3s_copy(m->statusForCamera->faceAngle, m->faceAngle); vec3s_copy(m->statusForCamera->faceAngle, m->faceAngle);
if ((m->flags & MARIO_UNKNOWN_25) == 0) { if (!(m->flags & MARIO_UNKNOWN_25)) {
vec3f_copy(m->statusForCamera->pos, m->pos); vec3f_copy(m->statusForCamera->pos, m->pos);
} }
} }
@ -1716,23 +1712,21 @@ u32 update_and_return_cap_flags(struct MarioState *m) {
if (m->capTimer == 0) { if (m->capTimer == 0) {
stop_cap_music(); stop_cap_music();
m->flags &= ~(MARIO_VANISH_CAP | MARIO_METAL_CAP | MARIO_WING_CAP); m->flags &= ~MARIO_SPECIAL_CAPS;
if ((m->flags & (MARIO_NORMAL_CAP | MARIO_VANISH_CAP | MARIO_METAL_CAP | MARIO_WING_CAP)) if (!(m->flags & MARIO_CAPS)) {
== 0) {
m->flags &= ~MARIO_CAP_ON_HEAD; m->flags &= ~MARIO_CAP_ON_HEAD;
} }
} }
if (m->capTimer == 0x3C) { if (m->capTimer == 60) {
fadeout_cap_music(); fadeout_cap_music();
} }
// This code flickers the cap through a long binary string, increasing in how // This code flickers the cap through a long binary string, increasing in how
// common it flickers near the end. // common it flickers near the end.
if ((m->capTimer < 0x40) && ((1ULL << m->capTimer) & sCapFlickerFrames)) { if ((m->capTimer < 64) && ((1ULL << m->capTimer) & sCapFlickerFrames)) {
flags &= ~(MARIO_VANISH_CAP | MARIO_METAL_CAP | MARIO_WING_CAP); flags &= ~MARIO_SPECIAL_CAPS;
if ((flags & (MARIO_NORMAL_CAP | MARIO_VANISH_CAP | MARIO_METAL_CAP | MARIO_WING_CAP)) if (!(flags & MARIO_CAPS)) {
== 0) {
flags &= ~MARIO_CAP_ON_HEAD; flags &= ~MARIO_CAP_ON_HEAD;
} }
} }
@ -1760,13 +1754,11 @@ void mario_update_hitbox_and_cap_model(struct MarioState *m) {
bodyState->modelState |= MODEL_STATE_METAL; bodyState->modelState |= MODEL_STATE_METAL;
} }
if (m->invincTimer >= 3) { //! (Pause buffered hitstun) Since the global timer increments while paused,
//! (Pause buffered hitstun) Since the global timer increments while paused, // this can be paused through to give continual invisibility. This leads to
// this can be paused through to give continual invisibility. This leads to // no interaction with objects.
// no interaction with objects. if ((m->invincTimer >= 3) && (gGlobalTimer & 1)) {
if (gGlobalTimer & 1) { m->marioObj->header.gfx.node.flags |= GRAPH_RENDER_INVISIBLE;
m->marioObj->header.gfx.node.flags |= GRAPH_RENDER_INVISIBLE;
}
} }
if (flags & MARIO_CAP_IN_HAND) { if (flags & MARIO_CAP_IN_HAND) {
@ -1809,7 +1801,7 @@ static void debug_update_mario_cap(u16 button, s32 flags, u16 capTimer, u16 capM
// (which is also what other debug functions do), // (which is also what other debug functions do),
// so likely debug behavior rather than unused behavior. // so likely debug behavior rather than unused behavior.
if ((gPlayer1Controller->buttonDown & Z_TRIG) && (gPlayer1Controller->buttonPressed & button) if ((gPlayer1Controller->buttonDown & Z_TRIG) && (gPlayer1Controller->buttonPressed & button)
&& ((gMarioState->flags & flags) == 0)) { && !(gMarioState->flags & flags)) {
gMarioState->flags |= (flags + MARIO_CAP_ON_HEAD); gMarioState->flags |= (flags + MARIO_CAP_ON_HEAD);
if (capTimer > gMarioState->capTimer) { if (capTimer > gMarioState->capTimer) {
@ -2121,7 +2113,7 @@ static void init_single_mario(struct MarioState* m) {
m->area = gCurrentArea; m->area = gCurrentArea;
m->marioObj = gMarioObjects[m->playerIndex]; m->marioObj = gMarioObjects[m->playerIndex];
if (m->marioObj == NULL) { return; } if (m->marioObj == NULL) { return; }
m->marioObj->header.gfx.unk38.animID = -1; m->marioObj->header.gfx.animInfo.animID = -1;
vec3s_copy(m->faceAngle, spawnInfo->startAngle); vec3s_copy(m->faceAngle, spawnInfo->startAngle);
vec3s_set(m->angleVel, 0, 0, 0); vec3s_set(m->angleVel, 0, 0, 0);
vec3s_to_vec3f(m->pos, spawnInfo->startPos); vec3s_to_vec3f(m->pos, spawnInfo->startPos);

View file

@ -2,7 +2,6 @@
#include "sm64.h" #include "sm64.h"
#include "area.h" #include "area.h"
#include "audio/data.h"
#include "audio/external.h" #include "audio/external.h"
#include "camera.h" #include "camera.h"
#include "engine/graph_node.h" #include "engine/graph_node.h"
@ -25,7 +24,7 @@
#include "pc/lua/smlua.h" #include "pc/lua/smlua.h"
void play_flip_sounds(struct MarioState *m, s16 frame1, s16 frame2, s16 frame3) { void play_flip_sounds(struct MarioState *m, s16 frame1, s16 frame2, s16 frame3) {
s32 animFrame = m->marioObj->header.gfx.unk38.animFrame; s32 animFrame = m->marioObj->header.gfx.animInfo.animFrame;
if (animFrame == frame1 || animFrame == frame2 || animFrame == frame3) { if (animFrame == frame1 || animFrame == frame2 || animFrame == frame3) {
play_sound(SOUND_ACTION_SPIN, m->marioObj->header.gfx.cameraToObject); play_sound(SOUND_ACTION_SPIN, m->marioObj->header.gfx.cameraToObject);
} }
@ -609,9 +608,9 @@ s32 act_side_flip(struct MarioState *m) {
m->marioObj->header.gfx.angle[1] += 0x8000; m->marioObj->header.gfx.angle[1] += 0x8000;
} }
// (this need to be on one line to match on PAL) // This must be one line to match on -O2
// clang-format off // clang-format off
if (m->marioObj->header.gfx.unk38.animFrame == 6) play_sound(SOUND_ACTION_SIDE_FLIP_UNK, m->marioObj->header.gfx.cameraToObject); if (m->marioObj->header.gfx.animInfo.animFrame == 6) play_sound(SOUND_ACTION_SIDE_FLIP_UNK, m->marioObj->header.gfx.cameraToObject);
// clang-format on // clang-format on
return FALSE; return FALSE;
} }
@ -938,7 +937,7 @@ s32 act_ground_pound(struct MarioState *m) {
} }
m->actionTimer++; m->actionTimer++;
if (m->actionTimer >= m->marioObj->header.gfx.unk38.curAnim->unk08 + 4) { if (m->actionTimer >= m->marioObj->header.gfx.animInfo.curAnim->loopEnd + 4) {
play_character_sound(m, CHAR_SOUND_GROUND_POUND_WAH); play_character_sound(m, CHAR_SOUND_GROUND_POUND_WAH);
m->actionState = 1; m->actionState = 1;
} }
@ -1158,7 +1157,7 @@ s32 check_wall_kick(struct MarioState *m) {
s32 act_backward_air_kb(struct MarioState *m) { s32 act_backward_air_kb(struct MarioState *m) {
if (check_wall_kick(m)) { if (check_wall_kick(m)) {
return 1; return TRUE;
} }
#ifndef VERSION_JP #ifndef VERSION_JP
@ -1172,7 +1171,7 @@ s32 act_backward_air_kb(struct MarioState *m) {
s32 act_forward_air_kb(struct MarioState *m) { s32 act_forward_air_kb(struct MarioState *m) {
if (check_wall_kick(m)) { if (check_wall_kick(m)) {
return 1; return TRUE;
} }
#ifndef VERSION_JP #ifndef VERSION_JP
@ -1249,7 +1248,7 @@ s32 act_thrown_forward(struct MarioState *m) {
s32 act_soft_bonk(struct MarioState *m) { s32 act_soft_bonk(struct MarioState *m) {
if (check_wall_kick(m)) { if (check_wall_kick(m)) {
return 1; return TRUE;
} }
#ifndef VERSION_JP #ifndef VERSION_JP
@ -1348,10 +1347,9 @@ s32 act_air_hit_wall(struct MarioState *m) {
//! Missing return statement. The returned value is the result of the call //! Missing return statement. The returned value is the result of the call
// to set_mario_animation. In practice, this value is nonzero. // to set_mario_animation. In practice, this value is nonzero.
// This results in this action "cancelling" into itself. It is supposed to // This results in this action "cancelling" into itself. It is supposed to
// execute three times, each on a separate frame, but instead it executes // execute on two frames, but instead it executes twice on the same frame.
// three times on the same frame.
// This results in firsties only being possible for a single frame, instead // This results in firsties only being possible for a single frame, instead
// of three. // of two.
} }
s32 act_forward_rollout(struct MarioState *m) { s32 act_forward_rollout(struct MarioState *m) {
@ -1430,7 +1428,7 @@ s32 act_backward_rollout(struct MarioState *m) {
break; break;
} }
if (m->actionState == 1 && m->marioObj->header.gfx.unk38.animFrame == 2) { if (m->actionState == 1 && m->marioObj->header.gfx.animInfo.animFrame == 2) {
m->actionState = 2; m->actionState = 2;
} }
return FALSE; return FALSE;
@ -1641,12 +1639,12 @@ s32 act_jump_kick(struct MarioState *m) {
if (m->actionState == 0) { if (m->actionState == 0) {
play_character_sound_if_no_flag(m, CHAR_SOUND_PUNCH_HOO, MARIO_ACTION_SOUND_PLAYED); play_character_sound_if_no_flag(m, CHAR_SOUND_PUNCH_HOO, MARIO_ACTION_SOUND_PLAYED);
m->marioObj->header.gfx.unk38.animID = -1; m->marioObj->header.gfx.animInfo.animID = -1;
set_mario_animation(m, MARIO_ANIM_AIR_KICK); set_mario_animation(m, MARIO_ANIM_AIR_KICK);
m->actionState = 1; m->actionState = 1;
} }
animFrame = m->marioObj->header.gfx.unk38.animFrame; animFrame = m->marioObj->header.gfx.animInfo.animFrame;
if (animFrame == 0) { if (animFrame == 0) {
m->marioBodyState->punchState = (2 << 6) | 6; m->marioBodyState->punchState = (2 << 6) | 6;
} }
@ -1819,7 +1817,7 @@ s32 act_flying(struct MarioState *m) {
set_mario_animation(m, MARIO_ANIM_FLY_FROM_CANNON); set_mario_animation(m, MARIO_ANIM_FLY_FROM_CANNON);
} else { } else {
set_mario_animation(m, MARIO_ANIM_FORWARD_SPINNING_FLIP); set_mario_animation(m, MARIO_ANIM_FORWARD_SPINNING_FLIP);
if (m->marioObj->header.gfx.unk38.animFrame == 1) { if (m->marioObj->header.gfx.animInfo.animFrame == 1) {
play_sound(SOUND_ACTION_SPIN, m->marioObj->header.gfx.cameraToObject); play_sound(SOUND_ACTION_SPIN, m->marioObj->header.gfx.cameraToObject);
} }
} }
@ -2014,7 +2012,7 @@ s32 act_flying_triple_jump(struct MarioState *m) {
if (m->actionState == 0) { if (m->actionState == 0) {
set_mario_animation(m, MARIO_ANIM_TRIPLE_JUMP_FLY); set_mario_animation(m, MARIO_ANIM_TRIPLE_JUMP_FLY);
if (m->marioObj->header.gfx.unk38.animFrame == 7) { if (m->marioObj->header.gfx.animInfo.animFrame == 7) {
play_sound(SOUND_ACTION_SPIN, m->marioObj->header.gfx.cameraToObject); play_sound(SOUND_ACTION_SPIN, m->marioObj->header.gfx.cameraToObject);
} }
@ -2025,7 +2023,7 @@ s32 act_flying_triple_jump(struct MarioState *m) {
} }
} }
if (m->actionState == 1 && m->marioObj->header.gfx.unk38.animFrame == 1) { if (m->actionState == 1 && m->marioObj->header.gfx.animInfo.animFrame == 1) {
play_sound(SOUND_ACTION_SPIN, m->marioObj->header.gfx.cameraToObject); play_sound(SOUND_ACTION_SPIN, m->marioObj->header.gfx.cameraToObject);
} }
@ -2091,7 +2089,7 @@ s32 act_vertical_wind(struct MarioState *m) {
play_character_sound_if_no_flag(m, CHAR_SOUND_HERE_WE_GO, MARIO_MARIO_SOUND_PLAYED); play_character_sound_if_no_flag(m, CHAR_SOUND_HERE_WE_GO, MARIO_MARIO_SOUND_PLAYED);
if (m->actionState == 0) { if (m->actionState == 0) {
set_mario_animation(m, MARIO_ANIM_FORWARD_SPINNING_FLIP); set_mario_animation(m, MARIO_ANIM_FORWARD_SPINNING_FLIP);
if (m->marioObj->header.gfx.unk38.animFrame == 1) { if (m->marioObj->header.gfx.animInfo.animFrame == 1) {
play_sound(SOUND_ACTION_SPIN, m->marioObj->header.gfx.cameraToObject); play_sound(SOUND_ACTION_SPIN, m->marioObj->header.gfx.cameraToObject);
queue_rumble_data_mario(m, 8, 80); queue_rumble_data_mario(m, 8, 80);
} }

View file

@ -25,13 +25,13 @@
#include "pc/network/network.h" #include "pc/network/network.h"
#include "pc/lua/smlua.h" #include "pc/lua/smlua.h"
#define POLE_NONE 0 #define POLE_NONE 0
#define POLE_TOUCHED_FLOOR 1 #define POLE_TOUCHED_FLOOR 1
#define POLE_FELL_OFF 2 #define POLE_FELL_OFF 2
#define HANG_NONE 0 #define HANG_NONE 0
#define HANG_HIT_CEIL_OR_OOB 1 #define HANG_HIT_CEIL_OR_OOB 1
#define HANG_LEFT_CEIL 2 #define HANG_LEFT_CEIL 2
void add_tree_leaf_particles(struct MarioState *m) { void add_tree_leaf_particles(struct MarioState *m) {
f32 leafHeight; f32 leafHeight;
@ -156,7 +156,7 @@ s32 act_holding_pole(struct MarioState *m) {
if (m->controller->stickY > 16.0f) { if (m->controller->stickY > 16.0f) {
f32 poleTop = m->usedObj->hitboxHeight - 100.0f; f32 poleTop = m->usedObj->hitboxHeight - 100.0f;
void *poleBehavior = virtual_to_segmented(0x13, m->usedObj->behavior); const BehaviorScript *poleBehavior = virtual_to_segmented(0x13, m->usedObj->behavior);
if (marioObj->oMarioPolePos < poleTop - 0.4f) { if (marioObj->oMarioPolePos < poleTop - 0.4f) {
return set_mario_action(m, ACT_CLIMBING_POLE, 0); return set_mario_action(m, ACT_CLIMBING_POLE, 0);
@ -264,7 +264,7 @@ s32 act_grab_pole_fast(struct MarioState *m) {
set_mario_animation(m, MARIO_ANIM_GRAB_POLE_SWING_PART1); set_mario_animation(m, MARIO_ANIM_GRAB_POLE_SWING_PART1);
} else { } else {
set_mario_animation(m, MARIO_ANIM_GRAB_POLE_SWING_PART2); set_mario_animation(m, MARIO_ANIM_GRAB_POLE_SWING_PART2);
if (is_anim_at_end(m) != 0) { if (is_anim_at_end(m)) {
marioObj->oMarioPoleYawVel = 0; marioObj->oMarioPoleYawVel = 0;
set_mario_action(m, ACT_HOLDING_POLE, 0); set_mario_action(m, ACT_HOLDING_POLE, 0);
} }
@ -287,7 +287,7 @@ s32 act_top_of_pole_transition(struct MarioState *m) {
} }
} else { } else {
set_mario_animation(m, MARIO_ANIM_RETURN_FROM_HANDSTAND); set_mario_animation(m, MARIO_ANIM_RETURN_FROM_HANDSTAND);
if (m->marioObj->header.gfx.unk38.animFrame == 0) { if (m->marioObj->header.gfx.animInfo.animFrame == 0) {
return set_mario_action(m, ACT_HOLDING_POLE, 0); return set_mario_action(m, ACT_HOLDING_POLE, 0);
} }
} }
@ -481,7 +481,7 @@ s32 act_hang_moving(struct MarioState *m) {
set_mario_animation(m, MARIO_ANIM_MOVE_ON_WIRE_NET_LEFT); set_mario_animation(m, MARIO_ANIM_MOVE_ON_WIRE_NET_LEFT);
} }
if (m->marioObj->header.gfx.unk38.animFrame == 12) { if (m->marioObj->header.gfx.animInfo.animFrame == 12) {
play_sound(SOUND_ACTION_HANGING_STEP, m->marioObj->header.gfx.cameraToObject); play_sound(SOUND_ACTION_HANGING_STEP, m->marioObj->header.gfx.cameraToObject);
queue_rumble_data_mario(m, 5, 30); queue_rumble_data_mario(m, 5, 30);
} }
@ -581,7 +581,7 @@ s32 act_ledge_grab(struct MarioState *m) {
return let_go_of_ledge(m); return let_go_of_ledge(m);
} }
#ifdef VERSION_EU #ifdef VERSION_EU
// On PAL, you can't slow climb up ledges while holding A. // On EU, you can't slow climb up ledges while holding A.
if (m->actionTimer == 10 && (m->input & INPUT_NONZERO_ANALOG) && !(m->input & INPUT_A_DOWN)) if (m->actionTimer == 10 && (m->input & INPUT_NONZERO_ANALOG) && !(m->input & INPUT_A_DOWN))
#else #else
if (m->actionTimer == 10 && (m->input & INPUT_NONZERO_ANALOG)) if (m->actionTimer == 10 && (m->input & INPUT_NONZERO_ANALOG))
@ -630,7 +630,7 @@ s32 act_ledge_climb_slow(struct MarioState *m) {
update_ledge_climb(m, MARIO_ANIM_SLOW_LEDGE_GRAB, ACT_IDLE); update_ledge_climb(m, MARIO_ANIM_SLOW_LEDGE_GRAB, ACT_IDLE);
update_ledge_climb_camera(m); update_ledge_climb_camera(m);
if (m->marioObj->header.gfx.unk38.animFrame == 17) { if (m->marioObj->header.gfx.animInfo.animFrame == 17) {
m->action = ACT_LEDGE_CLIMB_SLOW_2; m->action = ACT_LEDGE_CLIMB_SLOW_2;
} }
@ -659,7 +659,7 @@ s32 act_ledge_climb_fast(struct MarioState *m) {
update_ledge_climb(m, MARIO_ANIM_FAST_LEDGE_GRAB, ACT_IDLE); update_ledge_climb(m, MARIO_ANIM_FAST_LEDGE_GRAB, ACT_IDLE);
if (m->marioObj->header.gfx.unk38.animFrame == 8) { if (m->marioObj->header.gfx.animInfo.animFrame == 8) {
play_mario_landing_sound(m, SOUND_ACTION_TERRAIN_LANDING); play_mario_landing_sound(m, SOUND_ACTION_TERRAIN_LANDING);
} }
update_ledge_climb_camera(m); update_ledge_climb_camera(m);

View file

@ -3,7 +3,6 @@
#include "prevent_bss_reordering.h" #include "prevent_bss_reordering.h"
#include "sm64.h" #include "sm64.h"
#include "area.h" #include "area.h"
#include "audio/data.h"
#include "audio/external.h" #include "audio/external.h"
#include "behavior_data.h" #include "behavior_data.h"
#include "camera.h" #include "camera.h"
@ -56,7 +55,7 @@ static s8 D_8032CBE4 = 0;
static s8 D_8032CBE8 = 0; static s8 D_8032CBE8 = 0;
static s8 D_8032CBEC[7] = { 2, 3, 2, 1, 2, 3, 2 }; static s8 D_8032CBEC[7] = { 2, 3, 2, 1, 2, 3, 2 };
static u8 sStarsNeededForDialog[6] = { 1, 3, 8, 30, 50, 70 }; static u8 sStarsNeededForDialog[] = { 1, 3, 8, 30, 50, 70 };
static BehaviorScript* localDialogNPCBehavior = NULL; static BehaviorScript* localDialogNPCBehavior = NULL;
@ -244,7 +243,7 @@ s32 get_star_collection_dialog(struct MarioState *m) {
s32 dialogID = 0; s32 dialogID = 0;
s32 numStarsRequired; s32 numStarsRequired;
for (i = 0; i < 6; i++) { for (i = 0; i < ARRAY_COUNT(sStarsNeededForDialog); i++) {
numStarsRequired = sStarsNeededForDialog[i]; numStarsRequired = sStarsNeededForDialog[i];
if (m->prevNumStarsForDialog < numStarsRequired && m->numStars >= numStarsRequired) { if (m->prevNumStarsForDialog < numStarsRequired && m->numStars >= numStarsRequired) {
dialogID = i + DIALOG_141; dialogID = i + DIALOG_141;
@ -462,7 +461,7 @@ s32 act_reading_npc_dialog(struct MarioState *m) {
m->actionState++; m->actionState++;
} }
if (m->playerIndex != 0 && gCurrentObject->header.gfx.unk38.animID == -1) { if (m->playerIndex != 0 && gCurrentObject->header.gfx.animInfo.animID == -1) {
// set animation // set animation
set_mario_animation(m, m->heldObj == NULL ? MARIO_ANIM_FIRST_PERSON set_mario_animation(m, m->heldObj == NULL ? MARIO_ANIM_FIRST_PERSON
: MARIO_ANIM_IDLE_WITH_LIGHT_OBJ); : MARIO_ANIM_IDLE_WITH_LIGHT_OBJ);
@ -473,8 +472,8 @@ s32 act_reading_npc_dialog(struct MarioState *m) {
// puts Mario in a state where he's waiting for (npc) dialog; doesn't do much // puts Mario in a state where he's waiting for (npc) dialog; doesn't do much
s32 act_waiting_for_dialog(struct MarioState *m) { s32 act_waiting_for_dialog(struct MarioState *m) {
set_mario_animation(m, set_mario_animation(m, m->heldObj == NULL ? MARIO_ANIM_FIRST_PERSON
m->heldObj == NULL ? MARIO_ANIM_FIRST_PERSON : MARIO_ANIM_IDLE_WITH_LIGHT_OBJ); : MARIO_ANIM_IDLE_WITH_LIGHT_OBJ);
vec3f_copy(m->marioObj->header.gfx.pos, m->pos); vec3f_copy(m->marioObj->header.gfx.pos, m->pos);
vec3s_set(m->marioObj->header.gfx.angle, 0, m->faceAngle[1], 0); vec3s_set(m->marioObj->header.gfx.angle, 0, m->faceAngle[1], 0);
return FALSE; return FALSE;
@ -533,8 +532,8 @@ s32 act_reading_automatic_dialog(struct MarioState *m) {
// finished action // finished action
else if (m->actionState == 25) { else if (m->actionState == 25) {
disable_time_stop(); disable_time_stop();
if (gShouldNotPlayCastleMusic) { if (gNeverEnteredCastle) {
gShouldNotPlayCastleMusic = FALSE; gNeverEnteredCastle = FALSE;
play_cutscene_music(SEQUENCE_ARGS(0, SEQ_LEVEL_INSIDE_CASTLE)); play_cutscene_music(SEQUENCE_ARGS(0, SEQ_LEVEL_INSIDE_CASTLE));
} }
if (m->prevAction == ACT_STAR_DANCE_WATER) { if (m->prevAction == ACT_STAR_DANCE_WATER) {
@ -601,7 +600,6 @@ s32 act_reading_sign(struct MarioState *m) {
return FALSE; return FALSE;
} }
// debug free move action
s32 act_debug_free_move(struct MarioState *m) { s32 act_debug_free_move(struct MarioState *m) {
struct Surface *surf; struct Surface *surf;
f32 floorHeight; f32 floorHeight;
@ -653,7 +651,6 @@ s32 act_debug_free_move(struct MarioState *m) {
return FALSE; return FALSE;
} }
// star dance handler
void general_star_dance_handler(struct MarioState *m, s32 isInWater) { void general_star_dance_handler(struct MarioState *m, s32 isInWater) {
s32 dialogID; s32 dialogID;
if (m->actionState == 0) { if (m->actionState == 0) {
@ -761,7 +758,6 @@ s32 act_fall_after_star_grab(struct MarioState *m) {
return FALSE; return FALSE;
} }
// general death hander
s32 common_death_handler(struct MarioState *m, s32 animation, s32 frameToDeathWarp) { s32 common_death_handler(struct MarioState *m, s32 animation, s32 frameToDeathWarp) {
s32 animFrame = set_mario_animation(m, animation); s32 animFrame = set_mario_animation(m, animation);
if (animFrame == frameToDeathWarp) { if (animFrame == frameToDeathWarp) {
@ -783,7 +779,7 @@ s32 act_standing_death(struct MarioState *m) {
play_character_sound_if_no_flag(m, CHAR_SOUND_DYING, MARIO_ACTION_SOUND_PLAYED); play_character_sound_if_no_flag(m, CHAR_SOUND_DYING, MARIO_ACTION_SOUND_PLAYED);
common_death_handler(m, MARIO_ANIM_DYING_FALL_OVER, 80); common_death_handler(m, MARIO_ANIM_DYING_FALL_OVER, 80);
if (m->marioObj->header.gfx.unk38.animFrame == 77) { if (m->marioObj->header.gfx.animInfo.animFrame == 77) {
play_mario_landing_sound(m, SOUND_ACTION_TERRAIN_BODY_HIT_GROUND); play_mario_landing_sound(m, SOUND_ACTION_TERRAIN_BODY_HIT_GROUND);
} }
return FALSE; return FALSE;
@ -888,12 +884,12 @@ s32 act_unlocking_key_door(struct MarioState *m) {
m->faceAngle[1] += 0x8000; m->faceAngle[1] += 0x8000;
} }
if ((m->actionTimer == 0) || (m->playerIndex != 0 && gCurrentObject->header.gfx.unk38.animID == -1)) { if ((m->actionTimer == 0) || (m->playerIndex != 0 && gCurrentObject->header.gfx.animInfo.animID == -1)) {
spawn_obj_at_mario_rel_yaw(m, MODEL_BOWSER_KEY_CUTSCENE, bhvBowserKeyUnlockDoor, 0); spawn_obj_at_mario_rel_yaw(m, MODEL_BOWSER_KEY_CUTSCENE, bhvBowserKeyUnlockDoor, 0);
set_mario_animation(m, MARIO_ANIM_UNLOCK_DOOR); set_mario_animation(m, MARIO_ANIM_UNLOCK_DOOR);
} }
switch (m->marioObj->header.gfx.unk38.animFrame) { switch (m->marioObj->header.gfx.animInfo.animFrame) {
case 79: case 79:
play_sound(SOUND_GENERAL_DOOR_INSERT_KEY, m->marioObj->header.gfx.cameraToObject); play_sound(SOUND_GENERAL_DOOR_INSERT_KEY, m->marioObj->header.gfx.cameraToObject);
break; break;
@ -969,7 +965,6 @@ s32 act_unlocking_star_door(struct MarioState *m) {
return FALSE; return FALSE;
} }
// not sure what kind of door this is
s32 act_entering_star_door(struct MarioState *m) { s32 act_entering_star_door(struct MarioState *m) {
f32 targetDX; f32 targetDX;
f32 targetDZ; f32 targetDZ;
@ -1064,13 +1059,11 @@ s32 act_going_through_door(struct MarioState *m) {
if (m->actionTimer == 16) { if (m->actionTimer == 16) {
level_trigger_warp(m, WARP_OP_WARP_DOOR); level_trigger_warp(m, WARP_OP_WARP_DOOR);
} }
} else { } else if (is_anim_at_end(m)) {
if (is_anim_at_end(m)) { if (m->actionArg & 2) {
if (m->actionArg & 2) { m->faceAngle[1] += 0x8000;
m->faceAngle[1] += 0x8000;
}
set_mario_action(m, ACT_IDLE, 0);
} }
set_mario_action(m, ACT_IDLE, 0);
} }
m->actionTimer++; m->actionTimer++;
@ -1090,7 +1083,7 @@ s32 act_warp_door_spawn(struct MarioState *m) {
} }
} else if (m->usedObj == NULL || (m->usedObj->oAction == 0 || m->usedObj->oAction == 100)) { } else if (m->usedObj == NULL || (m->usedObj->oAction == 0 || m->usedObj->oAction == 100)) {
if (m->playerIndex == 0) { if (m->playerIndex == 0) {
if (gShouldNotPlayCastleMusic == TRUE && gCurrLevelNum == LEVEL_CASTLE) { if (gNeverEnteredCastle == TRUE && gCurrLevelNum == LEVEL_CASTLE) {
set_mario_action(m, ACT_READING_AUTOMATIC_DIALOG, DIALOG_021); set_mario_action(m, ACT_READING_AUTOMATIC_DIALOG, DIALOG_021);
} else { } else {
set_mario_action(m, ACT_IDLE, 0); set_mario_action(m, ACT_IDLE, 0);
@ -1477,7 +1470,7 @@ s32 act_bbh_enter_spin(struct MarioState *m) {
m->actionState = 4; m->actionState = 4;
} }
if (m->actionState == 2) { if (m->actionState == 2) {
if (m->marioObj->header.gfx.unk38.animFrame == 0) { if (m->marioObj->header.gfx.animInfo.animFrame == 0) {
m->actionState = 3; m->actionState = 3;
} }
} else { } else {
@ -1666,7 +1659,7 @@ s32 act_squished(struct MarioState *m) {
} }
// Both of the 1.8's are really floats, but one of them has to // Both of the 1.8's are really floats, but one of them has to
// be written as a double for this to match on EU. // be written as a double for this to match on -O2.
vec3f_set(m->marioObj->header.gfx.scale, 1.8, 0.05f, 1.8f); vec3f_set(m->marioObj->header.gfx.scale, 1.8, 0.05f, 1.8f);
queue_rumble_data_mario(m, 10, 80); queue_rumble_data_mario(m, 10, 80);
m->actionState = 1; m->actionState = 1;
@ -2814,7 +2807,7 @@ static s32 act_credits_cutscene(struct MarioState *m) {
} }
if (m->actionTimer++ == TIMER_CREDITS_WARP && m->playerIndex == 0) { if (m->actionTimer++ == TIMER_CREDITS_WARP && m->playerIndex == 0) {
level_trigger_warp(m, 24); level_trigger_warp(m, WARP_OP_CREDITS_NEXT);
} }
m->marioObj->header.gfx.angle[1] += (gCurrCreditsEntry->unk02 & 0xC0) << 8; m->marioObj->header.gfx.angle[1] += (gCurrCreditsEntry->unk02 & 0xC0) << 8;
@ -2941,10 +2934,8 @@ s32 mario_execute_cutscene_action(struct MarioState *m) {
/* clang-format on */ /* clang-format on */
} }
if (!cancel) { if (!cancel && (m->input & INPUT_IN_WATER)) {
if (m->input & INPUT_IN_WATER) { m->particleFlags |= PARTICLE_IDLE_WATER_WAVE;
m->particleFlags |= PARTICLE_IDLE_WATER_WAVE;
}
} }
return cancel; return cancel;

View file

@ -75,14 +75,14 @@ s16 tilt_body_running(struct MarioState *m) {
void play_step_sound(struct MarioState *m, s16 frame1, s16 frame2) { void play_step_sound(struct MarioState *m, s16 frame1, s16 frame2) {
if (is_anim_past_frame(m, frame1) || is_anim_past_frame(m, frame2)) { if (is_anim_past_frame(m, frame1) || is_anim_past_frame(m, frame2)) {
if (m->flags & MARIO_METAL_CAP) { if (m->flags & MARIO_METAL_CAP) {
if (m->marioObj->header.gfx.unk38.animID == MARIO_ANIM_TIPTOE) { if (m->marioObj->header.gfx.animInfo.animID == MARIO_ANIM_TIPTOE) {
play_sound_and_spawn_particles(m, SOUND_ACTION_METAL_STEP_TIPTOE, 0); play_sound_and_spawn_particles(m, SOUND_ACTION_METAL_STEP_TIPTOE, 0);
} else { } else {
play_sound_and_spawn_particles(m, SOUND_ACTION_METAL_STEP, 0); play_sound_and_spawn_particles(m, SOUND_ACTION_METAL_STEP, 0);
} }
} else if (m->quicksandDepth > 50.0f) { } else if (m->quicksandDepth > 50.0f) {
play_sound(SOUND_ACTION_QUICKSAND_STEP, m->marioObj->header.gfx.cameraToObject); play_sound(SOUND_ACTION_QUICKSAND_STEP, m->marioObj->header.gfx.cameraToObject);
} else if (m->marioObj->header.gfx.unk38.animID == MARIO_ANIM_TIPTOE) { } else if (m->marioObj->header.gfx.animInfo.animID == MARIO_ANIM_TIPTOE) {
play_sound_and_spawn_particles(m, SOUND_ACTION_TERRAIN_STEP_TIPTOE, 0); play_sound_and_spawn_particles(m, SOUND_ACTION_TERRAIN_STEP_TIPTOE, 0);
} else { } else {
play_sound_and_spawn_particles(m, SOUND_ACTION_TERRAIN_STEP, 0); play_sound_and_spawn_particles(m, SOUND_ACTION_TERRAIN_STEP, 0);
@ -119,22 +119,20 @@ void check_ledge_climb_down(struct MarioState *m) {
if (find_wall_collisions(&wallCols) != 0) { if (find_wall_collisions(&wallCols) != 0) {
floorHeight = find_floor(wallCols.x, wallCols.y, wallCols.z, &floor); floorHeight = find_floor(wallCols.x, wallCols.y, wallCols.z, &floor);
if (floor != NULL) { if (floor != NULL && (wallCols.y - floorHeight > 160.0f)) {
if (wallCols.y - floorHeight > 160.0f) { wall = wallCols.walls[wallCols.numWalls - 1];
wall = wallCols.walls[wallCols.numWalls - 1]; wallAngle = atan2s(wall->normal.z, wall->normal.x);
wallAngle = atan2s(wall->normal.z, wall->normal.x); wallDYaw = wallAngle - m->faceAngle[1];
wallDYaw = wallAngle - m->faceAngle[1];
if (wallDYaw > -0x4000 && wallDYaw < 0x4000) { if (wallDYaw > -0x4000 && wallDYaw < 0x4000) {
m->pos[0] = wallCols.x - 20.0f * wall->normal.x; m->pos[0] = wallCols.x - 20.0f * wall->normal.x;
m->pos[2] = wallCols.z - 20.0f * wall->normal.z; m->pos[2] = wallCols.z - 20.0f * wall->normal.z;
m->faceAngle[0] = 0; m->faceAngle[0] = 0;
m->faceAngle[1] = wallAngle + 0x8000; m->faceAngle[1] = wallAngle + 0x8000;
set_mario_action(m, ACT_LEDGE_CLIMB_DOWN, 0); set_mario_action(m, ACT_LEDGE_CLIMB_DOWN, 0);
set_mario_animation(m, MARIO_ANIM_CLIMB_DOWN_LEDGE); set_mario_animation(m, MARIO_ANIM_CLIMB_DOWN_LEDGE);
}
} }
} }
} }
@ -160,7 +158,7 @@ s32 set_triple_jump_action(struct MarioState *m, UNUSED u32 action, UNUSED u32 a
return set_mario_action(m, ACT_JUMP, 0); return set_mario_action(m, ACT_JUMP, 0);
} }
return 0; return FALSE;
} }
void update_sliding_angle(struct MarioState *m, f32 accel, f32 lossFactor) { void update_sliding_angle(struct MarioState *m, f32 accel, f32 lossFactor) {
@ -709,7 +707,7 @@ void push_or_sidle_wall(struct MarioState *m, Vec3f startPos) {
set_mario_anim_with_accel(m, MARIO_ANIM_SIDESTEP_LEFT, val04); set_mario_anim_with_accel(m, MARIO_ANIM_SIDESTEP_LEFT, val04);
} }
if (m->marioObj->header.gfx.unk38.animFrame < 20) { if (m->marioObj->header.gfx.animInfo.animFrame < 20) {
play_sound(SOUND_MOVING_TERRAIN_SLIDE + m->terrainSoundAddend, m->marioObj->header.gfx.cameraToObject); play_sound(SOUND_MOVING_TERRAIN_SLIDE + m->terrainSoundAddend, m->marioObj->header.gfx.cameraToObject);
m->particleFlags |= PARTICLE_DUST; m->particleFlags |= PARTICLE_DUST;
} }
@ -724,7 +722,7 @@ void push_or_sidle_wall(struct MarioState *m, Vec3f startPos) {
void tilt_body_walking(struct MarioState *m, s16 startYaw) { void tilt_body_walking(struct MarioState *m, s16 startYaw) {
struct MarioBodyState *val0C = m->marioBodyState; struct MarioBodyState *val0C = m->marioBodyState;
UNUSED struct Object *marioObj = m->marioObj; UNUSED struct Object *marioObj = m->marioObj;
s16 animID = m->marioObj->header.gfx.unk38.animID; s16 animID = m->marioObj->header.gfx.animInfo.animID;
s16 dYaw; s16 dYaw;
s16 val02; s16 val02;
s16 val00; s16 val00;
@ -1215,7 +1213,7 @@ s32 act_hold_decelerating(struct MarioState *m) {
} }
s32 act_riding_shell_ground(struct MarioState *m) { s32 act_riding_shell_ground(struct MarioState *m) {
/*06*/ s16 startYaw = m->faceAngle[1]; s16 startYaw = m->faceAngle[1];
if (m->input & INPUT_A_PRESSED) { if (m->input & INPUT_A_PRESSED) {
return set_mario_action(m, ACT_RIDING_SHELL_JUMP, 0); return set_mario_action(m, ACT_RIDING_SHELL_JUMP, 0);
@ -1376,9 +1374,9 @@ void tilt_body_butt_slide(struct MarioState *m) {
} }
void common_slide_action(struct MarioState *m, u32 endAction, u32 airAction, s32 animation) { void common_slide_action(struct MarioState *m, u32 endAction, u32 airAction, s32 animation) {
Vec3f val14; Vec3f pos;
vec3f_copy(val14, m->pos); vec3f_copy(pos, m->pos);
play_sound(SOUND_MOVING_TERRAIN_SLIDE + m->terrainSoundAddend, m->marioObj->header.gfx.cameraToObject); play_sound(SOUND_MOVING_TERRAIN_SLIDE + m->terrainSoundAddend, m->marioObj->header.gfx.cameraToObject);
reset_rumble_timers(m); reset_rumble_timers(m);
@ -1602,7 +1600,7 @@ s32 act_dive_slide(struct MarioState *m) {
} }
s32 common_ground_knockback_action(struct MarioState *m, s32 animation, s32 arg2, s32 arg3, s32 arg4) { s32 common_ground_knockback_action(struct MarioState *m, s32 animation, s32 arg2, s32 arg3, s32 arg4) {
s32 val04; s32 animFrame;
if (arg3) { if (arg3) {
play_mario_heavy_landing_sound_once(m, SOUND_ACTION_TERRAIN_BODY_HIT_GROUND); play_mario_heavy_landing_sound_once(m, SOUND_ACTION_TERRAIN_BODY_HIT_GROUND);
@ -1627,8 +1625,8 @@ s32 common_ground_knockback_action(struct MarioState *m, s32 animation, s32 arg2
} }
} }
val04 = set_mario_animation(m, animation); animFrame = set_mario_animation(m, animation);
if (val04 < arg2) { if (animFrame < arg2) {
apply_landing_accel(m, 0.9f); apply_landing_accel(m, 0.9f);
} else if (m->forwardVel >= 0.0f) { } else if (m->forwardVel >= 0.0f) {
mario_set_forward_vel(m, 0.1f); mario_set_forward_vel(m, 0.1f);
@ -1653,23 +1651,23 @@ s32 common_ground_knockback_action(struct MarioState *m, s32 animation, s32 arg2
} }
} }
return val04; return animFrame;
} }
s32 act_hard_backward_ground_kb(struct MarioState *m) { s32 act_hard_backward_ground_kb(struct MarioState *m) {
s32 val04 = s32 animFrame =
common_ground_knockback_action(m, MARIO_ANIM_FALL_OVER_BACKWARDS, 0x2B, TRUE, m->actionArg); common_ground_knockback_action(m, MARIO_ANIM_FALL_OVER_BACKWARDS, 43, TRUE, m->actionArg);
if (val04 == 0x2B && m->health < 0x100) { if (animFrame == 43 && m->health < 0x100) {
set_mario_action(m, ACT_DEATH_ON_BACK, 0); set_mario_action(m, ACT_DEATH_ON_BACK, 0);
} }
#ifndef VERSION_JP #ifndef VERSION_JP
if (val04 == 0x36 && m->prevAction == ACT_SPECIAL_DEATH_EXIT) { if (animFrame == 54 && m->prevAction == ACT_SPECIAL_DEATH_EXIT) {
play_character_sound(m, CHAR_SOUND_MAMA_MIA); play_character_sound(m, CHAR_SOUND_MAMA_MIA);
} }
#endif #endif
if (val04 == 0x45) { if (animFrame == 69) {
play_mario_landing_sound_once(m, SOUND_ACTION_TERRAIN_LANDING); play_mario_landing_sound_once(m, SOUND_ACTION_TERRAIN_LANDING);
} }
@ -1677,8 +1675,9 @@ s32 act_hard_backward_ground_kb(struct MarioState *m) {
} }
s32 act_hard_forward_ground_kb(struct MarioState *m) { s32 act_hard_forward_ground_kb(struct MarioState *m) {
s32 val04 = common_ground_knockback_action(m, MARIO_ANIM_LAND_ON_STOMACH, 0x15, TRUE, m->actionArg); s32 animFrame =
if (val04 == 0x17 && m->health < 0x100) { common_ground_knockback_action(m, MARIO_ANIM_LAND_ON_STOMACH, 21, TRUE, m->actionArg);
if (animFrame == 23 && m->health < 0x100) {
set_mario_action(m, ACT_DEATH_ON_STOMACH, 0); set_mario_action(m, ACT_DEATH_ON_STOMACH, 0);
} }
@ -1686,45 +1685,46 @@ s32 act_hard_forward_ground_kb(struct MarioState *m) {
} }
s32 act_backward_ground_kb(struct MarioState *m) { s32 act_backward_ground_kb(struct MarioState *m) {
common_ground_knockback_action(m, MARIO_ANIM_BACKWARD_KB, 0x16, TRUE, m->actionArg); common_ground_knockback_action(m, MARIO_ANIM_BACKWARD_KB, 22, TRUE, m->actionArg);
return FALSE; return FALSE;
} }
s32 act_forward_ground_kb(struct MarioState *m) { s32 act_forward_ground_kb(struct MarioState *m) {
common_ground_knockback_action(m, MARIO_ANIM_FORWARD_KB, 0x14, TRUE, m->actionArg); common_ground_knockback_action(m, MARIO_ANIM_FORWARD_KB, 20, TRUE, m->actionArg);
return FALSE; return FALSE;
} }
s32 act_soft_backward_ground_kb(struct MarioState *m) { s32 act_soft_backward_ground_kb(struct MarioState *m) {
common_ground_knockback_action(m, MARIO_ANIM_SOFT_BACK_KB, 0x64, FALSE, m->actionArg); common_ground_knockback_action(m, MARIO_ANIM_SOFT_BACK_KB, 100, FALSE, m->actionArg);
return FALSE; return FALSE;
} }
s32 act_soft_forward_ground_kb(struct MarioState *m) { s32 act_soft_forward_ground_kb(struct MarioState *m) {
common_ground_knockback_action(m, MARIO_ANIM_SOFT_FRONT_KB, 0x64, FALSE, m->actionArg); common_ground_knockback_action(m, MARIO_ANIM_SOFT_FRONT_KB, 100, FALSE, m->actionArg);
return FALSE; return FALSE;
} }
s32 act_ground_bonk(struct MarioState *m) { s32 act_ground_bonk(struct MarioState *m) {
s32 val04 = common_ground_knockback_action(m, MARIO_ANIM_GROUND_BONK, 0x20, TRUE, m->actionArg); s32 animFrame =
if (val04 == 0x20) { common_ground_knockback_action(m, MARIO_ANIM_GROUND_BONK, 32, TRUE, m->actionArg);
if (animFrame == 32) {
play_mario_landing_sound(m, SOUND_ACTION_TERRAIN_LANDING); play_mario_landing_sound(m, SOUND_ACTION_TERRAIN_LANDING);
} }
return FALSE; return FALSE;
} }
s32 act_death_exit_land(struct MarioState *m) { s32 act_death_exit_land(struct MarioState *m) {
s32 val04; s32 animFrame;
apply_landing_accel(m, 0.9f); apply_landing_accel(m, 0.9f);
play_mario_heavy_landing_sound_once(m, SOUND_ACTION_TERRAIN_BODY_HIT_GROUND); play_mario_heavy_landing_sound_once(m, SOUND_ACTION_TERRAIN_BODY_HIT_GROUND);
val04 = set_mario_animation(m, MARIO_ANIM_FALL_OVER_BACKWARDS); animFrame = set_mario_animation(m, MARIO_ANIM_FALL_OVER_BACKWARDS);
if (val04 == 0x36) { if (animFrame == 54) {
play_character_sound(m, CHAR_SOUND_MAMA_MIA); play_character_sound(m, CHAR_SOUND_MAMA_MIA);
} }
if (val04 == 0x44) { if (animFrame == 68) {
play_mario_landing_sound(m, SOUND_ACTION_TERRAIN_LANDING); play_mario_landing_sound(m, SOUND_ACTION_TERRAIN_LANDING);
} }

View file

@ -53,7 +53,7 @@ s32 mario_update_punch_sequence(struct MarioState *m) {
m->actionArg = 1; m->actionArg = 1;
} }
if (m->marioObj->header.gfx.unk38.animFrame >= 2) { if (m->marioObj->header.gfx.animInfo.animFrame >= 2) {
if (mario_check_object_grab(m)) { if (mario_check_object_grab(m)) {
return TRUE; return TRUE;
} }
@ -69,7 +69,7 @@ s32 mario_update_punch_sequence(struct MarioState *m) {
case 2: case 2:
set_mario_animation(m, MARIO_ANIM_FIRST_PUNCH_FAST); set_mario_animation(m, MARIO_ANIM_FIRST_PUNCH_FAST);
if (m->marioObj->header.gfx.unk38.animFrame <= 0) { if (m->marioObj->header.gfx.animInfo.animFrame <= 0) {
m->flags |= MARIO_PUNCHING; m->flags |= MARIO_PUNCHING;
} }
@ -93,7 +93,7 @@ s32 mario_update_punch_sequence(struct MarioState *m) {
m->actionArg = 4; m->actionArg = 4;
} }
if (m->marioObj->header.gfx.unk38.animFrame > 0) { if (m->marioObj->header.gfx.animInfo.animFrame > 0) {
m->flags |= MARIO_PUNCHING; m->flags |= MARIO_PUNCHING;
} }
@ -104,7 +104,7 @@ s32 mario_update_punch_sequence(struct MarioState *m) {
case 5: case 5:
set_mario_animation(m, MARIO_ANIM_SECOND_PUNCH_FAST); set_mario_animation(m, MARIO_ANIM_SECOND_PUNCH_FAST);
if (m->marioObj->header.gfx.unk38.animFrame <= 0) { if (m->marioObj->header.gfx.animInfo.animFrame <= 0) {
m->flags |= MARIO_PUNCHING; m->flags |= MARIO_PUNCHING;
} }
@ -136,7 +136,7 @@ s32 mario_update_punch_sequence(struct MarioState *m) {
case 9: case 9:
play_mario_action_sound(m, CHAR_SOUND_PUNCH_HOO, 1); play_mario_action_sound(m, CHAR_SOUND_PUNCH_HOO, 1);
set_mario_animation(m, MARIO_ANIM_BREAKDANCE); set_mario_animation(m, MARIO_ANIM_BREAKDANCE);
animFrame = m->marioObj->header.gfx.unk38.animFrame; animFrame = m->marioObj->header.gfx.animInfo.animFrame;
if (animFrame >= 2 && animFrame < 8) { if (animFrame >= 2 && animFrame < 8) {
m->flags |= MARIO_TRIPPING; m->flags |= MARIO_TRIPPING;

View file

@ -2,7 +2,6 @@
#include "sm64.h" #include "sm64.h"
#include "area.h" #include "area.h"
#include "audio/data.h"
#include "audio/external.h" #include "audio/external.h"
#include "behavior_data.h" #include "behavior_data.h"
#include "camera.h" #include "camera.h"
@ -61,7 +60,7 @@ s32 check_common_idle_cancels(struct MarioState *m) {
return set_mario_action(m, ACT_START_CROUCHING, 0); return set_mario_action(m, ACT_START_CROUCHING, 0);
} }
return 0; return FALSE;
} }
s32 check_common_hold_idle_cancels(struct MarioState *m) { s32 check_common_hold_idle_cancels(struct MarioState *m) {
@ -104,7 +103,7 @@ s32 check_common_hold_idle_cancels(struct MarioState *m) {
return drop_and_set_mario_action(m, ACT_START_CROUCHING, 0); return drop_and_set_mario_action(m, ACT_START_CROUCHING, 0);
} }
return 0; return FALSE;
} }
s32 act_idle(struct MarioState *m) { s32 act_idle(struct MarioState *m) {
@ -121,7 +120,7 @@ s32 act_idle(struct MarioState *m) {
} }
if (check_common_idle_cancels(m)) { if (check_common_idle_cancels(m)) {
return 1; return TRUE;
} }
if (m->actionState == 3) { if (m->actionState == 3) {
@ -174,22 +173,22 @@ s32 act_idle(struct MarioState *m) {
stationary_ground_step(m); stationary_ground_step(m);
return 0; return FALSE;
} }
void play_anim_sound(struct MarioState *m, u32 actionState, s32 animFrame, u32 sound) { void play_anim_sound(struct MarioState *m, u32 actionState, s32 animFrame, u32 sound) {
if (m->actionState == actionState && m->marioObj->header.gfx.unk38.animFrame == animFrame) { if (m->actionState == actionState && m->marioObj->header.gfx.animInfo.animFrame == animFrame) {
play_sound(sound, m->marioObj->header.gfx.cameraToObject); play_sound(sound, m->marioObj->header.gfx.cameraToObject);
} }
} }
s32 act_start_sleeping(struct MarioState *m) { s32 act_start_sleeping(struct MarioState *m) {
#ifndef VERSION_JP #ifndef VERSION_JP
s32 sp24; s32 animFrame;
#endif #endif
if (check_common_idle_cancels(m)) { if (check_common_idle_cancels(m)) {
return 1; return TRUE;
} }
if (m->quicksandDepth > 30.0f) { if (m->quicksandDepth > 30.0f) {
@ -203,35 +202,31 @@ s32 act_start_sleeping(struct MarioState *m) {
switch (m->actionState) { switch (m->actionState) {
case 0: case 0:
#ifndef VERSION_JP #ifndef VERSION_JP
sp24 = set_mario_animation(m, MARIO_ANIM_START_SLEEP_IDLE); animFrame =
#else
set_mario_animation(m, MARIO_ANIM_START_SLEEP_IDLE);
#endif #endif
set_mario_animation(m, MARIO_ANIM_START_SLEEP_IDLE);
break; break;
case 1: case 1:
#ifndef VERSION_JP #ifndef VERSION_JP
sp24 = set_mario_animation(m, MARIO_ANIM_START_SLEEP_SCRATCH); animFrame =
#else
set_mario_animation(m, MARIO_ANIM_START_SLEEP_SCRATCH);
#endif #endif
set_mario_animation(m, MARIO_ANIM_START_SLEEP_SCRATCH);
break; break;
case 2: case 2:
#ifndef VERSION_JP #ifndef VERSION_JP
sp24 = set_mario_animation(m, MARIO_ANIM_START_SLEEP_YAWN); animFrame =
#else
set_mario_animation(m, MARIO_ANIM_START_SLEEP_YAWN);
#endif #endif
set_mario_animation(m, MARIO_ANIM_START_SLEEP_YAWN);
m->marioBodyState->eyeState = MARIO_EYES_HALF_CLOSED; m->marioBodyState->eyeState = MARIO_EYES_HALF_CLOSED;
break; break;
case 3: case 3:
#ifndef VERSION_JP #ifndef VERSION_JP
sp24 = set_mario_animation(m, MARIO_ANIM_START_SLEEP_SITTING); animFrame =
#else
set_mario_animation(m, MARIO_ANIM_START_SLEEP_SITTING);
#endif #endif
set_mario_animation(m, MARIO_ANIM_START_SLEEP_SITTING);
m->marioBodyState->eyeState = MARIO_EYES_HALF_CLOSED; m->marioBodyState->eyeState = MARIO_EYES_HALF_CLOSED;
break; break;
} }
@ -245,16 +240,12 @@ s32 act_start_sleeping(struct MarioState *m) {
} }
#ifndef VERSION_JP #ifndef VERSION_JP
if (m->actionState == 2) { if (m->actionState == 2 && animFrame == -1) {
if (sp24 == -1) { play_character_sound(m, CHAR_SOUND_YAWNING);
play_character_sound(m, CHAR_SOUND_YAWNING);
}
} }
if (m->actionState == 1) { if (m->actionState == 2 && animFrame == -1) {
if (sp24 == -1) { play_character_sound(m, CHAR_SOUND_IMA_TIRED);
play_character_sound(m, CHAR_SOUND_IMA_TIRED);
}
} }
#else #else
if (m->actionState == 2) { if (m->actionState == 2) {
@ -263,13 +254,15 @@ s32 act_start_sleeping(struct MarioState *m) {
#endif #endif
stationary_ground_step(m); stationary_ground_step(m);
return 0; return FALSE;
} }
s32 act_sleeping(struct MarioState *m) { s32 act_sleeping(struct MarioState *m) {
s32 sp24; s32 animFrame;
if (m->playerIndex == 0) { if (m->playerIndex == 0) {
if (m->input & INPUT_UNKNOWN_A41F /* ? */) { if (m->input
& (INPUT_NONZERO_ANALOG | INPUT_A_PRESSED | INPUT_OFF_FLOOR | INPUT_ABOVE_SLIDE
| INPUT_FIRST_PERSON | INPUT_UNKNOWN_10 | INPUT_B_PRESSED | INPUT_Z_PRESSED)) {
return set_mario_action(m, ACT_WAKING_UP, m->actionState); return set_mario_action(m, ACT_WAKING_UP, m->actionState);
} }
@ -285,19 +278,19 @@ s32 act_sleeping(struct MarioState *m) {
m->marioBodyState->eyeState = MARIO_EYES_CLOSED; m->marioBodyState->eyeState = MARIO_EYES_CLOSED;
stationary_ground_step(m); stationary_ground_step(m);
switch (m->actionState) { switch (m->actionState) {
case 0: { case 0:
sp24 = set_mario_animation(m, MARIO_ANIM_SLEEP_IDLE); animFrame = set_mario_animation(m, MARIO_ANIM_SLEEP_IDLE);
if (m->playerIndex == 0 && sp24 == -1 && !m->actionTimer) { if (m->playerIndex == 0 && animFrame == -1 && !m->actionTimer) {
lower_background_noise(2); lower_background_noise(2);
} }
if (sp24 == 2) { if (animFrame == 2) {
play_character_sound(m, CHAR_SOUND_SNORING1); play_character_sound(m, CHAR_SOUND_SNORING1);
m->isSnoring = TRUE; m->isSnoring = TRUE;
} }
if (sp24 == 20) { if (animFrame == 20) {
play_character_sound(m, CHAR_SOUND_SNORING2); play_character_sound(m, CHAR_SOUND_SNORING2);
m->isSnoring = TRUE; m->isSnoring = TRUE;
} }
@ -309,8 +302,8 @@ s32 act_sleeping(struct MarioState *m) {
} }
} }
break; break;
}
case 1: { case 1:
if (set_mario_animation(m, MARIO_ANIM_SLEEP_START_LYING) == 18) { if (set_mario_animation(m, MARIO_ANIM_SLEEP_START_LYING) == 18) {
play_mario_heavy_landing_sound(m, SOUND_ACTION_TERRAIN_BODY_HIT_GROUND); play_mario_heavy_landing_sound(m, SOUND_ACTION_TERRAIN_BODY_HIT_GROUND);
} }
@ -319,27 +312,26 @@ s32 act_sleeping(struct MarioState *m) {
m->actionState++; m->actionState++;
} }
break; break;
}
case 2: { case 2:
sp24 = set_mario_animation(m, MARIO_ANIM_SLEEP_LYING); animFrame = set_mario_animation(m, MARIO_ANIM_SLEEP_LYING);
#ifndef VERSION_JP #ifndef VERSION_JP
play_character_sound_if_no_flag(m, CHAR_SOUND_SNORING3, MARIO_MARIO_SOUND_PLAYED); play_character_sound_if_no_flag(m, CHAR_SOUND_SNORING3, MARIO_MARIO_SOUND_PLAYED);
m->isSnoring = TRUE; m->isSnoring = TRUE;
#else #else
if (sp24 == 2) { if (animFrame == 2) {
play_character_sound(m, CHAR_SOUND_SNORING2); play_character_sound(m, CHAR_SOUND_SNORING2);
m->isSnoring = TRUE; m->isSnoring = TRUE;
} }
if (sp24 == 25) { if (animFrame == 25) {
play_character_sound(m, CHAR_SOUND_SNORING1); play_character_sound(m, CHAR_SOUND_SNORING1);
m->isSnoring = TRUE; m->isSnoring = TRUE;
} }
#endif #endif
break; break;
}
} }
return 0; return FALSE;
} }
s32 act_waking_up(struct MarioState *m) { s32 act_waking_up(struct MarioState *m) {
@ -376,11 +368,11 @@ s32 act_waking_up(struct MarioState *m) {
set_mario_animation(m, !m->actionArg ? MARIO_ANIM_WAKE_FROM_SLEEP : MARIO_ANIM_WAKE_FROM_LYING); set_mario_animation(m, !m->actionArg ? MARIO_ANIM_WAKE_FROM_SLEEP : MARIO_ANIM_WAKE_FROM_LYING);
return 0; return FALSE;
} }
s32 act_shivering(struct MarioState *m) { s32 act_shivering(struct MarioState *m) {
s32 sp24; s32 animFrame;
if (m->input & INPUT_UNKNOWN_10) { if (m->input & INPUT_UNKNOWN_10) {
return set_mario_action(m, ACT_SHOCKWAVE_BOUNCE, 0); return set_mario_action(m, ACT_SHOCKWAVE_BOUNCE, 0);
@ -394,66 +386,67 @@ s32 act_shivering(struct MarioState *m) {
return set_mario_action(m, ACT_BEGIN_SLIDING, 0); return set_mario_action(m, ACT_BEGIN_SLIDING, 0);
} }
if (m->input & INPUT_UNKNOWN_A41F) { if (m->input
& (INPUT_NONZERO_ANALOG | INPUT_A_PRESSED | INPUT_OFF_FLOOR | INPUT_ABOVE_SLIDE
| INPUT_FIRST_PERSON | INPUT_UNKNOWN_10 | INPUT_B_PRESSED | INPUT_Z_PRESSED)) {
m->actionState = 2; m->actionState = 2;
} }
stationary_ground_step(m); stationary_ground_step(m);
switch (m->actionState) { switch (m->actionState) {
case 0: { case 0:
sp24 = set_mario_animation(m, MARIO_ANIM_SHIVERING_WARMING_HAND); animFrame = set_mario_animation(m, MARIO_ANIM_SHIVERING_WARMING_HAND);
if (sp24 == 0x31) { if (animFrame == 49) {
m->particleFlags |= PARTICLE_BREATH; m->particleFlags |= PARTICLE_BREATH;
play_character_sound(m, CHAR_SOUND_PANTING_COLD); play_character_sound(m, CHAR_SOUND_PANTING_COLD);
} }
if (sp24 == 7 || sp24 == 0x51) { if (animFrame == 7 || animFrame == 81) {
play_sound(SOUND_ACTION_CLAP_HANDS_COLD, m->marioObj->header.gfx.cameraToObject); play_sound(SOUND_ACTION_CLAP_HANDS_COLD, m->marioObj->header.gfx.cameraToObject);
} }
if (is_anim_past_end(m)) { if (is_anim_past_end(m)) {
m->actionState = 1; m->actionState = 1;
} }
break; break;
}
case 1: { case 1:
sp24 = set_mario_animation(m, MARIO_ANIM_SHIVERING); animFrame = set_mario_animation(m, MARIO_ANIM_SHIVERING);
if (sp24 == 9 || sp24 == 0x19 || sp24 == 0x2C) { if (animFrame == 9 || animFrame == 25 || animFrame == 44) {
play_sound(SOUND_ACTION_CLAP_HANDS_COLD, m->marioObj->header.gfx.cameraToObject); play_sound(SOUND_ACTION_CLAP_HANDS_COLD, m->marioObj->header.gfx.cameraToObject);
} }
break; break;
}
case 2: { case 2:
set_mario_animation(m, MARIO_ANIM_SHIVERING_RETURN_TO_IDLE); set_mario_animation(m, MARIO_ANIM_SHIVERING_RETURN_TO_IDLE);
if (is_anim_past_end(m)) { if (is_anim_past_end(m)) {
set_mario_action(m, ACT_IDLE, 0); set_mario_action(m, ACT_IDLE, 0);
} }
break; break;
}
} }
return 0; return FALSE;
} }
s32 act_coughing(struct MarioState *m) { s32 act_coughing(struct MarioState *m) {
s32 sp1C; s32 animFrame;
if (check_common_idle_cancels(m)) { if (check_common_idle_cancels(m)) {
return 1; return TRUE;
} }
stationary_ground_step(m); stationary_ground_step(m);
sp1C = set_mario_animation(m, MARIO_ANIM_COUGHING); animFrame = set_mario_animation(m, MARIO_ANIM_COUGHING);
if (sp1C == 0x19 || sp1C == 0x23) { if (animFrame == 25 || animFrame == 35) {
play_character_sound(m, CHAR_SOUND_COUGHING3); play_character_sound(m, CHAR_SOUND_COUGHING3);
} }
if (sp1C == 0x32 || sp1C == 0x3A) { if (animFrame == 50 || animFrame == 58) {
play_character_sound(m, CHAR_SOUND_COUGHING2); play_character_sound(m, CHAR_SOUND_COUGHING2);
} }
if (sp1C == 0x47 || sp1C == 0x50) { if (animFrame == 71 || animFrame == 80) {
play_character_sound(m, CHAR_SOUND_COUGHING1); play_character_sound(m, CHAR_SOUND_COUGHING1);
} }
return 0; return FALSE;
} }
s32 act_hold_idle(struct MarioState *m) { s32 act_hold_idle(struct MarioState *m) {
@ -470,12 +463,12 @@ s32 act_hold_idle(struct MarioState *m) {
} }
if (check_common_hold_idle_cancels(m)) { if (check_common_hold_idle_cancels(m)) {
return 1; return TRUE;
} }
stationary_ground_step(m); stationary_ground_step(m);
set_mario_animation(m, MARIO_ANIM_IDLE_WITH_LIGHT_OBJ); set_mario_animation(m, MARIO_ANIM_IDLE_WITH_LIGHT_OBJ);
return 0; return FALSE;
} }
s32 act_hold_heavy_idle(struct MarioState *m) { s32 act_hold_heavy_idle(struct MarioState *m) {
@ -501,7 +494,7 @@ s32 act_hold_heavy_idle(struct MarioState *m) {
stationary_ground_step(m); stationary_ground_step(m);
set_mario_animation(m, MARIO_ANIM_IDLE_HEAVY_OBJ); set_mario_animation(m, MARIO_ANIM_IDLE_HEAVY_OBJ);
return 0; return FALSE;
} }
s32 act_standing_against_wall(struct MarioState *m) { s32 act_standing_against_wall(struct MarioState *m) {
@ -523,7 +516,7 @@ s32 act_standing_against_wall(struct MarioState *m) {
set_mario_animation(m, MARIO_ANIM_STAND_AGAINST_WALL); set_mario_animation(m, MARIO_ANIM_STAND_AGAINST_WALL);
stationary_ground_step(m); stationary_ground_step(m);
return 0; return FALSE;
} }
s32 act_in_quicksand(struct MarioState *m) { s32 act_in_quicksand(struct MarioState *m) {
@ -531,8 +524,8 @@ s32 act_in_quicksand(struct MarioState *m) {
return set_mario_action(m, ACT_IDLE, 0); return set_mario_action(m, ACT_IDLE, 0);
} }
if (check_common_idle_cancels(m) != 0) { if (check_common_idle_cancels(m)) {
return 1; return TRUE;
} }
if (m->quicksandDepth > 70.0f) { if (m->quicksandDepth > 70.0f) {
@ -542,7 +535,7 @@ s32 act_in_quicksand(struct MarioState *m) {
} }
stationary_ground_step(m); stationary_ground_step(m);
return 0; return FALSE;
} }
s32 act_crouching(struct MarioState *m) { s32 act_crouching(struct MarioState *m) {
@ -580,7 +573,7 @@ s32 act_crouching(struct MarioState *m) {
stationary_ground_step(m); stationary_ground_step(m);
set_mario_animation(m, MARIO_ANIM_CROUCHING); set_mario_animation(m, MARIO_ANIM_CROUCHING);
return 0; return FALSE;
} }
s32 act_panting(struct MarioState *m) { s32 act_panting(struct MarioState *m) {
@ -593,7 +586,7 @@ s32 act_panting(struct MarioState *m) {
} }
if (check_common_idle_cancels(m)) { if (check_common_idle_cancels(m)) {
return 1; return TRUE;
} }
if (set_mario_animation(m, MARIO_ANIM_WALK_PANTING) == 1) { if (set_mario_animation(m, MARIO_ANIM_WALK_PANTING) == 1) {
@ -602,7 +595,7 @@ s32 act_panting(struct MarioState *m) {
stationary_ground_step(m); stationary_ground_step(m);
m->marioBodyState->eyeState = MARIO_EYES_HALF_CLOSED; m->marioBodyState->eyeState = MARIO_EYES_HALF_CLOSED;
return 0; return FALSE;
} }
s32 act_hold_panting_unused(struct MarioState *m) { s32 act_hold_panting_unused(struct MarioState *m) {
@ -618,20 +611,20 @@ s32 act_hold_panting_unused(struct MarioState *m) {
return set_mario_action(m, ACT_HOLD_IDLE, 0); return set_mario_action(m, ACT_HOLD_IDLE, 0);
} }
if (check_common_hold_idle_cancels(m) != 0) { if (check_common_hold_idle_cancels(m)) {
return 1; return TRUE;
} }
set_mario_animation(m, MARIO_ANIM_WALK_PANTING); set_mario_animation(m, MARIO_ANIM_WALK_PANTING);
stationary_ground_step(m); stationary_ground_step(m);
m->marioBodyState->eyeState = MARIO_EYES_HALF_CLOSED; m->marioBodyState->eyeState = MARIO_EYES_HALF_CLOSED;
return 0; return FALSE;
} }
void stopping_step(struct MarioState *m, s32 animID, u32 action) { void stopping_step(struct MarioState *m, s32 animID, u32 action) {
stationary_ground_step(m); stationary_ground_step(m);
set_mario_animation(m, animID); set_mario_animation(m, animID);
if (is_anim_at_end(m) != 0) { if (is_anim_at_end(m)) {
set_mario_action(m, action, 0); set_mario_action(m, action, 0);
} }
} }
@ -655,7 +648,7 @@ s32 act_braking_stop(struct MarioState *m) {
} }
stopping_step(m, MARIO_ANIM_STOP_SKID, ACT_IDLE); stopping_step(m, MARIO_ANIM_STOP_SKID, ACT_IDLE);
return 0; return FALSE;
} }
s32 act_butt_slide_stop(struct MarioState *m) { s32 act_butt_slide_stop(struct MarioState *m) {
@ -668,11 +661,11 @@ s32 act_butt_slide_stop(struct MarioState *m) {
} }
stopping_step(m, MARIO_ANIM_STOP_SLIDE, ACT_IDLE); stopping_step(m, MARIO_ANIM_STOP_SLIDE, ACT_IDLE);
if (m->marioObj->header.gfx.unk38.animFrame == 6) { if (m->marioObj->header.gfx.animInfo.animFrame == 6) {
play_mario_landing_sound(m, SOUND_ACTION_TERRAIN_LANDING); play_mario_landing_sound(m, SOUND_ACTION_TERRAIN_LANDING);
} }
return 0; return FALSE;
} }
s32 act_hold_butt_slide_stop(struct MarioState *m) { s32 act_hold_butt_slide_stop(struct MarioState *m) {
@ -693,7 +686,7 @@ s32 act_hold_butt_slide_stop(struct MarioState *m) {
} }
stopping_step(m, MARIO_ANIM_STAND_UP_FROM_SLIDING_WITH_LIGHT_OBJ, ACT_HOLD_IDLE); stopping_step(m, MARIO_ANIM_STAND_UP_FROM_SLIDING_WITH_LIGHT_OBJ, ACT_HOLD_IDLE);
return 0; return FALSE;
} }
s32 act_slide_kick_slide_stop(struct MarioState *m) { s32 act_slide_kick_slide_stop(struct MarioState *m) {
@ -706,7 +699,7 @@ s32 act_slide_kick_slide_stop(struct MarioState *m) {
} }
stopping_step(m, MARIO_ANIM_CROUCH_FROM_SLIDE_KICK, ACT_CROUCHING); stopping_step(m, MARIO_ANIM_CROUCH_FROM_SLIDE_KICK, ACT_CROUCHING);
return 0; return FALSE;
} }
s32 act_start_crouching(struct MarioState *m) { s32 act_start_crouching(struct MarioState *m) {
@ -731,7 +724,7 @@ s32 act_start_crouching(struct MarioState *m) {
if (is_anim_past_end(m)) { if (is_anim_past_end(m)) {
set_mario_action(m, ACT_CROUCHING, 0); set_mario_action(m, ACT_CROUCHING, 0);
} }
return 0; return FALSE;
} }
s32 act_stop_crouching(struct MarioState *m) { s32 act_stop_crouching(struct MarioState *m) {
@ -756,7 +749,7 @@ s32 act_stop_crouching(struct MarioState *m) {
if (is_anim_past_end(m)) { if (is_anim_past_end(m)) {
set_mario_action(m, ACT_IDLE, 0); set_mario_action(m, ACT_IDLE, 0);
} }
return 0; return FALSE;
} }
s32 act_start_crawling(struct MarioState *m) { s32 act_start_crawling(struct MarioState *m) {
@ -782,7 +775,7 @@ s32 act_start_crawling(struct MarioState *m) {
set_mario_action(m, ACT_CRAWLING, 0); set_mario_action(m, ACT_CRAWLING, 0);
} }
return 0; return FALSE;
} }
s32 act_stop_crawling(struct MarioState *m) { s32 act_stop_crawling(struct MarioState *m) {
@ -803,14 +796,14 @@ s32 act_stop_crawling(struct MarioState *m) {
if (is_anim_past_end(m)) { if (is_anim_past_end(m)) {
set_mario_action(m, ACT_CROUCHING, 0); set_mario_action(m, ACT_CROUCHING, 0);
} }
return 0; return FALSE;
} }
s32 act_shockwave_bounce(struct MarioState *m) { s32 act_shockwave_bounce(struct MarioState *m) {
s16 sp1E; s16 sp1E;
f32 sp18; f32 sp18;
if (m->marioObj->oInteractStatus & 0x10) { if (m->marioObj->oInteractStatus & INT_STATUS_HIT_BY_SHOCKWAVE) {
queue_rumble_data_mario(m, 70, 40); queue_rumble_data_mario(m, 70, 40);
return hurt_and_set_mario_action(m, ACT_SHOCKED, 0, 4); return hurt_and_set_mario_action(m, ACT_SHOCKED, 0, 4);
} }
@ -822,11 +815,11 @@ s32 act_shockwave_bounce(struct MarioState *m) {
} }
} }
if (++m->actionTimer == 0x30) { if (++m->actionTimer == 48) {
return set_mario_action(m, ACT_IDLE, 0); return set_mario_action(m, ACT_IDLE, 0);
} }
sp1E = (m->actionTimer % 0x10) << 0xC; sp1E = (m->actionTimer % 16) << 12;
sp18 = (f32)(((f32)(6 - m->actionTimer / 8) * 8.0f) + 4.0f); sp18 = (f32)(((f32)(6 - m->actionTimer / 8) * 8.0f) + 4.0f);
mario_set_forward_vel(m, 0); mario_set_forward_vel(m, 0);
vec3f_set(m->vel, 0.0f, 0.0f, 0.0f); vec3f_set(m->vel, 0.0f, 0.0f, 0.0f);
@ -839,7 +832,7 @@ s32 act_shockwave_bounce(struct MarioState *m) {
vec3f_copy(m->marioObj->header.gfx.pos, m->pos); vec3f_copy(m->marioObj->header.gfx.pos, m->pos);
vec3s_set(m->marioObj->header.gfx.angle, 0, m->faceAngle[1], 0); vec3s_set(m->marioObj->header.gfx.angle, 0, m->faceAngle[1], 0);
set_mario_animation(m, MARIO_ANIM_A_POSE); set_mario_animation(m, MARIO_ANIM_A_POSE);
return 0; return FALSE;
} }
s32 landing_step(struct MarioState *m, s32 arg1, u32 action) { s32 landing_step(struct MarioState *m, s32 arg1, u32 action) {
@ -848,7 +841,7 @@ s32 landing_step(struct MarioState *m, s32 arg1, u32 action) {
if (is_anim_at_end(m)) { if (is_anim_at_end(m)) {
return set_mario_action(m, action, 0); return set_mario_action(m, action, 0);
} }
return 0; return FALSE;
} }
s32 check_common_landing_cancels(struct MarioState *m, u32 action) { s32 check_common_landing_cancels(struct MarioState *m, u32 action) {
@ -876,90 +869,89 @@ s32 check_common_landing_cancels(struct MarioState *m, u32 action) {
return set_mario_action(m, ACT_PUNCHING, 0); return set_mario_action(m, ACT_PUNCHING, 0);
} }
return 0; return FALSE;
} }
s32 act_jump_land_stop(struct MarioState *m) { s32 act_jump_land_stop(struct MarioState *m) {
if (check_common_landing_cancels(m, 0)) { if (check_common_landing_cancels(m, 0)) {
return 1; return TRUE;
} }
landing_step(m, MARIO_ANIM_LAND_FROM_SINGLE_JUMP, ACT_IDLE); landing_step(m, MARIO_ANIM_LAND_FROM_SINGLE_JUMP, ACT_IDLE);
return 0; return FALSE;
} }
s32 act_double_jump_land_stop(struct MarioState *m) { s32 act_double_jump_land_stop(struct MarioState *m) {
if (check_common_landing_cancels(m, 0)) { if (check_common_landing_cancels(m, 0)) {
return 1; return TRUE;
} }
landing_step(m, MARIO_ANIM_LAND_FROM_DOUBLE_JUMP, ACT_IDLE); landing_step(m, MARIO_ANIM_LAND_FROM_DOUBLE_JUMP, ACT_IDLE);
return 0; return FALSE;
} }
s32 act_side_flip_land_stop(struct MarioState *m) { s32 act_side_flip_land_stop(struct MarioState *m) {
if (check_common_landing_cancels(m, 0)) { if (check_common_landing_cancels(m, 0)) {
return 1; return TRUE;
} }
landing_step(m, MARIO_ANIM_SLIDEFLIP_LAND, ACT_IDLE); landing_step(m, MARIO_ANIM_SLIDEFLIP_LAND, ACT_IDLE);
m->marioObj->header.gfx.angle[1] += 0x8000; m->marioObj->header.gfx.angle[1] += 0x8000;
return 0; return FALSE;
} }
s32 act_freefall_land_stop(struct MarioState *m) { s32 act_freefall_land_stop(struct MarioState *m) {
if (check_common_landing_cancels(m, 0)) { if (check_common_landing_cancels(m, 0)) {
return 1; return TRUE;
} }
landing_step(m, MARIO_ANIM_GENERAL_LAND, ACT_IDLE); landing_step(m, MARIO_ANIM_GENERAL_LAND, ACT_IDLE);
return 0; return FALSE;
} }
s32 act_triple_jump_land_stop(struct MarioState *m) { s32 act_triple_jump_land_stop(struct MarioState *m) {
if (check_common_landing_cancels(m, ACT_JUMP)) { if (check_common_landing_cancels(m, ACT_JUMP)) {
return 1; return TRUE;
} }
landing_step(m, MARIO_ANIM_TRIPLE_JUMP_LAND, ACT_IDLE); landing_step(m, MARIO_ANIM_TRIPLE_JUMP_LAND, ACT_IDLE);
return 0; return FALSE;
} }
s32 act_backflip_land_stop(struct MarioState *m) { s32 act_backflip_land_stop(struct MarioState *m) {
if (!(m->input & INPUT_Z_DOWN) || m->marioObj->header.gfx.unk38.animFrame >= 6) { if (!(m->input & INPUT_Z_DOWN) || m->marioObj->header.gfx.animInfo.animFrame >= 6) {
m->input &= -3; m->input &= ~INPUT_A_PRESSED;
} }
if (check_common_landing_cancels(m, ACT_BACKFLIP)) { if (check_common_landing_cancels(m, ACT_BACKFLIP)) {
return 1; return TRUE;
} }
landing_step(m, MARIO_ANIM_TRIPLE_JUMP_LAND, ACT_IDLE); landing_step(m, MARIO_ANIM_TRIPLE_JUMP_LAND, ACT_IDLE);
return 0; return FALSE;
} }
s32 act_lava_boost_land(struct MarioState *m) { s32 act_lava_boost_land(struct MarioState *m) {
m->input &= -0x2011; m->input &= ~(INPUT_FIRST_PERSON | INPUT_B_PRESSED);
if (check_common_landing_cancels(m, 0)) { if (check_common_landing_cancels(m, 0)) {
return 1; return TRUE;
} }
landing_step(m, MARIO_ANIM_STAND_UP_FROM_LAVA_BOOST, ACT_IDLE); landing_step(m, MARIO_ANIM_STAND_UP_FROM_LAVA_BOOST, ACT_IDLE);
return 0; return FALSE;
} }
s32 act_long_jump_land_stop(struct MarioState *m) { s32 act_long_jump_land_stop(struct MarioState *m) {
m->input &= -0x2001; m->input &= ~INPUT_B_PRESSED;
if (check_common_landing_cancels(m, ACT_JUMP)) { if (check_common_landing_cancels(m, ACT_JUMP)) {
return 1; return TRUE;
} }
landing_step(m, landing_step(m, !m->marioObj->oMarioLongJumpIsSlow ? MARIO_ANIM_CROUCH_FROM_FAST_LONGJUMP
!m->marioObj->oMarioLongJumpIsSlow ? MARIO_ANIM_CROUCH_FROM_FAST_LONGJUMP : MARIO_ANIM_CROUCH_FROM_SLOW_LONGJUMP,
: MARIO_ANIM_CROUCH_FROM_SLOW_LONGJUMP, ACT_CROUCHING);
ACT_CROUCHING); return FALSE;
return 0;
} }
s32 act_hold_jump_land_stop(struct MarioState *m) { s32 act_hold_jump_land_stop(struct MarioState *m) {
@ -980,7 +972,7 @@ s32 act_hold_jump_land_stop(struct MarioState *m) {
} }
landing_step(m, MARIO_ANIM_JUMP_LAND_WITH_LIGHT_OBJ, ACT_HOLD_IDLE); landing_step(m, MARIO_ANIM_JUMP_LAND_WITH_LIGHT_OBJ, ACT_HOLD_IDLE);
return 0; return FALSE;
} }
s32 act_hold_freefall_land_stop(struct MarioState *m) { s32 act_hold_freefall_land_stop(struct MarioState *m) {
@ -1000,7 +992,7 @@ s32 act_hold_freefall_land_stop(struct MarioState *m) {
return set_mario_action(m, ACT_THROWING, 0); return set_mario_action(m, ACT_THROWING, 0);
} }
landing_step(m, MARIO_ANIM_FALL_LAND_WITH_LIGHT_OBJ, ACT_HOLD_IDLE); landing_step(m, MARIO_ANIM_FALL_LAND_WITH_LIGHT_OBJ, ACT_HOLD_IDLE);
return 0; return FALSE;
} }
s32 act_air_throw_land(struct MarioState *m) { s32 act_air_throw_land(struct MarioState *m) {
@ -1017,7 +1009,7 @@ s32 act_air_throw_land(struct MarioState *m) {
} }
landing_step(m, MARIO_ANIM_THROW_LIGHT_OBJECT, ACT_IDLE); landing_step(m, MARIO_ANIM_THROW_LIGHT_OBJECT, ACT_IDLE);
return 0; return FALSE;
} }
s32 act_twirl_land(struct MarioState *m) { s32 act_twirl_land(struct MarioState *m) {
@ -1042,14 +1034,12 @@ s32 act_twirl_land(struct MarioState *m) {
} }
m->marioObj->header.gfx.angle[1] += m->twirlYaw; m->marioObj->header.gfx.angle[1] += m->twirlYaw;
if (is_anim_at_end(m)) { if (is_anim_at_end(m) && m->angleVel[1] == 0) {
if (m->angleVel[1] == 0) { m->faceAngle[1] += m->twirlYaw;
m->faceAngle[1] += m->twirlYaw; set_mario_action(m, ACT_IDLE, 0);
set_mario_action(m, ACT_IDLE, 0);
}
} }
return 0; return FALSE;
} }
s32 act_ground_pound_land(struct MarioState *m) { s32 act_ground_pound_land(struct MarioState *m) {
@ -1067,47 +1057,39 @@ s32 act_ground_pound_land(struct MarioState *m) {
} }
landing_step(m, MARIO_ANIM_GROUND_POUND_LANDING, ACT_BUTT_SLIDE_STOP); landing_step(m, MARIO_ANIM_GROUND_POUND_LANDING, ACT_BUTT_SLIDE_STOP);
return 0; return FALSE;
} }
s32 act_first_person(struct MarioState *m) { s32 act_first_person(struct MarioState *m) {
s32 sp1C; s32 sp1C = (m->input & (INPUT_OFF_FLOOR | INPUT_ABOVE_SLIDE | INPUT_UNKNOWN_10)) != 0;
s16 sp1A;
s16 sp18;
sp1C = 0 != (m->input & (INPUT_UNKNOWN_10 | 0xC));
if (m->actionState == 0) { if (m->actionState == 0) {
if (m->playerIndex == 0) { if (m->playerIndex == 0) {
lower_background_noise(2); lower_background_noise(2);
set_camera_mode(m->area->camera, CAMERA_MODE_C_UP, 0x10); set_camera_mode(m->area->camera, CAMERA_MODE_C_UP, 0x10);
} }
m->actionState = 1; m->actionState = 1;
} else { } else if (!(m->input & INPUT_FIRST_PERSON) || sp1C) {
if (!(m->input & INPUT_FIRST_PERSON) || sp1C) { if (m->playerIndex == 0) {
if (m->playerIndex == 0) { raise_background_noise(2);
raise_background_noise(2); // Go back to the last camera mode
// Go back to the last camera mode set_camera_mode(m->area->camera, -1, 1);
set_camera_mode(m->area->camera, -1, 1);
}
return set_mario_action(m, ACT_IDLE, 0);
} }
return set_mario_action(m, ACT_IDLE, 0);
} }
if (m->floor->type == SURFACE_LOOK_UP_WARP) { if (m->floor->type == SURFACE_LOOK_UP_WARP
if (save_file_get_total_star_count(gCurrSaveFileNum - 1, 0, 0x18) >= 10) { && save_file_get_total_star_count(gCurrSaveFileNum - 1, COURSE_MIN - 1, COURSE_MAX - 1) >= 10) {
sp1A = m->statusForCamera->headRotation[0]; s16 sp1A = m->statusForCamera->headRotation[0];
sp18 = ((m->statusForCamera->headRotation[1] * 4) / 3) + m->faceAngle[1]; s16 sp18 = ((m->statusForCamera->headRotation[1] * 4) / 3) + m->faceAngle[1];
if (sp1A == -0x1800) { if (sp1A == -0x1800 && (sp18 < -0x6FFF || sp18 >= 0x7000)) {
if (sp18 < -0x6FFF || sp18 >= 0x7000) { level_trigger_warp(m, WARP_OP_UNKNOWN_01);
level_trigger_warp(m, 1);
}
}
} }
} }
stationary_ground_step(m); stationary_ground_step(m);
set_mario_animation(m, MARIO_ANIM_FIRST_PERSON); set_mario_animation(m, MARIO_ANIM_FIRST_PERSON);
return 0; return FALSE;
} }
s32 check_common_stationary_cancels(struct MarioState *m) { s32 check_common_stationary_cancels(struct MarioState *m) {
@ -1128,75 +1110,73 @@ s32 check_common_stationary_cancels(struct MarioState *m) {
return drop_and_set_mario_action(m, ACT_SQUISHED, 0); return drop_and_set_mario_action(m, ACT_SQUISHED, 0);
} }
if (m->action != 0x0002020E) { if (m->action != ACT_UNKNOWN_0002020E) {
if (m->health < 0x100) { if (m->health < 0x100) {
update_mario_sound_and_camera(m); update_mario_sound_and_camera(m);
return drop_and_set_mario_action(m, ACT_STANDING_DEATH, 0); return drop_and_set_mario_action(m, ACT_STANDING_DEATH, 0);
} }
} }
return 0; return FALSE;
} }
s32 mario_execute_stationary_action(struct MarioState *m) { s32 mario_execute_stationary_action(struct MarioState *m) {
s32 sp24; s32 cancel;
if (check_common_stationary_cancels(m)) { if (check_common_stationary_cancels(m)) {
return 1; return TRUE;
} }
if (mario_update_quicksand(m, 0.5f)) { if (mario_update_quicksand(m, 0.5f)) {
return 1; return TRUE;
} }
if (!smlua_call_action_hook(m, &sp24)) { if (!smlua_call_action_hook(m, &cancel)) {
/* clang-format off */ /* clang-format off */
switch (m->action) { switch (m->action) {
case ACT_IDLE: sp24 = act_idle(m); break; case ACT_IDLE: cancel = act_idle(m); break;
case ACT_START_SLEEPING: sp24 = act_start_sleeping(m); break; case ACT_START_SLEEPING: cancel = act_start_sleeping(m); break;
case ACT_SLEEPING: sp24 = act_sleeping(m); break; case ACT_SLEEPING: cancel = act_sleeping(m); break;
case ACT_WAKING_UP: sp24 = act_waking_up(m); break; case ACT_WAKING_UP: cancel = act_waking_up(m); break;
case ACT_PANTING: sp24 = act_panting(m); break; case ACT_PANTING: cancel = act_panting(m); break;
case ACT_HOLD_PANTING_UNUSED: sp24 = act_hold_panting_unused(m); break; case ACT_HOLD_PANTING_UNUSED: cancel = act_hold_panting_unused(m); break;
case ACT_HOLD_IDLE: sp24 = act_hold_idle(m); break; case ACT_HOLD_IDLE: cancel = act_hold_idle(m); break;
case ACT_HOLD_HEAVY_IDLE: sp24 = act_hold_heavy_idle(m); break; case ACT_HOLD_HEAVY_IDLE: cancel = act_hold_heavy_idle(m); break;
case ACT_IN_QUICKSAND: sp24 = act_in_quicksand(m); break; case ACT_IN_QUICKSAND: cancel = act_in_quicksand(m); break;
case ACT_STANDING_AGAINST_WALL: sp24 = act_standing_against_wall(m); break; case ACT_STANDING_AGAINST_WALL: cancel = act_standing_against_wall(m); break;
case ACT_COUGHING: sp24 = act_coughing(m); break; case ACT_COUGHING: cancel = act_coughing(m); break;
case ACT_SHIVERING: sp24 = act_shivering(m); break; case ACT_SHIVERING: cancel = act_shivering(m); break;
case ACT_CROUCHING: sp24 = act_crouching(m); break; case ACT_CROUCHING: cancel = act_crouching(m); break;
case ACT_START_CROUCHING: sp24 = act_start_crouching(m); break; case ACT_START_CROUCHING: cancel = act_start_crouching(m); break;
case ACT_STOP_CROUCHING: sp24 = act_stop_crouching(m); break; case ACT_STOP_CROUCHING: cancel = act_stop_crouching(m); break;
case ACT_START_CRAWLING: sp24 = act_start_crawling(m); break; case ACT_START_CRAWLING: cancel = act_start_crawling(m); break;
case ACT_STOP_CRAWLING: sp24 = act_stop_crawling(m); break; case ACT_STOP_CRAWLING: cancel = act_stop_crawling(m); break;
case ACT_SLIDE_KICK_SLIDE_STOP: sp24 = act_slide_kick_slide_stop(m); break; case ACT_SLIDE_KICK_SLIDE_STOP: cancel = act_slide_kick_slide_stop(m); break;
case ACT_SHOCKWAVE_BOUNCE: sp24 = act_shockwave_bounce(m); break; case ACT_SHOCKWAVE_BOUNCE: cancel = act_shockwave_bounce(m); break;
case ACT_FIRST_PERSON: sp24 = act_first_person(m); break; case ACT_FIRST_PERSON: cancel = act_first_person(m); break;
case ACT_JUMP_LAND_STOP: sp24 = act_jump_land_stop(m); break; case ACT_JUMP_LAND_STOP: cancel = act_jump_land_stop(m); break;
case ACT_DOUBLE_JUMP_LAND_STOP: sp24 = act_double_jump_land_stop(m); break; case ACT_DOUBLE_JUMP_LAND_STOP: cancel = act_double_jump_land_stop(m); break;
case ACT_FREEFALL_LAND_STOP: sp24 = act_freefall_land_stop(m); break; case ACT_FREEFALL_LAND_STOP: cancel = act_freefall_land_stop(m); break;
case ACT_SIDE_FLIP_LAND_STOP: sp24 = act_side_flip_land_stop(m); break; case ACT_SIDE_FLIP_LAND_STOP: cancel = act_side_flip_land_stop(m); break;
case ACT_HOLD_JUMP_LAND_STOP: sp24 = act_hold_jump_land_stop(m); break; case ACT_HOLD_JUMP_LAND_STOP: cancel = act_hold_jump_land_stop(m); break;
case ACT_HOLD_FREEFALL_LAND_STOP: sp24 = act_hold_freefall_land_stop(m); break; case ACT_HOLD_FREEFALL_LAND_STOP: cancel = act_hold_freefall_land_stop(m); break;
case ACT_AIR_THROW_LAND: sp24 = act_air_throw_land(m); break; case ACT_AIR_THROW_LAND: cancel = act_air_throw_land(m); break;
case ACT_LAVA_BOOST_LAND: sp24 = act_lava_boost_land(m); break; case ACT_LAVA_BOOST_LAND: cancel = act_lava_boost_land(m); break;
case ACT_TWIRL_LAND: sp24 = act_twirl_land(m); break; case ACT_TWIRL_LAND: cancel = act_twirl_land(m); break;
case ACT_TRIPLE_JUMP_LAND_STOP: sp24 = act_triple_jump_land_stop(m); break; case ACT_TRIPLE_JUMP_LAND_STOP: cancel = act_triple_jump_land_stop(m); break;
case ACT_BACKFLIP_LAND_STOP: sp24 = act_backflip_land_stop(m); break; case ACT_BACKFLIP_LAND_STOP: cancel = act_backflip_land_stop(m); break;
case ACT_LONG_JUMP_LAND_STOP: sp24 = act_long_jump_land_stop(m); break; case ACT_LONG_JUMP_LAND_STOP: cancel = act_long_jump_land_stop(m); break;
case ACT_GROUND_POUND_LAND: sp24 = act_ground_pound_land(m); break; case ACT_GROUND_POUND_LAND: cancel = act_ground_pound_land(m); break;
case ACT_BRAKING_STOP: sp24 = act_braking_stop(m); break; case ACT_BRAKING_STOP: cancel = act_braking_stop(m); break;
case ACT_BUTT_SLIDE_STOP: sp24 = act_butt_slide_stop(m); break; case ACT_BUTT_SLIDE_STOP: cancel = act_butt_slide_stop(m); break;
case ACT_HOLD_BUTT_SLIDE_STOP: sp24 = act_hold_butt_slide_stop(m); break; case ACT_HOLD_BUTT_SLIDE_STOP: cancel = act_hold_butt_slide_stop(m); break;
default: LOG_ERROR("Attempted to execute unimplemented action '%04X'", m->action); return true; default: LOG_ERROR("Attempted to execute unimplemented action '%04X'", m->action); return true;
} }
/* clang-format on */ /* clang-format on */
} }
if (!sp24) { if (!cancel && (m->input & INPUT_IN_WATER)) {
if (m->input & INPUT_IN_WATER) { m->particleFlags |= PARTICLE_IDLE_WATER_WAVE;
m->particleFlags |= PARTICLE_IDLE_WATER_WAVE;
}
} }
return sp24; return cancel;
} }

View file

@ -5,8 +5,6 @@
#include "types.h" #include "types.h"
#define INPUT_UNKNOWN_A41F 0xA41F
s32 check_common_idle_cancels(struct MarioState *m); s32 check_common_idle_cancels(struct MarioState *m);
s32 check_common_hold_idle_cancels(struct MarioState *m); s32 check_common_hold_idle_cancels(struct MarioState *m);
s32 act_idle(struct MarioState *m); s32 act_idle(struct MarioState *m);

View file

@ -486,9 +486,9 @@ static void common_swimming_step(struct MarioState *m, s16 swimStrength) {
} }
static void play_swimming_noise(struct MarioState *m) { static void play_swimming_noise(struct MarioState *m) {
s16 animFrame = m->marioObj->header.gfx.unk38.animFrame; s16 animFrame = m->marioObj->header.gfx.animInfo.animFrame;
// (this need to be on one line to match on PAL) // This must be one line to match on -O2
if (animFrame == 0 || animFrame == 12) play_sound(SOUND_ACTION_UNKNOWN434, m->marioObj->header.gfx.cameraToObject); if (animFrame == 0 || animFrame == 12) play_sound(SOUND_ACTION_UNKNOWN434, m->marioObj->header.gfx.cameraToObject);
} }
@ -927,7 +927,7 @@ static s32 act_drowning(struct MarioState *m) {
case 1: case 1:
set_mario_animation(m, MARIO_ANIM_DROWNING_PART2); set_mario_animation(m, MARIO_ANIM_DROWNING_PART2);
m->marioBodyState->eyeState = MARIO_EYES_DEAD; m->marioBodyState->eyeState = MARIO_EYES_DEAD;
if (m->marioObj->header.gfx.unk38.animFrame == 30) { if (m->marioObj->header.gfx.animInfo.animFrame == 30) {
if (gServerSettings.bubbleDeath) { if (gServerSettings.bubbleDeath) {
mario_set_bubbled(m); mario_set_bubbled(m);
} else { } else {
@ -1272,7 +1272,7 @@ static s32 act_metal_water_walking(struct MarioState *m) {
break; break;
case GROUND_STEP_HIT_WALL: case GROUND_STEP_HIT_WALL:
m->forwardVel = 0; m->forwardVel = 0.0f;
break; break;
} }

View file

@ -159,7 +159,7 @@ Gfx *geo_draw_mario_head_goddard(s32 callContext, struct GraphNode *node, Mat4 *
UNUSED Mat4 *transform = c; UNUSED Mat4 *transform = c;
if (callContext == GEO_CONTEXT_RENDER) { if (callContext == GEO_CONTEXT_RENDER) {
if (gPlayer1Controller->controllerData != NULL && gWarpTransition.isActive == 0) { if (gPlayer1Controller->controllerData != NULL && !gWarpTransition.isActive) {
gd_copy_p1_contpad(gPlayer1Controller->controllerData); gd_copy_p1_contpad(gPlayer1Controller->controllerData);
} }
gfx = (Gfx *) PHYSICAL_TO_VIRTUAL(gdm_gettestdl(asGenerated->parameter)); gfx = (Gfx *) PHYSICAL_TO_VIRTUAL(gdm_gettestdl(asGenerated->parameter));
@ -172,9 +172,9 @@ Gfx *geo_draw_mario_head_goddard(s32 callContext, struct GraphNode *node, Mat4 *
static void toad_message_faded(void) { static void toad_message_faded(void) {
if (gCurrentObject->oDistanceToMario > 700.0f) { if (gCurrentObject->oDistanceToMario > 700.0f) {
gCurrentObject->oToadMessageRecentlyTalked = 0; gCurrentObject->oToadMessageRecentlyTalked = FALSE;
} }
if (gCurrentObject->oToadMessageRecentlyTalked == 0 && gCurrentObject->oDistanceToMario < 600.0f) { if (!gCurrentObject->oToadMessageRecentlyTalked && gCurrentObject->oDistanceToMario < 600.0f) {
gCurrentObject->oToadMessageState = TOAD_MESSAGE_OPACIFYING; gCurrentObject->oToadMessageState = TOAD_MESSAGE_OPACIFYING;
} }
} }
@ -182,14 +182,12 @@ static void toad_message_faded(void) {
static void toad_message_opaque(void) { static void toad_message_opaque(void) {
if (gCurrentObject->oDistanceToMario > 700.0f) { if (gCurrentObject->oDistanceToMario > 700.0f) {
gCurrentObject->oToadMessageState = TOAD_MESSAGE_FADING; gCurrentObject->oToadMessageState = TOAD_MESSAGE_FADING;
} else { } else if (!gCurrentObject->oToadMessageRecentlyTalked) {
if (gCurrentObject->oToadMessageRecentlyTalked == 0) { gCurrentObject->oInteractionSubtype = INT_SUBTYPE_NPC;
gCurrentObject->oInteractionSubtype = INT_SUBTYPE_NPC; if (gCurrentObject->oInteractStatus & INT_STATUS_INTERACTED) {
if (gCurrentObject->oInteractStatus & INT_STATUS_INTERACTED) { gCurrentObject->oInteractStatus = 0;
gCurrentObject->oInteractStatus = 0; gCurrentObject->oToadMessageState = TOAD_MESSAGE_TALKING;
gCurrentObject->oToadMessageState = TOAD_MESSAGE_TALKING; play_toads_jingle();
play_toads_jingle();
}
} }
} }
} }
@ -197,7 +195,7 @@ static void toad_message_opaque(void) {
static void toad_message_talking(void) { static void toad_message_talking(void) {
if (cur_obj_update_dialog_with_cutscene(&gMarioStates[0], 3, 1, CUTSCENE_DIALOG, gCurrentObject->oToadMessageDialogId, NULL) if (cur_obj_update_dialog_with_cutscene(&gMarioStates[0], 3, 1, CUTSCENE_DIALOG, gCurrentObject->oToadMessageDialogId, NULL)
!= 0) { != 0) {
gCurrentObject->oToadMessageRecentlyTalked = 1; gCurrentObject->oToadMessageRecentlyTalked = TRUE;
gCurrentObject->oToadMessageState = TOAD_MESSAGE_FADING; gCurrentObject->oToadMessageState = TOAD_MESSAGE_FADING;
switch (gCurrentObject->oToadMessageDialogId) { switch (gCurrentObject->oToadMessageDialogId) {
case TOAD_STAR_1_DIALOG: case TOAD_STAR_1_DIALOG:
@ -253,33 +251,33 @@ void bhv_toad_message_loop(void) {
void bhv_toad_message_init(void) { void bhv_toad_message_init(void) {
s32 saveFlags = save_file_get_flags(); s32 saveFlags = save_file_get_flags();
s32 starCount = save_file_get_total_star_count(gCurrSaveFileNum - 1, 0, 24); s32 starCount = save_file_get_total_star_count(gCurrSaveFileNum - 1, COURSE_MIN - 1, COURSE_MAX - 1);
s32 dialogId = (gCurrentObject->oBehParams >> 24) & 0xFF; s32 dialogId = (gCurrentObject->oBehParams >> 24) & 0xFF;
s32 enoughStars = TRUE; s32 enoughStars = TRUE;
switch (dialogId) { switch (dialogId) {
case TOAD_STAR_1_DIALOG: case TOAD_STAR_1_DIALOG:
enoughStars = (starCount >= TOAD_STAR_1_REQUIREMENT); enoughStars = (starCount >= TOAD_STAR_1_REQUIREMENT);
if (saveFlags & (1 << 24)) { if (saveFlags & SAVE_FLAG_COLLECTED_TOAD_STAR_1) {
dialogId = TOAD_STAR_1_DIALOG_AFTER; dialogId = TOAD_STAR_1_DIALOG_AFTER;
} }
break; break;
case TOAD_STAR_2_DIALOG: case TOAD_STAR_2_DIALOG:
enoughStars = (starCount >= TOAD_STAR_2_REQUIREMENT); enoughStars = (starCount >= TOAD_STAR_2_REQUIREMENT);
if (saveFlags & (1 << 25)) { if (saveFlags & SAVE_FLAG_COLLECTED_TOAD_STAR_2) {
dialogId = TOAD_STAR_2_DIALOG_AFTER; dialogId = TOAD_STAR_2_DIALOG_AFTER;
} }
break; break;
case TOAD_STAR_3_DIALOG: case TOAD_STAR_3_DIALOG:
enoughStars = (starCount >= TOAD_STAR_3_REQUIREMENT); enoughStars = (starCount >= TOAD_STAR_3_REQUIREMENT);
if (saveFlags & (1 << 26)) { if (saveFlags & SAVE_FLAG_COLLECTED_TOAD_STAR_3) {
dialogId = TOAD_STAR_3_DIALOG_AFTER; dialogId = TOAD_STAR_3_DIALOG_AFTER;
} }
break; break;
} }
if (enoughStars) { if (enoughStars) {
gCurrentObject->oToadMessageDialogId = dialogId; gCurrentObject->oToadMessageDialogId = dialogId;
gCurrentObject->oToadMessageRecentlyTalked = 0; gCurrentObject->oToadMessageRecentlyTalked = FALSE;
gCurrentObject->oToadMessageState = TOAD_MESSAGE_FADED; gCurrentObject->oToadMessageState = TOAD_MESSAGE_FADED;
gCurrentObject->oOpacity = 81; gCurrentObject->oOpacity = 81;
} else { } else {
@ -442,7 +440,7 @@ Gfx* geo_switch_mario_stand_run(s32 callContext, struct GraphNode* node, UNUSED
if (callContext == GEO_CONTEXT_RENDER) { if (callContext == GEO_CONTEXT_RENDER) {
// assign result. 0 if moving, 1 if stationary. // assign result. 0 if moving, 1 if stationary.
switchCase->selectedCase = ((bodyState->action & ACT_FLAG_STATIONARY) == FALSE); switchCase->selectedCase = ((bodyState->action & ACT_FLAG_STATIONARY) == 0);
} }
return NULL; return NULL;
} }
@ -658,16 +656,14 @@ Gfx* geo_mario_rotate_wing_cap_wings(s32 callContext, struct GraphNode* node, UN
if (callContext == GEO_CONTEXT_RENDER) { if (callContext == GEO_CONTEXT_RENDER) {
struct GraphNodeRotation* rotNode = (struct GraphNodeRotation*) node->next; struct GraphNodeRotation* rotNode = (struct GraphNodeRotation*) node->next;
if (bodyState->wingFlutter == FALSE) { if (!bodyState->wingFlutter) {
rotX = (coss((gAreaUpdateCounter & 0xF) << 12) + 1.0f) * 4096.0f; rotX = (coss((gAreaUpdateCounter & 0xF) << 12) + 1.0f) * 4096.0f;
} } else {
else {
rotX = (coss((gAreaUpdateCounter & 7) << 13) + 1.0f) * 6144.0f; rotX = (coss((gAreaUpdateCounter & 7) << 13) + 1.0f) * 6144.0f;
} }
if (!(asGenerated->parameter & 1)) { if (!(asGenerated->parameter & 1)) {
rotNode->rotation[0] = -rotX; rotNode->rotation[0] = -rotX;
} } else {
else {
rotNode->rotation[0] = rotX; rotNode->rotation[0] = rotX;
} }
} }
@ -741,25 +737,20 @@ Gfx* geo_render_mirror_mario(s32 callContext, struct GraphNode* node, UNUSED Mat
if (mario->header.gfx.pos[0] > 1700.0f) { if (mario->header.gfx.pos[0] > 1700.0f) {
// TODO: Is this a geo layout copy or a graph node copy? // TODO: Is this a geo layout copy or a graph node copy?
gMirrorMario[i].sharedChild = mario->header.gfx.sharedChild; gMirrorMario[i].sharedChild = mario->header.gfx.sharedChild;
gMirrorMario[i].unk18 = mario->header.gfx.unk18; gMirrorMario[i].areaIndex = mario->header.gfx.areaIndex;
vec3s_copy(gMirrorMario[i].angle, mario->header.gfx.angle); vec3s_copy(gMirrorMario[i].angle, mario->header.gfx.angle);
vec3f_copy(gMirrorMario[i].pos, mario->header.gfx.pos); vec3f_copy(gMirrorMario[i].pos, mario->header.gfx.pos);
vec3f_copy(gMirrorMario[i].scale, mario->header.gfx.scale); vec3f_copy(gMirrorMario[i].scale, mario->header.gfx.scale);
// FIXME: why does this set unk38, an inline struct, to a ptr to another one? wrong // FIXME: why does this set unk38, an inline struct, to a ptr to another one? wrong
// GraphNode types again? // GraphNode types again?
gMirrorMario[i].unk38 = *(struct GraphNodeObject_sub*) & mario->header.gfx.unk38.animID; gMirrorMario[i].animInfo = *(struct AnimInfo*) & mario->header.gfx.animInfo.animID;
mirroredX = MIRROR_X - gMirrorMario[i].pos[0]; mirroredX = MIRROR_X - gMirrorMario[i].pos[0];
gMirrorMario[i].pos[0] = mirroredX + MIRROR_X; gMirrorMario[i].pos[0] = mirroredX + MIRROR_X;
gMirrorMario[i].angle[1] = -gMirrorMario[i].angle[1]; gMirrorMario[i].angle[1] = -gMirrorMario[i].angle[1];
gMirrorMario[i].scale[0] *= -1.0f; gMirrorMario[i].scale[0] *= -1.0f;
// FIXME: Why doesn't this match? ((struct GraphNode *) &gMirrorMario)->flags |= 1;
// gMirrorMario.node.flags |= 1; } else {
((s16*)&gMirrorMario[i])[1] |= 1; ((struct GraphNode *) &gMirrorMario)->flags &= ~1;
}
else {
// FIXME: Why doesn't this match?
// gMirrorMario.node.flags &= ~1;
((s16*)&gMirrorMario[i])[1] &= ~1;
} }
break; break;
} }

View file

@ -154,7 +154,7 @@ u32 mario_update_quicksand(struct MarioState *m, f32 sinkingSpeed) {
} }
} }
return 0; return FALSE;
} }
u32 mario_push_off_steep_floor(struct MarioState *m, u32 action, u32 actionArg) { u32 mario_push_off_steep_floor(struct MarioState *m, u32 action, u32 actionArg) {
@ -183,10 +183,10 @@ u32 mario_update_moving_sand(struct MarioState *m) {
m->vel[0] += pushSpeed * sins(pushAngle); m->vel[0] += pushSpeed * sins(pushAngle);
m->vel[2] += pushSpeed * coss(pushAngle); m->vel[2] += pushSpeed * coss(pushAngle);
return 1; return TRUE;
} }
return 0; return FALSE;
} }
u32 mario_update_windy_ground(struct MarioState *m) { u32 mario_update_windy_ground(struct MarioState *m) {
@ -216,10 +216,10 @@ u32 mario_update_windy_ground(struct MarioState *m) {
#if VERSION_JP #if VERSION_JP
play_sound(SOUND_ENV_WIND2, m->marioObj->header.gfx.cameraToObject); play_sound(SOUND_ENV_WIND2, m->marioObj->header.gfx.cameraToObject);
#endif #endif
return 1; return TRUE;
} }
return 0; return FALSE;
} }
void stop_and_set_height_to_floor(struct MarioState *m) { void stop_and_set_height_to_floor(struct MarioState *m) {
@ -356,7 +356,7 @@ u32 check_ledge_grab(struct MarioState *m, struct Surface *wall, Vec3f intendedP
f32 displacementZ; f32 displacementZ;
if (m->vel[1] > 0) { if (m->vel[1] > 0) {
return 0; return FALSE;
} }
displacementX = nextPos[0] - intendedPos[0]; displacementX = nextPos[0] - intendedPos[0];
@ -365,7 +365,7 @@ u32 check_ledge_grab(struct MarioState *m, struct Surface *wall, Vec3f intendedP
// Only ledge grab if the wall displaced Mario in the opposite direction of // Only ledge grab if the wall displaced Mario in the opposite direction of
// his velocity. // his velocity.
if (displacementX * m->vel[0] + displacementZ * m->vel[2] > 0.0f) { if (displacementX * m->vel[0] + displacementZ * m->vel[2] > 0.0f) {
return 0; return FALSE;
} }
//! Since the search for floors starts at y + 160, we will sometimes grab //! Since the search for floors starts at y + 160, we will sometimes grab
@ -375,7 +375,7 @@ u32 check_ledge_grab(struct MarioState *m, struct Surface *wall, Vec3f intendedP
ledgePos[1] = find_floor(ledgePos[0], nextPos[1] + 160.0f, ledgePos[2], &ledgeFloor); ledgePos[1] = find_floor(ledgePos[0], nextPos[1] + 160.0f, ledgePos[2], &ledgeFloor);
if (ledgePos[1] - nextPos[1] <= 100.0f) { if (ledgePos[1] - nextPos[1] <= 100.0f) {
return 0; return FALSE;
} }
vec3f_copy(m->pos, ledgePos); vec3f_copy(m->pos, ledgePos);
@ -386,7 +386,7 @@ u32 check_ledge_grab(struct MarioState *m, struct Surface *wall, Vec3f intendedP
m->faceAngle[0] = 0; m->faceAngle[0] = 0;
m->faceAngle[1] = atan2s(wall->normal.z, wall->normal.x) + 0x8000; m->faceAngle[1] = atan2s(wall->normal.z, wall->normal.x) + 0x8000;
return 1; return TRUE;
} }
s32 perform_air_quarter_step(struct MarioState *m, Vec3f intendedPos, u32 stepArg) { s32 perform_air_quarter_step(struct MarioState *m, Vec3f intendedPos, u32 stepArg) {

Some files were not shown because too many files have changed in this diff Show more