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

@ -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

@ -43,4 +43,3 @@
.else .else
.byte 0x00 /* Version */ .byte 0x00 /* Version */
.endif .endif

394
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:
try:
import cxxfilt
except ModuleNotFoundError as e:
fail(MISSING_PREREQUISITES.format(e.name))
for binutils_cand in ["mips-linux-gnu-", "mips64-elf-"]: if objdump_executable is None:
for objdump_cand in ["mips-linux-gnu-objdump", "mips64-elf-objdump"]:
try: try:
subprocess.check_call( subprocess.check_call(
[binutils_cand + "objdump", "--version"], [objdump_cand, "--version"],
stdout=subprocess.DEVNULL, stdout=subprocess.DEVNULL,
stderr=subprocess.DEVNULL, stderr=subprocess.DEVNULL,
) )
binutils_prefix = binutils_cand objdump_executable = objdump_cand
break break
except subprocess.CalledProcessError: except subprocess.CalledProcessError:
pass pass
except FileNotFoundError: except FileNotFoundError:
pass pass
if not binutils_prefix: 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,10 +439,11 @@ def ansi_ljust(s, width):
return s return s
if arch == "mips":
re_int = re.compile(r"[0-9]+") re_int = re.compile(r"[0-9]+")
re_comments = re.compile(r"<.*?>") re_comment = re.compile(r"<.*?>")
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_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_sprel = re.compile(r",([0-9]+|0x[0-9a-f]+)\(sp\)") re_sprel = re.compile(r"(?<=,)([0-9]+|0x[0-9a-f]+)\(sp\)")
re_large_imm = re.compile(r"-?[1-9][0-9]{2,}|-?0x[0-9a-f]{3,}") re_large_imm = re.compile(r"-?[1-9][0-9]{2,}|-?0x[0-9a-f]{3,}")
re_imm = re.compile(r"(\b|-)([0-9]+|0x[0-9a-fA-F]+)\b(?!\(sp)|%(lo|hi)\([^)]*\)") re_imm = re.compile(r"(\b|-)([0-9]+|0x[0-9a-fA-F]+)\b(?!\(sp)|%(lo|hi)\([^)]*\)")
forbidden = set(string.ascii_letters + "_") forbidden = set(string.ascii_letters + "_")
@ -388,7 +462,22 @@ branch_likely_instructions = {
branch_instructions = branch_likely_instructions.union( branch_instructions = branch_likely_instructions.union(
{"b", "beq", "bne", "beqz", "bnez", "bgez", "bgtz", "blez", "bltz", "bc1t", "bc1f"} {"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)
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) 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):
if not same_relative_target:
# only imms differences # only imms differences
sym_color = Fore.LIGHTBLUE_EX sym_color = Fore.LIGHTBLUE_EX
line_prefix = "i" 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
@ -661,12 +661,11 @@
/* 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)
@ -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)) { } else {
eu_stubbed_printf_0("WARNING: NO FREE AUTOSEQ AREA.\n");
if ((firstVal == SOUND_LOAD_STATUS_DISCARDABLE) && (secondVal == SOUND_LOAD_STATUS_DISCARDABLE)) {
// 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) {
tp->nextSide = 0; tp->nextSide = 0;
} else if (secondVal == SOUND_LOAD_STATUS_DISCARDABLE) { } else if (secondVal == SOUND_LOAD_STATUS_DISCARDABLE) {
tp->nextSide = 1; tp->nextSide = 1;
} else if (firstVal != SOUND_LOAD_STATUS_IN_PROGRESS) { } 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; tp->nextSide = 0;
} else if (secondVal != SOUND_LOAD_STATUS_IN_PROGRESS) { } else if (secondVal != SOUND_LOAD_STATUS_IN_PROGRESS) {
tp->nextSide = 1; tp->nextSide = 1;
} else { } else {
// Both left and right sides are being loaded into. // Both left and right sides are being loaded into.
eu_stubbed_printf_0("TWO SIDES ARE LOADING... ALLOC CANCELED.\n");
return NULL; 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 {
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; 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

@ -8,6 +8,9 @@
#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
{ {
/*0x00*/ f32 x, y, z; /*0x00*/ f32 x, y, z;

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;
} }
} }
@ -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,13 +20,15 @@ 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;
} }
} }
}
void one_up_loop_in_air(void) { void one_up_loop_in_air(void) {
if (o->oTimer < 5) { if (o->oTimer < 5) {

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,8 +370,7 @@ 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,8 +656,7 @@ 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;
} }
@ -837,11 +834,10 @@ 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) {
case ACT_DOUBLE_JUMP: case ACT_DOUBLE_JUMP:
@ -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,14 +1754,12 @@ 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 (gGlobalTimer & 1) { if ((m->invincTimer >= 3) && (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) {
if (flags & MARIO_WING_CAP) { if (flags & MARIO_WING_CAP) {
@ -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

@ -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,14 +1059,12 @@ 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++;
return FALSE; return FALSE;
@ -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,11 +2934,9 @@ 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,8 +119,7 @@ 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];
@ -139,7 +138,6 @@ void check_ledge_climb_down(struct MarioState *m) {
} }
} }
} }
}
void slide_bonk(struct MarioState *m, u32 fastAction, u32 slowAction) { void slide_bonk(struct MarioState *m, u32 fastAction, u32 slowAction) {
if (m->forwardVel > 16.0f) { if (m->forwardVel > 16.0f) {
@ -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,17 +240,13 @@ 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) {
play_character_sound_if_no_flag(m, CHAR_SOUND_YAWNING, MARIO_MARIO_SOUND_PLAYED); play_character_sound_if_no_flag(m, CHAR_SOUND_YAWNING, MARIO_MARIO_SOUND_PLAYED);
@ -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 FALSE;
return 0;
} }
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 FALSE;
return 0;
} }
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 0; return FALSE;
} }
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,23 +1057,19 @@ 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
@ -1091,23 +1077,19 @@ s32 act_first_person(struct MarioState *m) {
} }
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,8 +182,7 @@ 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;
@ -192,12 +191,11 @@ 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) {

View file

@ -22,7 +22,7 @@ struct MainPoolState {
u32 freeSpace; u32 freeSpace;
struct MainPoolBlock *listHeadL; struct MainPoolBlock *listHeadL;
struct MainPoolBlock *listHeadR; struct MainPoolBlock *listHeadR;
void *prev; struct MainPoolState *prev;
}; };
struct MainPoolBlock { struct MainPoolBlock {
@ -30,17 +30,17 @@ struct MainPoolBlock {
struct MainPoolBlock *next; struct MainPoolBlock *next;
}; };
struct MemoryPool {
u32 totalSpace;
struct MemoryBlock *firstBlock;
struct MemoryBlock *freeList;
};
struct MemoryBlock { struct MemoryBlock {
struct MemoryBlock *next; struct MemoryBlock *next;
u32 size; u32 size;
}; };
struct MemoryPool {
u32 totalSpace;
struct MemoryBlock *firstBlock;
struct MemoryBlock freeList;
};
extern uintptr_t sSegmentTable[32]; extern uintptr_t sSegmentTable[32];
extern u32 sPoolFreeSpace; extern u32 sPoolFreeSpace;
extern u8 *sPoolStart; extern u8 *sPoolStart;
@ -137,7 +137,8 @@ void *main_pool_alloc(u32 size, u32 side) {
/** /**
* Free a block of memory that was allocated from the pool. The block must be * Free a block of memory that was allocated from the pool. The block must be
* the most recently allocated block from its end of the pool. * the most recently allocated block from its end of the pool, otherwise all
* newer blocks are freed as well.
* Return the amount of free space left in the pool. * Return the amount of free space left in the pool.
*/ */
u32 main_pool_free(void *addr) { u32 main_pool_free(void *addr) {
@ -192,7 +193,7 @@ u32 main_pool_available(void) {
* in the pool. * in the pool.
*/ */
u32 main_pool_push_state(void) { u32 main_pool_push_state(void) {
void *prevState = gMainPoolState; struct MainPoolState *prevState = gMainPoolState;
u32 freeSpace = sPoolFreeSpace; u32 freeSpace = sPoolFreeSpace;
struct MainPoolBlock *lhead = sPoolListHeadL; struct MainPoolBlock *lhead = sPoolListHeadL;
struct MainPoolBlock *rhead = sPoolListHeadR; struct MainPoolBlock *rhead = sPoolListHeadR;
@ -305,13 +306,13 @@ struct MemoryPool *mem_pool_init(u32 size, u32 side) {
struct MemoryPool *pool = NULL; struct MemoryPool *pool = NULL;
size = ALIGN4(size); size = ALIGN4(size);
addr = main_pool_alloc(size + ALIGN16(sizeof(struct MemoryPool)), side); addr = main_pool_alloc(size + sizeof(struct MemoryPool), side);
if (addr != NULL) { if (addr != NULL) {
pool = (struct MemoryPool *) addr; pool = (struct MemoryPool *) addr;
pool->totalSpace = size; pool->totalSpace = size;
pool->firstBlock = (struct MemoryBlock *) ((u8 *) addr + ALIGN16(sizeof(struct MemoryPool))); pool->firstBlock = (struct MemoryBlock *) ((u8 *) addr + sizeof(struct MemoryPool));
pool->freeList = (struct MemoryBlock *) ((u8 *) addr + ALIGN16(sizeof(struct MemoryPool))); pool->freeList.next = (struct MemoryBlock *) ((u8 *) addr + sizeof(struct MemoryPool));
block = pool->firstBlock; block = pool->firstBlock;
block->next = NULL; block->next = NULL;
@ -324,7 +325,7 @@ struct MemoryPool *mem_pool_init(u32 size, u32 side) {
* Allocate from a memory pool. Return NULL if there is not enough space. * Allocate from a memory pool. Return NULL if there is not enough space.
*/ */
void *mem_pool_alloc(struct MemoryPool *pool, u32 size) { void *mem_pool_alloc(struct MemoryPool *pool, u32 size) {
struct MemoryBlock *freeBlock = (struct MemoryBlock *) &pool->freeList; struct MemoryBlock *freeBlock = &pool->freeList;
void *addr = NULL; void *addr = NULL;
size = ALIGN4(size) + sizeof(struct MemoryBlock); size = ALIGN4(size) + sizeof(struct MemoryBlock);
@ -352,20 +353,20 @@ void *mem_pool_alloc(struct MemoryPool *pool, u32 size) {
*/ */
void mem_pool_free(struct MemoryPool *pool, void *addr) { void mem_pool_free(struct MemoryPool *pool, void *addr) {
struct MemoryBlock *block = (struct MemoryBlock *) ((u8 *) addr - sizeof(struct MemoryBlock)); struct MemoryBlock *block = (struct MemoryBlock *) ((u8 *) addr - sizeof(struct MemoryBlock));
struct MemoryBlock *freeList = pool->freeList; struct MemoryBlock *freeList = pool->freeList.next;
if (pool->freeList == NULL) { if (pool->freeList.next == NULL) {
pool->freeList = block; pool->freeList.next = block;
block->next = NULL; block->next = NULL;
} else { } else {
if (block < pool->freeList) { if (block < pool->freeList.next) {
if ((u8 *) pool->freeList == (u8 *) block + block->size) { if ((u8 *) pool->freeList.next == (u8 *) block + block->size) {
block->size += freeList->size; block->size += freeList->size;
block->next = freeList->next; block->next = freeList->next;
pool->freeList = block; pool->freeList.next = block;
} else { } else {
block->next = pool->freeList; block->next = pool->freeList.next;
pool->freeList = block; pool->freeList.next = block;
} }
} else { } else {
while (freeList->next != NULL) { while (freeList->next != NULL) {

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