mirror of
https://github.com/zeldaret/oot.git
synced 2025-07-03 22:44:30 +00:00
Merge branch 'main' into doc_pause_menu
This commit is contained in:
commit
20c7fdeda6
81 changed files with 2616 additions and 454 deletions
3
.gitignore
vendored
3
.gitignore
vendored
|
@ -10,12 +10,14 @@ __pycache__/
|
|||
CMakeLists.txt
|
||||
cmake-build-debug
|
||||
venv/
|
||||
.venv/
|
||||
|
||||
# Project-specific ignores
|
||||
build/
|
||||
expected/
|
||||
notes/
|
||||
baserom/
|
||||
baseroms/*/segments/
|
||||
docs/doxygen/
|
||||
*.elf
|
||||
*.sra
|
||||
|
@ -25,6 +27,7 @@ docs/doxygen/
|
|||
*.map
|
||||
*.dump
|
||||
out.txt
|
||||
*.ram
|
||||
|
||||
# Tool artifacts
|
||||
tools/mipspro7.2_compiler/
|
||||
|
|
4
Jenkinsfile
vendored
4
Jenkinsfile
vendored
|
@ -6,7 +6,7 @@ pipeline {
|
|||
stages {
|
||||
stage('Setup') {
|
||||
steps {
|
||||
sh 'cp /usr/local/etc/roms/baserom_oot.z64 baserom_original.z64'
|
||||
sh 'cp /usr/local/etc/roms/baserom_oot.z64 baseroms/gc-eu-mq-dbg/baserom.z64'
|
||||
sh 'make -j setup'
|
||||
}
|
||||
}
|
||||
|
@ -15,7 +15,7 @@ pipeline {
|
|||
branch 'main'
|
||||
}
|
||||
steps {
|
||||
sh 'ORIG_COMPILER=1 make -j'
|
||||
sh 'make -j ORIG_COMPILER=1'
|
||||
}
|
||||
}
|
||||
stage('Build') {
|
||||
|
|
73
Makefile
73
Makefile
|
@ -17,6 +17,8 @@ COMPILER := ido
|
|||
# Target game version. Currently only the following version is supported:
|
||||
# gc-eu-mq-dbg GameCube Europe/PAL Master Quest Debug (default)
|
||||
VERSION := gc-eu-mq-dbg
|
||||
# Number of threads to extract and compress with
|
||||
N_THREADS := $(shell nproc)
|
||||
|
||||
CFLAGS ?=
|
||||
CPPFLAGS ?=
|
||||
|
@ -53,6 +55,7 @@ endif
|
|||
|
||||
PROJECT_DIR := $(dir $(realpath $(firstword $(MAKEFILE_LIST))))
|
||||
BUILD_DIR := build/$(VERSION)
|
||||
VENV := .venv
|
||||
|
||||
MAKE = make
|
||||
CFLAGS += -DOOT_DEBUG
|
||||
|
@ -72,8 +75,6 @@ else
|
|||
endif
|
||||
endif
|
||||
|
||||
N_THREADS := $(shell nproc)
|
||||
|
||||
#### Tools ####
|
||||
ifneq ($(shell type $(MIPS_BINUTILS_PREFIX)ld >/dev/null 2>/dev/null; echo $$?), 0)
|
||||
$(error Unable to find $(MIPS_BINUTILS_PREFIX)ld. Please install or build MIPS binutils, commonly mips-linux-gnu. (or set MIPS_BINUTILS_PREFIX if your MIPS binutils install uses another prefix))
|
||||
|
@ -105,6 +106,7 @@ AS := $(MIPS_BINUTILS_PREFIX)as
|
|||
LD := $(MIPS_BINUTILS_PREFIX)ld
|
||||
OBJCOPY := $(MIPS_BINUTILS_PREFIX)objcopy
|
||||
OBJDUMP := $(MIPS_BINUTILS_PREFIX)objdump
|
||||
NM := $(MIPS_BINUTILS_PREFIX)nm
|
||||
|
||||
N64_EMULATOR ?=
|
||||
|
||||
|
@ -119,6 +121,7 @@ MKDMADATA := tools/mkdmadata
|
|||
ELF2ROM := tools/elf2rom
|
||||
ZAPD := tools/ZAPD/ZAPD.out
|
||||
FADO := tools/fado/fado.elf
|
||||
PYTHON ?= $(VENV)/bin/python3
|
||||
|
||||
# Command to replace path variables in the spec file. We can't use the C
|
||||
# preprocessor for this because it won't substitute inside string literals.
|
||||
|
@ -161,6 +164,7 @@ OBJDUMP_FLAGS := -d -r -z -Mreg-names=32
|
|||
#### Files ####
|
||||
|
||||
# ROM image
|
||||
ROMC := oot-$(VERSION)-compressed.z64
|
||||
ROM := oot-$(VERSION).z64
|
||||
ELF := $(ROM:.z64=.elf)
|
||||
# description of ROM segments
|
||||
|
@ -184,9 +188,10 @@ UNDECOMPILED_DATA_DIRS := $(shell find data -type d)
|
|||
# source files
|
||||
C_FILES := $(filter-out %.inc.c,$(foreach dir,$(SRC_DIRS) $(ASSET_BIN_DIRS),$(wildcard $(dir)/*.c)))
|
||||
S_FILES := $(foreach dir,$(SRC_DIRS) $(UNDECOMPILED_DATA_DIRS),$(wildcard $(dir)/*.s))
|
||||
BASEROM_BIN_FILES := $(wildcard baseroms/$(VERSION)/segments/*)
|
||||
O_FILES := $(foreach f,$(S_FILES:.s=.o),$(BUILD_DIR)/$f) \
|
||||
$(foreach f,$(C_FILES:.c=.o),$(BUILD_DIR)/$f) \
|
||||
$(foreach f,$(wildcard baserom/*),$(BUILD_DIR)/$f.o)
|
||||
$(foreach f,$(BASEROM_BIN_FILES),$(BUILD_DIR)/baserom/$(notdir $f).o)
|
||||
|
||||
OVL_RELOC_FILES := $(shell $(CPP) $(CPPFLAGS) $(SPEC) | $(SPEC_REPLACE_VARS) | grep -o '[^"]*_reloc.o' )
|
||||
|
||||
|
@ -246,11 +251,11 @@ $(BUILD_DIR)/src/libultra/rmon/%.o: CC := $(CC_OLD)
|
|||
$(BUILD_DIR)/src/code/jpegutils.o: CC := $(CC_OLD)
|
||||
$(BUILD_DIR)/src/code/jpegdecoder.o: CC := $(CC_OLD)
|
||||
|
||||
$(BUILD_DIR)/src/boot/%.o: CC := python3 tools/asm_processor/build.py $(CC) -- $(AS) $(ASFLAGS) --
|
||||
$(BUILD_DIR)/src/code/%.o: CC := python3 tools/asm_processor/build.py $(CC) -- $(AS) $(ASFLAGS) --
|
||||
$(BUILD_DIR)/src/overlays/%.o: CC := python3 tools/asm_processor/build.py $(CC) -- $(AS) $(ASFLAGS) --
|
||||
$(BUILD_DIR)/src/boot/%.o: CC := $(PYTHON) tools/asm_processor/build.py $(CC) -- $(AS) $(ASFLAGS) --
|
||||
$(BUILD_DIR)/src/code/%.o: CC := $(PYTHON) tools/asm_processor/build.py $(CC) -- $(AS) $(ASFLAGS) --
|
||||
$(BUILD_DIR)/src/overlays/%.o: CC := $(PYTHON) tools/asm_processor/build.py $(CC) -- $(AS) $(ASFLAGS) --
|
||||
|
||||
$(BUILD_DIR)/assets/%.o: CC := python3 tools/asm_processor/build.py $(CC) -- $(AS) $(ASFLAGS) --
|
||||
$(BUILD_DIR)/assets/%.o: CC := $(PYTHON) tools/asm_processor/build.py $(CC) -- $(AS) $(ASFLAGS) --
|
||||
else
|
||||
$(BUILD_DIR)/src/libultra/libc/ll.o: OPTFLAGS := -Ofast
|
||||
$(BUILD_DIR)/src/%.o: CC := $(CC) -fexec-charset=euc-jp
|
||||
|
@ -258,14 +263,22 @@ endif
|
|||
|
||||
#### Main Targets ###
|
||||
|
||||
all: $(ROM)
|
||||
ifeq ($(COMPARE),1)
|
||||
all: rom compress
|
||||
|
||||
rom: $(ROM)
|
||||
ifneq ($(COMPARE),0)
|
||||
@md5sum $(ROM)
|
||||
@md5sum -c checksum.md5
|
||||
@md5sum -c baseroms/$(VERSION)/checksum.md5
|
||||
endif
|
||||
|
||||
compress: $(ROMC)
|
||||
ifneq ($(COMPARE),0)
|
||||
@md5sum $(ROMC)
|
||||
@md5sum -c baseroms/$(VERSION)/checksum-compressed.md5
|
||||
endif
|
||||
|
||||
clean:
|
||||
$(RM) -r $(ROM) $(ELF) $(BUILD_DIR)
|
||||
$(RM) -r $(ROMC) $(ROM) $(ELF) $(BUILD_DIR)
|
||||
|
||||
assetclean:
|
||||
$(RM) -r $(ASSET_BIN_DIRS)
|
||||
|
@ -274,14 +287,19 @@ assetclean:
|
|||
$(RM) -r .extracted-assets.json
|
||||
|
||||
distclean: clean assetclean
|
||||
$(RM) -r baserom/
|
||||
$(RM) -r baseroms/$(VERSION)/segments
|
||||
$(MAKE) -C tools distclean
|
||||
|
||||
setup:
|
||||
venv:
|
||||
test -d $(VENV) || python3 -m venv $(VENV)
|
||||
$(PYTHON) -m pip install -U pip
|
||||
$(PYTHON) -m pip install -U -r requirements.txt
|
||||
|
||||
setup: venv
|
||||
$(MAKE) -C tools
|
||||
python3 fixbaserom.py
|
||||
python3 extract_baserom.py
|
||||
python3 extract_assets.py -j$(N_THREADS)
|
||||
$(PYTHON) tools/decompress_baserom.py $(VERSION)
|
||||
$(PYTHON) extract_baserom.py
|
||||
$(PYTHON) extract_assets.py -j$(N_THREADS)
|
||||
|
||||
run: $(ROM)
|
||||
ifeq ($(N64_EMULATOR),)
|
||||
|
@ -290,13 +308,19 @@ endif
|
|||
$(N64_EMULATOR) $<
|
||||
|
||||
|
||||
.PHONY: all clean setup run distclean assetclean
|
||||
.PHONY: all rom compress clean assetclean distclean venv setup run
|
||||
.DEFAULT_GOAL := rom
|
||||
|
||||
#### Various Recipes ####
|
||||
|
||||
$(ROM): $(ELF)
|
||||
$(ELF2ROM) -cic 6105 $< $@
|
||||
|
||||
$(ROMC): $(ROM) $(ELF) $(BUILD_DIR)/compress_ranges.txt
|
||||
# note: $(BUILD_DIR)/compress_ranges.txt should only be used for nonmatching builds. it works by chance for matching builds too though
|
||||
$(PYTHON) tools/compress.py --in $(ROM) --out $@ --dma-range `./tools/dmadata_range.sh $(NM) $(ELF)` --compress `cat $(BUILD_DIR)/compress_ranges.txt` --threads $(N_THREADS)
|
||||
$(PYTHON) -m ipl3checksum sum --cic 6105 --update $@
|
||||
|
||||
$(ELF): $(TEXTURE_FILES_OUT) $(ASSET_FILES_OUT) $(O_FILES) $(OVL_RELOC_FILES) $(BUILD_DIR)/ldscript.txt $(BUILD_DIR)/undefined_syms.txt
|
||||
$(LD) -T $(BUILD_DIR)/undefined_syms.txt -T $(BUILD_DIR)/ldscript.txt --no-check-sections --accept-unknown-input-arch --emit-relocs -Map $(BUILD_DIR)/z64.map -o $@
|
||||
|
||||
|
@ -321,14 +345,14 @@ $(BUILD_DIR)/ldscript.txt: $(BUILD_DIR)/$(SPEC)
|
|||
$(BUILD_DIR)/undefined_syms.txt: undefined_syms.txt
|
||||
$(CPP) $(CPPFLAGS) $< > $@
|
||||
|
||||
$(BUILD_DIR)/baserom/%.o: baserom/%
|
||||
$(BUILD_DIR)/baserom/%.o: baseroms/$(VERSION)/segments/%
|
||||
$(OBJCOPY) -I binary -O elf32-big $< $@
|
||||
|
||||
$(BUILD_DIR)/data/%.o: data/%.s
|
||||
$(AS) $(ASFLAGS) $< -o $@
|
||||
|
||||
$(BUILD_DIR)/assets/text/%.enc.h: assets/text/%.h assets/text/charmap.txt
|
||||
python3 tools/msgenc.py assets/text/charmap.txt $< $@
|
||||
$(PYTHON) tools/msgenc.py assets/text/charmap.txt $< $@
|
||||
|
||||
# Dependencies for files including message data headers
|
||||
# TODO remove when full header dependencies are used.
|
||||
|
@ -345,8 +369,8 @@ $(BUILD_DIR)/assets/%.o: assets/%.c
|
|||
$(BUILD_DIR)/src/%.o: src/%.s
|
||||
$(CPP) $(CPPFLAGS) -Iinclude $< | $(AS) $(ASFLAGS) -o $@
|
||||
|
||||
$(BUILD_DIR)/dmadata_table_spec.h: $(BUILD_DIR)/$(SPEC)
|
||||
$(MKDMADATA) $< $@
|
||||
$(BUILD_DIR)/dmadata_table_spec.h $(BUILD_DIR)/compress_ranges.txt: $(BUILD_DIR)/$(SPEC)
|
||||
$(MKDMADATA) $< $(BUILD_DIR)/dmadata_table_spec.h $(BUILD_DIR)/compress_ranges.txt
|
||||
|
||||
# Dependencies for files that may include the dmadata header automatically generated from the spec file
|
||||
$(BUILD_DIR)/src/boot/z_std_dma.o: $(BUILD_DIR)/dmadata_table_spec.h
|
||||
|
@ -370,13 +394,13 @@ $(BUILD_DIR)/src/%.o: src/%.c
|
|||
$(BUILD_DIR)/src/libultra/libc/ll.o: src/libultra/libc/ll.c
|
||||
$(CC_CHECK) $<
|
||||
$(CC) -c $(CFLAGS) $(MIPS_VERSION) $(OPTFLAGS) -o $@ $<
|
||||
python3 tools/set_o32abi_bit.py $@
|
||||
$(PYTHON) tools/set_o32abi_bit.py $@
|
||||
@$(OBJDUMP) $(OBJDUMP_FLAGS) $@ > $(@:.o=.s)
|
||||
|
||||
$(BUILD_DIR)/src/libultra/libc/llcvt.o: src/libultra/libc/llcvt.c
|
||||
$(CC_CHECK) $<
|
||||
$(CC) -c $(CFLAGS) $(MIPS_VERSION) $(OPTFLAGS) -o $@ $<
|
||||
python3 tools/set_o32abi_bit.py $@
|
||||
$(PYTHON) tools/set_o32abi_bit.py $@
|
||||
@$(OBJDUMP) $(OBJDUMP_FLAGS) $@ > $(@:.o=.s)
|
||||
|
||||
$(BUILD_DIR)/src/overlays/%_reloc.o: $(BUILD_DIR)/$(SPEC)
|
||||
|
@ -393,3 +417,6 @@ $(BUILD_DIR)/assets/%.jpg.inc.c: assets/%.jpg
|
|||
$(ZAPD) bren -eh -i $< -o $@
|
||||
|
||||
-include $(DEP_FILES)
|
||||
|
||||
# Print target for debugging
|
||||
print-% : ; $(info $* is a $(flavor $*) variable set to [$($*)]) @true
|
||||
|
|
13
README.md
13
README.md
|
@ -68,13 +68,15 @@ The build process has the following package requirements:
|
|||
* build-essential
|
||||
* binutils-mips-linux-gnu
|
||||
* python3
|
||||
* python3-pip
|
||||
* python3-venv
|
||||
* libpng-dev
|
||||
|
||||
Under Debian / Ubuntu (which we recommend using), you can install them with the following commands:
|
||||
|
||||
```bash
|
||||
sudo apt-get update
|
||||
sudo apt-get install git build-essential binutils-mips-linux-gnu python3 libpng-dev
|
||||
sudo apt-get install git build-essential binutils-mips-linux-gnu python3 python3-pip python3-venv libpng-dev
|
||||
```
|
||||
|
||||
If you are using GCC as the compiler for Ocarina of Time, you will also need:
|
||||
|
@ -100,8 +102,9 @@ cd oot
|
|||
|
||||
#### 3. Prepare a base ROM
|
||||
|
||||
Copy over your copy of the Master Quest (Debug) ROM inside the root of this new project directory.
|
||||
Rename the file to "baserom_original.z64", "baserom_original.n64" or "baserom_original.v64", depending on the original extension.
|
||||
Place a copy of the Master Quest (Debug) ROM inside the `baseroms/gc-eu-mq-dbg/` folder.
|
||||
|
||||
Rename the file to `baserom.z64`, `baserom.n64` or `baserom.v64`, depending on the original extension.
|
||||
|
||||
#### 4. Setup the ROM and build process
|
||||
|
||||
|
@ -111,7 +114,8 @@ Setup and extract everything from your ROM with the following command:
|
|||
make setup
|
||||
```
|
||||
|
||||
This will generate a new ROM called "baserom.z64" that will have the overdump removed and the header patched.
|
||||
This downloads some dependencies (from pip), and compiles tools for the build process.
|
||||
Then it generates a new ROM "baseroms/gc-eu-mq-dbg/baserom-decompressed.z64" that will have the overdump removed and the header patched.
|
||||
It will also extract the individual assets from the ROM.
|
||||
|
||||
#### 5. Build the ROM
|
||||
|
@ -145,7 +149,6 @@ This means that the built ROM isn't the same as the base one, so something went
|
|||
|
||||
Both of these have the disadvantage that the ordering of the terminal output is scrambled, so for debugging it is best to stick to one thread (i.e. not pass `-j` or `-jN`).
|
||||
|
||||
|
||||
## Contributing
|
||||
|
||||
All contributions are welcome. This is a group effort, and even small contributions can make a difference.
|
||||
|
|
1
baseroms/gc-eu-mq-dbg/checksum-compressed.md5
Normal file
1
baseroms/gc-eu-mq-dbg/checksum-compressed.md5
Normal file
|
@ -0,0 +1 @@
|
|||
5831385a7f216370cdbea55616b12fed oot-gc-eu-mq-dbg-compressed.z64
|
|
@ -10,13 +10,13 @@
|
|||
.balign 16
|
||||
|
||||
glabel gSoundFontTable
|
||||
.incbin "baserom.z64", 0xBCC270, 0x270
|
||||
.incbin "baseroms/gc-eu-mq-dbg/baserom-decompressed.z64", 0xBCC270, 0x270
|
||||
|
||||
glabel gSequenceFontTable
|
||||
.incbin "baserom.z64", 0xBCC4E0, 0x1C0
|
||||
.incbin "baseroms/gc-eu-mq-dbg/baserom-decompressed.z64", 0xBCC4E0, 0x1C0
|
||||
|
||||
glabel gSequenceTable
|
||||
.incbin "baserom.z64", 0xBCC6A0, 0x6F0
|
||||
.incbin "baseroms/gc-eu-mq-dbg/baserom-decompressed.z64", 0xBCC6A0, 0x6F0
|
||||
|
||||
glabel gSampleBankTable
|
||||
.incbin "baserom.z64", 0xBCCD90, 0x80
|
||||
.incbin "baseroms/gc-eu-mq-dbg/baserom-decompressed.z64", 0xBCCD90, 0x80
|
||||
|
|
|
@ -10,21 +10,21 @@
|
|||
.balign 16
|
||||
|
||||
glabel aspMainDataStart
|
||||
.incbin "baserom.z64", 0xBCCE10, 0x2E0
|
||||
.incbin "baseroms/gc-eu-mq-dbg/baserom-decompressed.z64", 0xBCCE10, 0x2E0
|
||||
glabel aspMainDataEnd
|
||||
|
||||
glabel gspF3DZEX2_NoN_PosLight_fifoTextStart
|
||||
.incbin "baserom.z64", 0xBCD0F0, 0x1630
|
||||
.incbin "baseroms/gc-eu-mq-dbg/baserom-decompressed.z64", 0xBCD0F0, 0x1630
|
||||
glabel gspF3DZEX2_NoN_PosLight_fifoTextEnd
|
||||
|
||||
glabel gspF3DZEX2_NoN_PosLight_fifoDataStart
|
||||
.incbin "baserom.z64", 0xBCE720, 0x420
|
||||
.incbin "baseroms/gc-eu-mq-dbg/baserom-decompressed.z64", 0xBCE720, 0x420
|
||||
glabel gspF3DZEX2_NoN_PosLight_fifoDataEnd
|
||||
|
||||
glabel gspS2DEX2d_fifoDataStart
|
||||
.incbin "baserom.z64", 0xBCEB40, 0x390
|
||||
.incbin "baseroms/gc-eu-mq-dbg/baserom-decompressed.z64", 0xBCEB40, 0x390
|
||||
glabel gspS2DEX2d_fifoDataEnd
|
||||
|
||||
glabel njpgdspMainDataStart
|
||||
.incbin "baserom.z64", 0xBCEED0, 0x60
|
||||
.incbin "baseroms/gc-eu-mq-dbg/baserom-decompressed.z64", 0xBCEED0, 0x60
|
||||
glabel njpgdspMainDataEnd
|
||||
|
|
|
@ -10,13 +10,13 @@
|
|||
.balign 16
|
||||
|
||||
glabel aspMainTextStart
|
||||
.incbin "baserom.z64", 0xB89260, 0xFB0
|
||||
.incbin "baseroms/gc-eu-mq-dbg/baserom-decompressed.z64", 0xB89260, 0xFB0
|
||||
glabel aspMainTextEnd
|
||||
|
||||
glabel gspS2DEX2d_fifoTextStart
|
||||
.incbin "baserom.z64", 0xB8A210, 0x18C0
|
||||
.incbin "baseroms/gc-eu-mq-dbg/baserom-decompressed.z64", 0xB8A210, 0x18C0
|
||||
glabel gspS2DEX2d_fifoTextEnd
|
||||
|
||||
glabel njpgdspMainTextStart
|
||||
.incbin "baserom.z64", 0xB8BAD0, 0xAF0
|
||||
.incbin "baseroms/gc-eu-mq-dbg/baserom-decompressed.z64", 0xB8BAD0, 0xAF0
|
||||
glabel njpgdspMainTextEnd
|
||||
|
|
|
@ -10,5 +10,5 @@
|
|||
.balign 16
|
||||
|
||||
glabel rspbootTextStart
|
||||
.incbin "baserom.z64", 0x9F20, 0xD0
|
||||
.incbin "baseroms/gc-eu-mq-dbg/baserom-decompressed.z64", 0x9F20, 0xD0
|
||||
glabel rspbootTextEnd
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
# temporary file name, rename to something more appropriate when decompiled
|
||||
|
||||
glabel gMojiFontTLUTs
|
||||
.incbin "baserom.z64", 0xBA18E0, 0x80
|
||||
.incbin "baseroms/gc-eu-mq-dbg/baserom-decompressed.z64", 0xBA18E0, 0x80
|
||||
|
||||
glabel gMojiFontTex
|
||||
.incbin "baserom.z64", 0xBA1960, 0x400
|
||||
.incbin "baseroms/gc-eu-mq-dbg/baserom-decompressed.z64", 0xBA1960, 0x400
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
def apply(config, args):
|
||||
config['mapfile'] = 'build/gc-eu-mq-dbg/z64.map'
|
||||
config['myimg'] = 'oot-gc-eu-mq-dbg.z64'
|
||||
config['baseimg'] = 'baserom.z64'
|
||||
config['baseimg'] = 'baseroms/gc-eu-mq-dbg/baserom-decompressed.z64'
|
||||
config['makeflags'] = []
|
||||
config['source_directories'] = ['src', 'include', 'spec']
|
||||
|
|
|
@ -229,7 +229,7 @@ which initialises common properties of actor using an InitChain, which is usuall
|
|||
The InitChain script is also in the tools directory, and is called `ichaindis.py`. Simply passing it the ROM address will spit out the entire contents of the InitChain, in this case:
|
||||
|
||||
```
|
||||
$ ./tools/ichaindis.py baserom.z64 80A88CE0
|
||||
$ ./tools/ichaindis.py baseroms/gc-eu-mq-dbg/baserom-decompressed.z64 80A88CE0
|
||||
static InitChainEntry sInitChain[] = {
|
||||
ICHAIN_VEC3F_DIV1000(unk_50, 87, ICHAIN_CONTINUE),
|
||||
ICHAIN_F32(unk_F4, 4000, ICHAIN_CONTINUE),
|
||||
|
@ -240,7 +240,7 @@ static InitChainEntry sInitChain[] = {
|
|||
|
||||
However, some of these variables have now been given names in the Actor struct. Pass it `--names` to fill these in automatically:
|
||||
```
|
||||
$ ./tools/ichaindis.py --names baserom.z64 80A88CE0
|
||||
$ ./tools/ichaindis.py --names baseroms/gc-eu-mq-dbg/baserom-decompressed.z64 80A88CE0
|
||||
static InitChainEntry sInitChain[] = {
|
||||
ICHAIN_VEC3F_DIV1000(scale, 87, ICHAIN_CONTINUE),
|
||||
ICHAIN_F32(uncullZoneForward, 4000, ICHAIN_CONTINUE),
|
||||
|
|
|
@ -557,7 +557,7 @@ Ignore the first line: `gDmaDataTable` is always different if the ROM is shifted
|
|||
|
||||
To fix this, we use a binary diff program. A suitable one is `vbindiff`: run it on the baserom and the zelda_whatever one the compiler generates:
|
||||
```
|
||||
vbindiff baserom.z64 oot-gc-eu-mq-dbg.z64
|
||||
vbindiff baseroms/gc-eu-mq-dbg/baserom-decompressed.z64 oot-gc-eu-mq-dbg.z64
|
||||
```
|
||||
In this, press `g` to open up goto position, and paste in the address `0xE3ED10` from the first important line of the `first_diff` output. This gives us the following:
|
||||
|
||||
|
|
|
@ -2,6 +2,27 @@
|
|||
|
||||
This list gives brief information on the most common usage cases. For more information, first try using `-h` or `--help` as an argument, and failing that, ask in #oot-decomp-help or #tools-other in the Discord.
|
||||
|
||||
Many tools require activating a Python virtual environment that contains Python
|
||||
dependencies. This virtual environment is automatically installed into the
|
||||
`.venv` directory by `make setup`, but you need to **activate** it in your
|
||||
current terminal session in order to run Python tools. To start using the
|
||||
virtual environment in your current terminal run:
|
||||
|
||||
```bash
|
||||
source .venv/bin/activate
|
||||
```
|
||||
|
||||
Keep in mind that for each new terminal session, you will need to activate the
|
||||
Python virtual environment again. That is, run the above `source .venv/bin/activate` command.
|
||||
|
||||
To deactivate the virtual environment, run
|
||||
|
||||
```bash
|
||||
deactivate
|
||||
```
|
||||
|
||||
and your terminal session state will be restored to what it was before.
|
||||
|
||||
## m2ctx
|
||||
|
||||
This generates the context for mips2c to use to type objects in its output. It lives in the tools directory. Running
|
||||
|
|
|
@ -74,7 +74,7 @@ Add the following to (or create) the `.vscode/settings.json` file for VSCode to
|
|||
"search.useIgnoreFiles": false,
|
||||
"search.exclude": {
|
||||
"**/.git": true,
|
||||
"baserom/**": true,
|
||||
"baseroms/**": true,
|
||||
"build/**": true,
|
||||
"expected/**": true,
|
||||
},
|
||||
|
|
|
@ -28,7 +28,7 @@ def ExtractFile(xmlPath, outputPath, outputSourcePath):
|
|||
Path(outputPath).mkdir(parents=True, exist_ok=True)
|
||||
Path(outputSourcePath).mkdir(parents=True, exist_ok=True)
|
||||
|
||||
execStr = f"{zapdPath} e -eh -i {xmlPath} -b baserom -o {outputPath} -osf {outputSourcePath} -gsf 1 -rconf {configPath} {ZAPDArgs}"
|
||||
execStr = f"{zapdPath} e -eh -i {xmlPath} -b baseroms/gc-eu-mq-dbg/segments -o {outputPath} -osf {outputSourcePath} -gsf 1 -rconf {configPath} {ZAPDArgs}"
|
||||
|
||||
if "overlays" in xmlPath:
|
||||
execStr += " --static"
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
#!/usr/bin/python3
|
||||
|
||||
import os
|
||||
import sys
|
||||
import struct
|
||||
from multiprocessing import Pool, cpu_count
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
ROM_FILE_NAME = 'baserom.z64'
|
||||
ROM_FILE_PATH = Path('baseroms/gc-eu-mq-dbg/baserom-decompressed.z64')
|
||||
SEGMENTS_PATH = Path('baseroms/gc-eu-mq-dbg/segments/')
|
||||
FILE_TABLE_OFFSET = 0x12F70
|
||||
|
||||
FILE_NAMES = [
|
||||
|
@ -1562,7 +1562,7 @@ def write_output_file(name, offset, size):
|
|||
print('failed to write file ' + name)
|
||||
|
||||
def ExtractFunc(i):
|
||||
filename = 'baserom/' + FILE_NAMES[i]
|
||||
filename = SEGMENTS_PATH / FILE_NAMES[i]
|
||||
entryOffset = FILE_TABLE_OFFSET + 16 * i
|
||||
|
||||
virtStart = read_uint32_be(entryOffset + 0)
|
||||
|
@ -1571,32 +1571,24 @@ def ExtractFunc(i):
|
|||
physEnd = read_uint32_be(entryOffset + 12)
|
||||
|
||||
if physEnd == 0: # uncompressed
|
||||
compressed = False
|
||||
size = virtEnd - virtStart
|
||||
else: # compressed
|
||||
compressed = True
|
||||
size = physEnd - physStart
|
||||
|
||||
print('extracting ' + filename + " (0x%08X, 0x%08X)" % (virtStart, virtEnd))
|
||||
print(f'extracting {filename} (0x{virtStart:08X}, 0x{virtEnd:08X})')
|
||||
write_output_file(filename, physStart, size)
|
||||
if compressed:
|
||||
os.system('tools/yaz0 -d ' + filename + ' ' + filename)
|
||||
|
||||
#####################################################################
|
||||
|
||||
def main():
|
||||
try:
|
||||
os.mkdir('baserom')
|
||||
except:
|
||||
pass
|
||||
SEGMENTS_PATH.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
# read baserom data
|
||||
try:
|
||||
with open(ROM_FILE_NAME, 'rb') as f:
|
||||
rom_data = f.read()
|
||||
rom_data = ROM_FILE_PATH.read_bytes()
|
||||
except IOError:
|
||||
print('failed to read file' + ROM_FILE_NAME)
|
||||
sys.exit(1)
|
||||
print(f'failed to read file {ROM_FILE_PATH}')
|
||||
exit(1)
|
||||
|
||||
# extract files
|
||||
num_cores = cpu_count()
|
||||
|
|
|
@ -3,17 +3,8 @@
|
|||
import argparse
|
||||
from pathlib import Path
|
||||
|
||||
try:
|
||||
import rabbitizer
|
||||
except ImportError:
|
||||
print("Missing dependency rabbitizer, install it with `python3 -m pip install 'rabbitizer>=1.0.0,<2.0.0'`")
|
||||
exit(1)
|
||||
|
||||
try:
|
||||
import mapfile_parser
|
||||
except ImportError:
|
||||
print("Missing dependency mapfile_parser, install it with `python3 -m pip install 'mapfile-parser>=1.2.1,<2.0.0'`")
|
||||
exit(1)
|
||||
import rabbitizer
|
||||
import mapfile_parser
|
||||
|
||||
|
||||
def decodeInstruction(bytesDiff: bytes, mapFile: mapfile_parser.MapFile) -> str:
|
||||
|
@ -49,7 +40,7 @@ def firstDiffMain():
|
|||
BUILTROM = Path(f"oot-{args.version}.z64")
|
||||
BUILTMAP = buildFolder / "z64.map"
|
||||
|
||||
EXPECTEDROM = Path("baserom.z64")
|
||||
EXPECTEDROM = Path(f"baseroms/{args.version}/baserom-decompressed.z64")
|
||||
EXPECTEDMAP = "expected" / BUILTMAP
|
||||
|
||||
mapfile_parser.frontends.first_diff.doFirstDiff(BUILTMAP, EXPECTEDMAP, BUILTROM, EXPECTEDROM, args.count, mismatchSize=True, addColons=args.add_colons, bytesConverterCallback=decodeInstruction)
|
||||
|
|
|
@ -1,96 +0,0 @@
|
|||
from os import path
|
||||
import sys
|
||||
import struct
|
||||
import hashlib
|
||||
|
||||
|
||||
def get_str_hash(byte_array):
|
||||
return str(hashlib.md5(byte_array).hexdigest())
|
||||
|
||||
|
||||
# If the baserom exists and is correct, we don't need to change anything
|
||||
if path.exists("baserom.z64"):
|
||||
with open("baserom.z64", mode="rb") as file:
|
||||
fileContent = bytearray(file.read())
|
||||
if get_str_hash(fileContent) == "f0b7f35375f9cc8ca1b2d59d78e35405":
|
||||
print("Found valid baserom - exiting early")
|
||||
sys.exit(0)
|
||||
|
||||
# Determine if we have a ROM file
|
||||
romFileExtensions = ["z64", "n64", "v64"]
|
||||
|
||||
def find_baserom_original():
|
||||
for romFileExtLower in romFileExtensions:
|
||||
for romFileExt in (romFileExtLower, romFileExtLower.upper()):
|
||||
romFileNameCandidate = "baserom_original." + romFileExt
|
||||
if path.exists(romFileNameCandidate):
|
||||
return romFileNameCandidate
|
||||
return None
|
||||
|
||||
romFileName = find_baserom_original()
|
||||
|
||||
if romFileName is None:
|
||||
print("Error: Could not find baserom_original.z64/baserom_original.n64/baserom_original.v64.")
|
||||
sys.exit(1)
|
||||
|
||||
# Read in the original ROM
|
||||
print("File '" + romFileName + "' found.")
|
||||
with open(romFileName, mode="rb") as file:
|
||||
fileContent = bytearray(file.read())
|
||||
|
||||
# Strip the overdump
|
||||
print("Stripping overdump...")
|
||||
fileContent = fileContent[0:0x3600000]
|
||||
|
||||
fileContentLen = len(fileContent)
|
||||
|
||||
# Check if ROM needs to be byte/word swapped
|
||||
# Little-endian
|
||||
if fileContent[0] == 0x40:
|
||||
# Word Swap ROM
|
||||
print("ROM needs to be word swapped...")
|
||||
words = str(int(fileContentLen/4))
|
||||
little_byte_format = "<" + words + "I"
|
||||
big_byte_format = ">" + words + "I"
|
||||
tmp = struct.unpack_from(little_byte_format, fileContent, 0)
|
||||
struct.pack_into(big_byte_format, fileContent, 0, *tmp)
|
||||
|
||||
print("Word swapping done.")
|
||||
|
||||
# Byte-swapped
|
||||
elif fileContent[0] == 0x37:
|
||||
# Byte Swap ROM
|
||||
print("ROM needs to be byte swapped...")
|
||||
halfwords = str(int(fileContentLen/2))
|
||||
little_byte_format = "<" + halfwords + "H"
|
||||
big_byte_format = ">" + halfwords + "H"
|
||||
tmp = struct.unpack_from(little_byte_format, fileContent, 0)
|
||||
struct.pack_into(big_byte_format, fileContent, 0, *tmp)
|
||||
|
||||
print("Byte swapping done.")
|
||||
|
||||
# Patch the header
|
||||
print("Patching header...")
|
||||
fileContent[0x3E] = 0x50
|
||||
|
||||
for i in range(0x35CF000, len(fileContent)):
|
||||
fileContent[i] = 0xFF
|
||||
|
||||
# Check to see if the ROM is a "vanilla" Debug ROM
|
||||
str_hash = get_str_hash(bytearray(fileContent))
|
||||
if str_hash != "f0b7f35375f9cc8ca1b2d59d78e35405":
|
||||
print("Error: Expected a hash of f0b7f35375f9cc8ca1b2d59d78e35405 but got " + str_hash + ". " +
|
||||
"The baserom has probably been tampered, find a new one")
|
||||
|
||||
if str_hash == "32fe2770c0f9b1a9cd2a4d449348c1cb":
|
||||
print("The provided baserom is a rom which has been edited with ZeldaEdit and is not suitable for use with decomp. " +
|
||||
"Find a new one.")
|
||||
|
||||
sys.exit(1)
|
||||
|
||||
# Write out our new ROM
|
||||
print("Writing new ROM 'baserom.z64'.")
|
||||
with open("baserom.z64", mode="wb") as file:
|
||||
file.write(bytes(fileContent))
|
||||
|
||||
print("Done!")
|
|
@ -354,8 +354,9 @@ void Actor_MoveXZGravity(Actor* actor);
|
|||
void Actor_UpdateVelocityXYZ(Actor* actor);
|
||||
void Actor_MoveXYZ(Actor* actor);
|
||||
void Actor_SetProjectileSpeed(Actor* actor, f32 speedXYZ);
|
||||
s16 Actor_WorldYawTowardActor(Actor* actorA, Actor* actorB);
|
||||
s16 Actor_WorldYawTowardPoint(Actor* actor, Vec3f* refPoint);
|
||||
s16 Actor_WorldYawTowardActor(Actor* origin, Actor* target);
|
||||
s16 Actor_FocusYawTowardActor(Actor* origin, Actor* target);
|
||||
s16 Actor_WorldYawTowardPoint(Actor* origin, Vec3f* point);
|
||||
f32 Actor_WorldDistXYZToActor(Actor* actorA, Actor* actorB);
|
||||
f32 Actor_WorldDistXYZToPoint(Actor* actor, Vec3f* refPoint);
|
||||
s16 Actor_WorldPitchTowardActor(Actor* actorA, Actor* actorB);
|
||||
|
@ -856,7 +857,7 @@ void Math_Vec3f_Scale(Vec3f* vec, f32 scaleF);
|
|||
f32 Math_Vec3f_DistXYZ(Vec3f* a, Vec3f* b);
|
||||
f32 Math_Vec3f_DistXYZAndStoreDiff(Vec3f* a, Vec3f* b, Vec3f* dest);
|
||||
f32 Math_Vec3f_DistXZ(Vec3f* a, Vec3f* b);
|
||||
s16 Math_Vec3f_Yaw(Vec3f* a, Vec3f* b);
|
||||
s16 Math_Vec3f_Yaw(Vec3f* origin, Vec3f* point);
|
||||
s16 Math_Vec3f_Pitch(Vec3f* a, Vec3f* b);
|
||||
void Actor_ProcessInitChain(Actor* actor, InitChainEntry* ichain);
|
||||
f32 Math_SmoothStepToF(f32* pValue, f32 target, f32 fraction, f32 step, f32 minStep);
|
||||
|
|
|
@ -103,14 +103,14 @@
|
|||
#ifdef OOT_DEBUG
|
||||
#define PRINTF osSyncPrintf
|
||||
#else
|
||||
#ifdef __GNUC__
|
||||
#define PRINTF(format, ...) (void)0
|
||||
#else
|
||||
#ifdef __sgi /* IDO compiler */
|
||||
// IDO doesn't support variadic macros, but it merely throws a warning for the
|
||||
// number of arguments not matching the definition (warning 609) instead of
|
||||
// throwing an error. We suppress this warning and rely on GCC to catch macro
|
||||
// argument errors instead.
|
||||
#define PRINTF(args) (void)0
|
||||
#else
|
||||
#define PRINTF(format, ...) (void)0
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
@ -189,6 +189,8 @@ extern struct GraphicsContext* __gfxCtx;
|
|||
#define ZELDA_ARENA_MALLOC(size, file, line) ZeldaArena_MallocDebug(size, file, line)
|
||||
#define ZELDA_ARENA_MALLOC_R(size, file, line) ZeldaArena_MallocRDebug(size, file, line)
|
||||
#define ZELDA_ARENA_FREE(size, file, line) ZeldaArena_FreeDebug(size, file, line)
|
||||
#define LOG_UTILS_CHECK_NULL_POINTER(exp, ptr, file, line) LogUtils_CheckNullPointer(exp, ptr, file, line)
|
||||
#define LOG_UTILS_CHECK_VALID_POINTER(exp, ptr, file, line) LogUtils_CheckValidPointer(exp, ptr, file, line)
|
||||
|
||||
#else
|
||||
|
||||
|
@ -215,6 +217,8 @@ extern struct GraphicsContext* __gfxCtx;
|
|||
#define ZELDA_ARENA_MALLOC(size, file, line) ZeldaArena_Malloc(size)
|
||||
#define ZELDA_ARENA_MALLOC_R(size, file, line) ZeldaArena_MallocR(size)
|
||||
#define ZELDA_ARENA_FREE(size, file, line) ZeldaArena_Free(size)
|
||||
#define LOG_UTILS_CHECK_NULL_POINTER(exp, ptr, file, line) (void)0
|
||||
#define LOG_UTILS_CHECK_VALID_POINTER(exp, ptr, file, line) (void)0
|
||||
|
||||
#endif /* OOT_DEBUG */
|
||||
|
||||
|
|
|
@ -140,36 +140,90 @@ typedef struct {
|
|||
/* 0x18 */ Vec3f feetPos[2]; // Update by using `Actor_SetFeetPos` in PostLimbDraw
|
||||
} ActorShape; // size = 0x30
|
||||
|
||||
//
|
||||
#define ACTOR_FLAG_0 (1 << 0)
|
||||
|
||||
//
|
||||
#define ACTOR_FLAG_2 (1 << 2)
|
||||
|
||||
//
|
||||
#define ACTOR_FLAG_3 (1 << 3)
|
||||
|
||||
//
|
||||
#define ACTOR_FLAG_4 (1 << 4)
|
||||
|
||||
//
|
||||
#define ACTOR_FLAG_5 (1 << 5)
|
||||
|
||||
//
|
||||
#define ACTOR_FLAG_6 (1 << 6)
|
||||
#define ACTOR_FLAG_7 (1 << 7)
|
||||
|
||||
// hidden or revealed by Lens of Truth (depending on room lensMode)
|
||||
#define ACTOR_FLAG_REACT_TO_LENS (1 << 7)
|
||||
|
||||
// Signals that player has accepted an offer to talk to an actor
|
||||
// Player will retain this flag until the player is finished talking
|
||||
// Actor will retain this flag until `Actor_TalkOfferAccepted` is called or manually turned off by the actor
|
||||
#define ACTOR_FLAG_TALK (1 << 8)
|
||||
|
||||
//
|
||||
#define ACTOR_FLAG_9 (1 << 9)
|
||||
|
||||
//
|
||||
#define ACTOR_FLAG_10 (1 << 10)
|
||||
|
||||
//
|
||||
#define ACTOR_FLAG_ENKUSA_CUT (1 << 11)
|
||||
#define ACTOR_FLAG_IGNORE_QUAKE (1 << 12) // actor will not shake when a quake occurs
|
||||
|
||||
// Actor will not shake when a quake occurs
|
||||
#define ACTOR_FLAG_IGNORE_QUAKE (1 << 12)
|
||||
|
||||
//
|
||||
#define ACTOR_FLAG_13 (1 << 13)
|
||||
|
||||
//
|
||||
#define ACTOR_FLAG_14 (1 << 14)
|
||||
|
||||
//
|
||||
#define ACTOR_FLAG_15 (1 << 15)
|
||||
|
||||
//
|
||||
#define ACTOR_FLAG_16 (1 << 16)
|
||||
|
||||
//
|
||||
#define ACTOR_FLAG_17 (1 << 17)
|
||||
|
||||
//
|
||||
#define ACTOR_FLAG_18 (1 << 18)
|
||||
|
||||
//
|
||||
#define ACTOR_FLAG_19 (1 << 19)
|
||||
|
||||
//
|
||||
#define ACTOR_FLAG_20 (1 << 20)
|
||||
|
||||
//
|
||||
#define ACTOR_FLAG_21 (1 << 21)
|
||||
#define ACTOR_FLAG_22 (1 << 22)
|
||||
|
||||
// ignores point lights but not directional lights (such as environment lights)
|
||||
#define ACTOR_FLAG_IGNORE_POINT_LIGHTS (1 << 22)
|
||||
|
||||
//
|
||||
#define ACTOR_FLAG_23 (1 << 23)
|
||||
|
||||
//
|
||||
#define ACTOR_FLAG_24 (1 << 24)
|
||||
|
||||
//
|
||||
#define ACTOR_FLAG_25 (1 << 25)
|
||||
|
||||
//
|
||||
#define ACTOR_FLAG_26 (1 << 26)
|
||||
|
||||
//
|
||||
#define ACTOR_FLAG_27 (1 << 27)
|
||||
|
||||
//
|
||||
#define ACTOR_FLAG_28 (1 << 28)
|
||||
|
||||
#define COLORFILTER_GET_COLORINTENSITY(colorFilterParams) (((colorFilterParams) & 0x1F00) >> 5)
|
||||
|
@ -251,7 +305,9 @@ typedef struct Actor {
|
|||
/* 0x130 */ ActorFunc update; // Update Routine. Called by `Actor_UpdateAll`
|
||||
/* 0x134 */ ActorFunc draw; // Draw Routine. Called by `Actor_Draw`
|
||||
/* 0x138 */ ActorOverlay* overlayEntry; // Pointer to the overlay table entry for this actor
|
||||
/* 0x13C */ char dbgPad[0x10]; // Padding that only exists in the debug rom
|
||||
#ifdef OOT_DEBUG
|
||||
/* 0x13C */ char dbgPad[0x10];
|
||||
#endif
|
||||
} Actor; // size = 0x14C
|
||||
|
||||
typedef enum {
|
||||
|
|
18
requirements.txt
Normal file
18
requirements.txt
Normal file
|
@ -0,0 +1,18 @@
|
|||
# Setup and compression
|
||||
crunch64>=0.3.1,<1.0.0
|
||||
ipl3checksum>=1.2.0,<2.0.0
|
||||
|
||||
# asm-differ
|
||||
argcomplete
|
||||
colorama
|
||||
cxxfilt
|
||||
python-Levenshtein
|
||||
watchdog
|
||||
|
||||
# decomp-permuter
|
||||
pycparser
|
||||
toml
|
||||
|
||||
# tools
|
||||
mapfile-parser>=1.2.1,<2.0.0
|
||||
rabbitizer>=1.0.0,<2.0.0
|
|
@ -53,10 +53,10 @@ void PreRender_CopyImage(PreRender* this, Gfx** gfxP, void* img, void* imgDst) {
|
|||
s32 curRow;
|
||||
s32 nRows;
|
||||
|
||||
LogUtils_CheckNullPointer("this", this, "../PreRender.c", 215);
|
||||
LogUtils_CheckNullPointer("glistpp", gfxP, "../PreRender.c", 216);
|
||||
LOG_UTILS_CHECK_NULL_POINTER("this", this, "../PreRender.c", 215);
|
||||
LOG_UTILS_CHECK_NULL_POINTER("glistpp", gfxP, "../PreRender.c", 216);
|
||||
gfx = *gfxP;
|
||||
LogUtils_CheckNullPointer("glistp", gfx, "../PreRender.c", 218);
|
||||
LOG_UTILS_CHECK_NULL_POINTER("glistp", gfx, "../PreRender.c", 218);
|
||||
|
||||
gDPPipeSync(gfx++);
|
||||
// Configure the cycle type to COPY mode, disable blending
|
||||
|
@ -114,10 +114,10 @@ void PreRender_CopyImageRegionImpl(PreRender* this, Gfx** gfxP) {
|
|||
s32 curRow;
|
||||
s32 nRows;
|
||||
|
||||
LogUtils_CheckNullPointer("this", this, "../PreRender.c", 278);
|
||||
LogUtils_CheckNullPointer("glistpp", gfxP, "../PreRender.c", 279);
|
||||
LOG_UTILS_CHECK_NULL_POINTER("this", this, "../PreRender.c", 278);
|
||||
LOG_UTILS_CHECK_NULL_POINTER("glistpp", gfxP, "../PreRender.c", 279);
|
||||
gfx = *gfxP;
|
||||
LogUtils_CheckNullPointer("glistp", gfx, "../PreRender.c", 281);
|
||||
LOG_UTILS_CHECK_NULL_POINTER("glistp", gfx, "../PreRender.c", 281);
|
||||
|
||||
gDPPipeSync(gfx++);
|
||||
// Configure the cycle type to COPY mode, disable blending
|
||||
|
@ -177,10 +177,10 @@ void func_800C170C(PreRender* this, Gfx** gfxP, void* buf, void* bufSave, u32 r,
|
|||
s32 curRow;
|
||||
s32 nRows;
|
||||
|
||||
LogUtils_CheckNullPointer("this", this, "../PreRender.c", 343);
|
||||
LogUtils_CheckNullPointer("glistpp", gfxP, "../PreRender.c", 344);
|
||||
LOG_UTILS_CHECK_NULL_POINTER("this", this, "../PreRender.c", 343);
|
||||
LOG_UTILS_CHECK_NULL_POINTER("glistpp", gfxP, "../PreRender.c", 344);
|
||||
gfx = *gfxP;
|
||||
LogUtils_CheckNullPointer("glistp", gfx, "../PreRender.c", 346);
|
||||
LOG_UTILS_CHECK_NULL_POINTER("glistp", gfx, "../PreRender.c", 346);
|
||||
|
||||
gDPPipeSync(gfx++);
|
||||
// Set the cycle type to 1-cycle mode to use the color combiner
|
||||
|
@ -256,10 +256,10 @@ void PreRender_CoverageRgba16ToI8(PreRender* this, Gfx** gfxP, void* img, void*
|
|||
s32 curRow;
|
||||
s32 nRows;
|
||||
|
||||
LogUtils_CheckNullPointer("this", this, "../PreRender.c", 422);
|
||||
LogUtils_CheckNullPointer("glistpp", gfxP, "../PreRender.c", 423);
|
||||
LOG_UTILS_CHECK_NULL_POINTER("this", this, "../PreRender.c", 422);
|
||||
LOG_UTILS_CHECK_NULL_POINTER("glistpp", gfxP, "../PreRender.c", 423);
|
||||
gfx = *gfxP;
|
||||
LogUtils_CheckNullPointer("glistp", gfx, "../PreRender.c", 425);
|
||||
LOG_UTILS_CHECK_NULL_POINTER("glistp", gfx, "../PreRender.c", 425);
|
||||
|
||||
gDPPipeSync(gfx++);
|
||||
gDPSetOtherMode(gfx++,
|
||||
|
@ -333,8 +333,8 @@ void PreRender_CoverageRgba16ToI8(PreRender* this, Gfx** gfxP, void* img, void*
|
|||
* Saves zbuf to zbufSave
|
||||
*/
|
||||
void PreRender_SaveZBuffer(PreRender* this, Gfx** gfxP) {
|
||||
LogUtils_CheckNullPointer("this->zbuf_save", this->zbufSave, "../PreRender.c", 481);
|
||||
LogUtils_CheckNullPointer("this->zbuf", this->zbuf, "../PreRender.c", 482);
|
||||
LOG_UTILS_CHECK_NULL_POINTER("this->zbuf_save", this->zbufSave, "../PreRender.c", 481);
|
||||
LOG_UTILS_CHECK_NULL_POINTER("this->zbuf", this->zbuf, "../PreRender.c", 482);
|
||||
|
||||
if ((this->zbufSave != NULL) && (this->zbuf != NULL)) {
|
||||
PreRender_CopyImage(this, gfxP, this->zbuf, this->zbufSave);
|
||||
|
@ -345,8 +345,8 @@ void PreRender_SaveZBuffer(PreRender* this, Gfx** gfxP) {
|
|||
* Saves fbuf to fbufSave
|
||||
*/
|
||||
void PreRender_SaveFramebuffer(PreRender* this, Gfx** gfxP) {
|
||||
LogUtils_CheckNullPointer("this->fbuf_save", this->fbufSave, "../PreRender.c", 495);
|
||||
LogUtils_CheckNullPointer("this->fbuf", this->fbuf, "../PreRender.c", 496);
|
||||
LOG_UTILS_CHECK_NULL_POINTER("this->fbuf_save", this->fbufSave, "../PreRender.c", 495);
|
||||
LOG_UTILS_CHECK_NULL_POINTER("this->fbuf", this->fbuf, "../PreRender.c", 496);
|
||||
|
||||
if ((this->fbufSave != NULL) && (this->fbuf != NULL)) {
|
||||
func_800C1AE8(this, gfxP, this->fbuf, this->fbufSave);
|
||||
|
@ -401,7 +401,7 @@ void PreRender_FetchFbufCoverage(PreRender* this, Gfx** gfxP) {
|
|||
*/
|
||||
void PreRender_DrawCoverage(PreRender* this, Gfx** gfxP) {
|
||||
PreRender_FetchFbufCoverage(this, gfxP);
|
||||
LogUtils_CheckNullPointer("this->cvg_save", this->cvgSave, "../PreRender.c", 532);
|
||||
LOG_UTILS_CHECK_NULL_POINTER("this->cvg_save", this->cvgSave, "../PreRender.c", 532);
|
||||
if (this->cvgSave != NULL) {
|
||||
PreRender_CoverageRgba16ToI8(this, gfxP, this->fbuf, this->cvgSave);
|
||||
}
|
||||
|
@ -426,10 +426,10 @@ void func_800C213C(PreRender* this, Gfx** gfxP) {
|
|||
s32 rtile = 1;
|
||||
|
||||
if (this->cvgSave != NULL) {
|
||||
LogUtils_CheckNullPointer("this", this, "../PreRender.c", 563);
|
||||
LogUtils_CheckNullPointer("glistpp", gfxP, "../PreRender.c", 564);
|
||||
LOG_UTILS_CHECK_NULL_POINTER("this", this, "../PreRender.c", 563);
|
||||
LOG_UTILS_CHECK_NULL_POINTER("glistpp", gfxP, "../PreRender.c", 564);
|
||||
gfx = *gfxP;
|
||||
LogUtils_CheckNullPointer("glistp", gfx, "../PreRender.c", 566);
|
||||
LOG_UTILS_CHECK_NULL_POINTER("glistp", gfx, "../PreRender.c", 566);
|
||||
|
||||
gDPPipeSync(gfx++);
|
||||
gDPSetEnvColor(gfx++, 255, 255, 255, 32);
|
||||
|
|
|
@ -415,7 +415,7 @@ void GameState_Init(GameState* gameState, GameStateFunc init, GraphicsContext* g
|
|||
PRINTF("init 処理時間 %d us\n", OS_CYCLES_TO_USEC(endTime - startTime));
|
||||
|
||||
startTime = endTime;
|
||||
LogUtils_CheckNullPointer("this->cleanup", gameState->destroy, "../game.c", 1088);
|
||||
LOG_UTILS_CHECK_NULL_POINTER("this->cleanup", gameState->destroy, "../game.c", 1088);
|
||||
VisCvg_Init(&sVisCvg);
|
||||
VisZBuf_Init(&sVisZBuf);
|
||||
VisMono_Init(&sVisMono);
|
||||
|
@ -440,7 +440,7 @@ void GameState_Destroy(GameState* gameState) {
|
|||
AudioMgr_StopAllSfx();
|
||||
func_800F3054();
|
||||
osRecvMesg(&gameState->gfxCtx->queue, NULL, OS_MESG_BLOCK);
|
||||
LogUtils_CheckNullPointer("this->cleanup", gameState->destroy, "../game.c", 1139);
|
||||
LOG_UTILS_CHECK_NULL_POINTER("this->cleanup", gameState->destroy, "../game.c", 1139);
|
||||
if (gameState->destroy != NULL) {
|
||||
gameState->destroy(gameState);
|
||||
}
|
||||
|
|
|
@ -49,8 +49,8 @@ void GameAlloc_Free(GameAlloc* this, void* data) {
|
|||
|
||||
if (data != NULL) {
|
||||
ptr = &((GameAllocEntry*)data)[-1];
|
||||
LogUtils_CheckNullPointer("ptr->prev", ptr->prev, "../gamealloc.c", 120);
|
||||
LogUtils_CheckNullPointer("ptr->next", ptr->next, "../gamealloc.c", 121);
|
||||
LOG_UTILS_CHECK_NULL_POINTER("ptr->prev", ptr->prev, "../gamealloc.c", 120);
|
||||
LOG_UTILS_CHECK_NULL_POINTER("ptr->next", ptr->next, "../gamealloc.c", 121);
|
||||
ptr->prev->next = ptr->next;
|
||||
ptr->next->prev = ptr->prev;
|
||||
this->head = this->base.prev;
|
||||
|
|
|
@ -59,9 +59,9 @@ u32 sIrqMgrRetraceCount = 0;
|
|||
void IrqMgr_AddClient(IrqMgr* irqMgr, IrqMgrClient* client, OSMesgQueue* msgQueue) {
|
||||
OSIntMask prevInt;
|
||||
|
||||
LogUtils_CheckNullPointer("this", irqMgr, "../irqmgr.c", 96);
|
||||
LogUtils_CheckNullPointer("c", client, "../irqmgr.c", 97);
|
||||
LogUtils_CheckNullPointer("msgQ", msgQueue, "../irqmgr.c", 98);
|
||||
LOG_UTILS_CHECK_NULL_POINTER("this", irqMgr, "../irqmgr.c", 96);
|
||||
LOG_UTILS_CHECK_NULL_POINTER("c", client, "../irqmgr.c", 97);
|
||||
LOG_UTILS_CHECK_NULL_POINTER("msgQ", msgQueue, "../irqmgr.c", 98);
|
||||
|
||||
prevInt = osSetIntMask(OS_IM_NONE);
|
||||
|
||||
|
@ -85,8 +85,8 @@ void IrqMgr_RemoveClient(IrqMgr* irqMgr, IrqMgrClient* client) {
|
|||
IrqMgrClient* lastClient = NULL;
|
||||
OSIntMask prevInt;
|
||||
|
||||
LogUtils_CheckNullPointer("this", irqMgr, "../irqmgr.c", 129);
|
||||
LogUtils_CheckNullPointer("c", client, "../irqmgr.c", 130);
|
||||
LOG_UTILS_CHECK_NULL_POINTER("this", irqMgr, "../irqmgr.c", 129);
|
||||
LOG_UTILS_CHECK_NULL_POINTER("c", client, "../irqmgr.c", 130);
|
||||
|
||||
// Disable interrupts to prevent a thread context switch while the linked list is modified
|
||||
prevInt = osSetIntMask(OS_IM_NONE);
|
||||
|
@ -290,8 +290,8 @@ void IrqMgr_ThreadEntry(void* arg) {
|
|||
}
|
||||
|
||||
void IrqMgr_Init(IrqMgr* irqMgr, void* stack, OSPri pri, u8 retraceCount) {
|
||||
LogUtils_CheckNullPointer("this", irqMgr, "../irqmgr.c", 346);
|
||||
LogUtils_CheckNullPointer("stack", stack, "../irqmgr.c", 347);
|
||||
LOG_UTILS_CHECK_NULL_POINTER("this", irqMgr, "../irqmgr.c", 346);
|
||||
LOG_UTILS_CHECK_NULL_POINTER("stack", stack, "../irqmgr.c", 347);
|
||||
|
||||
irqMgr->clients = NULL;
|
||||
// Messages to send to each client message queue on each interrupt event
|
||||
|
|
|
@ -4,8 +4,8 @@ void MtxConv_F2L(Mtx* m1, MtxF* m2) {
|
|||
s32 i;
|
||||
s32 j;
|
||||
|
||||
LogUtils_CheckNullPointer("m1", m1, "../mtxuty-cvt.c", 31);
|
||||
LogUtils_CheckNullPointer("m2", m2, "../mtxuty-cvt.c", 32);
|
||||
LOG_UTILS_CHECK_NULL_POINTER("m1", m1, "../mtxuty-cvt.c", 31);
|
||||
LOG_UTILS_CHECK_NULL_POINTER("m2", m2, "../mtxuty-cvt.c", 32);
|
||||
|
||||
for (i = 0; i < 4; i++) {
|
||||
for (j = 0; j < 4; j++) {
|
||||
|
@ -18,7 +18,7 @@ void MtxConv_F2L(Mtx* m1, MtxF* m2) {
|
|||
}
|
||||
|
||||
void MtxConv_L2F(MtxF* m1, Mtx* m2) {
|
||||
LogUtils_CheckNullPointer("m1", m1, "../mtxuty-cvt.c", 55);
|
||||
LogUtils_CheckNullPointer("m2", m2, "../mtxuty-cvt.c", 56);
|
||||
LOG_UTILS_CHECK_NULL_POINTER("m1", m1, "../mtxuty-cvt.c", 55);
|
||||
LOG_UTILS_CHECK_NULL_POINTER("m2", m2, "../mtxuty-cvt.c", 56);
|
||||
guMtxL2F(m1, m2);
|
||||
}
|
||||
|
|
|
@ -477,7 +477,7 @@ void PadMgr_ThreadEntry(PadMgr* padMgr) {
|
|||
}
|
||||
|
||||
osRecvMesg(&padMgr->interruptQueue, (OSMesg*)&msg, OS_MESG_BLOCK);
|
||||
LogUtils_CheckNullPointer("msg", msg, "../padmgr.c", 563);
|
||||
LOG_UTILS_CHECK_NULL_POINTER("msg", msg, "../padmgr.c", 563);
|
||||
|
||||
switch (*msg) {
|
||||
case OS_SC_RETRACE_MSG:
|
||||
|
|
|
@ -58,7 +58,7 @@ OSTime sRDPTimeStart;
|
|||
void Sched_SwapFrameBufferImpl(CfbInfo* cfbInfo) {
|
||||
u16 width;
|
||||
|
||||
LogUtils_CheckValidPointer("cfbinfo->swapbuffer", cfbInfo->swapBuffer, "../sched.c", 340);
|
||||
LOG_UTILS_CHECK_VALID_POINTER("cfbinfo->swapbuffer", cfbInfo->swapBuffer, "../sched.c", 340);
|
||||
|
||||
if (cfbInfo->swapBuffer != NULL) {
|
||||
// Register the swapbuffer to display on next VI
|
||||
|
@ -330,7 +330,7 @@ void Sched_SetNextFramebufferFromTask(Scheduler* sc, OSScTask* task) {
|
|||
if (sc->pendingSwapBuf1 == NULL) {
|
||||
sc->pendingSwapBuf1 = task->framebuffer;
|
||||
|
||||
LogUtils_CheckValidPointer("sc->pending_swapbuffer1", sc->pendingSwapBuf1, "../sched.c", 618);
|
||||
LOG_UTILS_CHECK_VALID_POINTER("sc->pending_swapbuffer1", sc->pendingSwapBuf1, "../sched.c", 618);
|
||||
|
||||
if (sc->curBuf == NULL || sc->curBuf->updateTimer <= 0) {
|
||||
Sched_SwapFrameBuffer(sc, task->framebuffer);
|
||||
|
|
|
@ -92,7 +92,7 @@ typedef struct {
|
|||
gDPPipeSync(gfx)
|
||||
|
||||
void SpeedMeter_InitImpl(SpeedMeter* this, u32 x, u32 y) {
|
||||
LogUtils_CheckNullPointer("this", this, "../speed_meter.c", 181);
|
||||
LOG_UTILS_CHECK_NULL_POINTER("this", this, "../speed_meter.c", 181);
|
||||
this->x = x;
|
||||
this->y = y;
|
||||
}
|
||||
|
|
|
@ -915,16 +915,25 @@ void Actor_UpdatePosByAnimation(Actor* actor, SkelAnime* skelAnime) {
|
|||
actor->world.pos.z += posDiff.z * actor->scale.z;
|
||||
}
|
||||
|
||||
s16 Actor_WorldYawTowardActor(Actor* actorA, Actor* actorB) {
|
||||
return Math_Vec3f_Yaw(&actorA->world.pos, &actorB->world.pos);
|
||||
/**
|
||||
* @return Yaw towards `target` for `origin`, using world positions.
|
||||
*/
|
||||
s16 Actor_WorldYawTowardActor(Actor* origin, Actor* target) {
|
||||
return Math_Vec3f_Yaw(&origin->world.pos, &target->world.pos);
|
||||
}
|
||||
|
||||
s16 Actor_FocusYawTowardActor(Actor* actorA, Actor* actorB) {
|
||||
return Math_Vec3f_Yaw(&actorA->focus.pos, &actorB->focus.pos);
|
||||
/**
|
||||
* @return Yaw towards `target` for `origin`, using focus positions.
|
||||
*/
|
||||
s16 Actor_FocusYawTowardActor(Actor* origin, Actor* target) {
|
||||
return Math_Vec3f_Yaw(&origin->focus.pos, &target->focus.pos);
|
||||
}
|
||||
|
||||
s16 Actor_WorldYawTowardPoint(Actor* actor, Vec3f* refPoint) {
|
||||
return Math_Vec3f_Yaw(&actor->world.pos, refPoint);
|
||||
/**
|
||||
* @return Yaw towards `point` for `origin`.
|
||||
*/
|
||||
s16 Actor_WorldYawTowardPoint(Actor* origin, Vec3f* point) {
|
||||
return Math_Vec3f_Yaw(&origin->world.pos, point);
|
||||
}
|
||||
|
||||
s16 Actor_WorldPitchTowardActor(Actor* actorA, Actor* actorB) {
|
||||
|
@ -2302,7 +2311,8 @@ void Actor_Draw(PlayState* play, Actor* actor) {
|
|||
|
||||
lights = LightContext_NewLights(&play->lightCtx, play->state.gfxCtx);
|
||||
|
||||
Lights_BindAll(lights, play->lightCtx.listHead, (actor->flags & ACTOR_FLAG_22) ? NULL : &actor->world.pos);
|
||||
Lights_BindAll(lights, play->lightCtx.listHead,
|
||||
(actor->flags & ACTOR_FLAG_IGNORE_POINT_LIGHTS) ? NULL : &actor->world.pos);
|
||||
Lights_Draw(lights, play->state.gfxCtx);
|
||||
|
||||
if (actor->flags & ACTOR_FLAG_IGNORE_QUAKE) {
|
||||
|
@ -2552,7 +2562,7 @@ void func_800315AC(PlayState* play, ActorContext* actorCtx) {
|
|||
|
||||
if ((HREG(64) != 1) || ((HREG(65) != -1) && (HREG(65) != HREG(66))) || (HREG(71) == 0)) {
|
||||
if ((actor->init == NULL) && (actor->draw != NULL) && (actor->flags & (ACTOR_FLAG_5 | ACTOR_FLAG_6))) {
|
||||
if ((actor->flags & ACTOR_FLAG_7) &&
|
||||
if ((actor->flags & ACTOR_FLAG_REACT_TO_LENS) &&
|
||||
((play->roomCtx.curRoom.lensMode == LENS_MODE_HIDE_ACTORS) || play->actorCtx.lensActive ||
|
||||
(actor->room != play->roomCtx.curRoom.num))) {
|
||||
ASSERT(invisibleActorCounter < INVISIBLE_ACTOR_MAX,
|
||||
|
|
|
@ -17,7 +17,7 @@ KaleidoMgrOverlay* gKaleidoMgrCurOvl = NULL;
|
|||
u8 gBossMarkState = 0;
|
||||
|
||||
void KaleidoManager_LoadOvl(KaleidoMgrOverlay* ovl) {
|
||||
LogUtils_CheckNullPointer("KaleidoArea_allocp", sKaleidoAreaPtr, "../z_kaleido_manager.c", 99);
|
||||
LOG_UTILS_CHECK_NULL_POINTER("KaleidoArea_allocp", sKaleidoAreaPtr, "../z_kaleido_manager.c", 99);
|
||||
|
||||
ovl->loadedRamAddr = sKaleidoAreaPtr;
|
||||
Overlay_Load(ovl->vromStart, ovl->vromEnd, ovl->vramStart, ovl->vramEnd, ovl->loadedRamAddr);
|
||||
|
@ -58,7 +58,7 @@ void KaleidoManager_Init(PlayState* play) {
|
|||
PRINTF(VT_RST);
|
||||
|
||||
sKaleidoAreaPtr = GAME_STATE_ALLOC(&play->state, largestSize, "../z_kaleido_manager.c", 150);
|
||||
LogUtils_CheckNullPointer("KaleidoArea_allocp", sKaleidoAreaPtr, "../z_kaleido_manager.c", 151);
|
||||
LOG_UTILS_CHECK_NULL_POINTER("KaleidoArea_allocp", sKaleidoAreaPtr, "../z_kaleido_manager.c", 151);
|
||||
|
||||
PRINTF(VT_FGCOL(GREEN));
|
||||
PRINTF("KaleidoArea %08x - %08x\n", sKaleidoAreaPtr, (uintptr_t)sKaleidoAreaPtr + largestSize);
|
||||
|
|
|
@ -300,9 +300,14 @@ f32 Math_Vec3f_DiffY(Vec3f* a, Vec3f* b) {
|
|||
return b->y - a->y;
|
||||
}
|
||||
|
||||
s16 Math_Vec3f_Yaw(Vec3f* a, Vec3f* b) {
|
||||
f32 dx = b->x - a->x;
|
||||
f32 dz = b->z - a->z;
|
||||
/**
|
||||
* @param origin Position of the origin, the location from which to look at the target `point`
|
||||
* @param point Position of the target point, in the same space as `origin`
|
||||
* @return The yaw towards `point` when at `origin`, assuming +z is forwards.
|
||||
*/
|
||||
s16 Math_Vec3f_Yaw(Vec3f* origin, Vec3f* point) {
|
||||
f32 dx = point->x - origin->x;
|
||||
f32 dz = point->z - origin->z;
|
||||
|
||||
return Math_Atan2S(dz, dx);
|
||||
}
|
||||
|
|
|
@ -58,7 +58,7 @@ void MapMark_Init(PlayState* play) {
|
|||
u32 overlaySize = (uintptr_t)overlay->vramEnd - (uintptr_t)overlay->vramStart;
|
||||
|
||||
overlay->loadedRamAddr = GAME_STATE_ALLOC(&play->state, overlaySize, "../z_map_mark.c", 235);
|
||||
LogUtils_CheckNullPointer("dlftbl->allocp", overlay->loadedRamAddr, "../z_map_mark.c", 236);
|
||||
LOG_UTILS_CHECK_NULL_POINTER("dlftbl->allocp", overlay->loadedRamAddr, "../z_map_mark.c", 236);
|
||||
|
||||
Overlay_Load(overlay->vromStart, overlay->vromEnd, overlay->vramStart, overlay->vramEnd, overlay->loadedRamAddr);
|
||||
|
||||
|
|
|
@ -20,8 +20,11 @@ Vec3f OnePointCutscene_AddVecGeoToVec3f(Vec3f* a, VecGeo* geo) {
|
|||
return sum;
|
||||
}
|
||||
|
||||
s16 OnePointCutscene_Vec3fYaw(Vec3f* vec1, Vec3f* vec2) {
|
||||
return CAM_DEG_TO_BINANG(RAD_TO_DEG(Math_FAtan2F(vec2->x - vec1->x, vec2->z - vec1->z)));
|
||||
/**
|
||||
* @see Math_Vec3f_Yaw
|
||||
*/
|
||||
s16 OnePointCutscene_Vec3fYaw(Vec3f* origin, Vec3f* point) {
|
||||
return CAM_DEG_TO_BINANG(RAD_TO_DEG(Math_FAtan2F(point->x - origin->x, point->z - origin->z)));
|
||||
}
|
||||
|
||||
void OnePointCutscene_Vec3sToVec3f(Vec3f* src, Vec3s* dst) {
|
||||
|
|
|
@ -483,6 +483,26 @@ void Scene_CommandMiscSettings(PlayState* play, SceneCmd* cmd) {
|
|||
}
|
||||
}
|
||||
|
||||
void Scene_SetTransitionForNextEntrance(PlayState* play) {
|
||||
s16 entranceIndex;
|
||||
|
||||
if (!IS_DAY) {
|
||||
if (!LINK_IS_ADULT) {
|
||||
entranceIndex = play->nextEntranceIndex + 1;
|
||||
} else {
|
||||
entranceIndex = play->nextEntranceIndex + 3;
|
||||
}
|
||||
} else {
|
||||
if (!LINK_IS_ADULT) {
|
||||
entranceIndex = play->nextEntranceIndex;
|
||||
} else {
|
||||
entranceIndex = play->nextEntranceIndex + 2;
|
||||
}
|
||||
}
|
||||
|
||||
play->transitionType = ENTRANCE_INFO_START_TRANS_TYPE(gEntranceTable[entranceIndex].field);
|
||||
}
|
||||
|
||||
void (*gSceneCmdHandlers[SCENE_CMD_ID_MAX])(PlayState*, SceneCmd*) = {
|
||||
Scene_CommandPlayerEntryList, // SCENE_CMD_ID_SPAWN_LIST
|
||||
Scene_CommandActorEntryList, // SCENE_CMD_ID_ACTOR_LIST
|
||||
|
|
|
@ -77,26 +77,6 @@ Gfx sDefaultDisplayList[] = {
|
|||
gsSPEndDisplayList(),
|
||||
};
|
||||
|
||||
void Scene_SetTransitionForNextEntrance(PlayState* play) {
|
||||
s16 entranceIndex;
|
||||
|
||||
if (!IS_DAY) {
|
||||
if (!LINK_IS_ADULT) {
|
||||
entranceIndex = play->nextEntranceIndex + 1;
|
||||
} else {
|
||||
entranceIndex = play->nextEntranceIndex + 3;
|
||||
}
|
||||
} else {
|
||||
if (!LINK_IS_ADULT) {
|
||||
entranceIndex = play->nextEntranceIndex;
|
||||
} else {
|
||||
entranceIndex = play->nextEntranceIndex + 2;
|
||||
}
|
||||
}
|
||||
|
||||
play->transitionType = ENTRANCE_INFO_START_TRANS_TYPE(gEntranceTable[entranceIndex].field);
|
||||
}
|
||||
|
||||
void Scene_DrawConfigDefault(PlayState* play) {
|
||||
OPEN_DISPS(play->state.gfxCtx, "../z_scene_table.c", 4725);
|
||||
|
||||
|
|
|
@ -292,7 +292,7 @@ s32 View_ApplyPerspective(View* view) {
|
|||
|
||||
// Viewport
|
||||
vp = GRAPH_ALLOC(gfxCtx, sizeof(Vp));
|
||||
LogUtils_CheckNullPointer("vp", vp, "../z_view.c", 601);
|
||||
LOG_UTILS_CHECK_NULL_POINTER("vp", vp, "../z_view.c", 601);
|
||||
View_ViewportToVp(vp, &view->viewport);
|
||||
view->vp = *vp;
|
||||
|
||||
|
@ -303,7 +303,7 @@ s32 View_ApplyPerspective(View* view) {
|
|||
|
||||
// Perspective projection
|
||||
projection = GRAPH_ALLOC(gfxCtx, sizeof(Mtx));
|
||||
LogUtils_CheckNullPointer("projection", projection, "../z_view.c", 616);
|
||||
LOG_UTILS_CHECK_NULL_POINTER("projection", projection, "../z_view.c", 616);
|
||||
view->projectionPtr = projection;
|
||||
|
||||
width = view->viewport.rightX - view->viewport.leftX;
|
||||
|
@ -351,7 +351,7 @@ s32 View_ApplyPerspective(View* view) {
|
|||
|
||||
// View matrix (look-at)
|
||||
viewing = GRAPH_ALLOC(gfxCtx, sizeof(Mtx));
|
||||
LogUtils_CheckNullPointer("viewing", viewing, "../z_view.c", 667);
|
||||
LOG_UTILS_CHECK_NULL_POINTER("viewing", viewing, "../z_view.c", 667);
|
||||
view->viewingPtr = viewing;
|
||||
|
||||
if (view->eye.x == view->at.x && view->eye.y == view->at.y && view->eye.z == view->at.z) {
|
||||
|
@ -395,7 +395,7 @@ s32 View_ApplyOrtho(View* view) {
|
|||
OPEN_DISPS(gfxCtx, "../z_view.c", 726);
|
||||
|
||||
vp = GRAPH_ALLOC(gfxCtx, sizeof(Vp));
|
||||
LogUtils_CheckNullPointer("vp", vp, "../z_view.c", 730);
|
||||
LOG_UTILS_CHECK_NULL_POINTER("vp", vp, "../z_view.c", 730);
|
||||
View_ViewportToVp(vp, &view->viewport);
|
||||
view->vp = *vp;
|
||||
|
||||
|
@ -406,7 +406,7 @@ s32 View_ApplyOrtho(View* view) {
|
|||
gSPViewport(OVERLAY_DISP++, vp);
|
||||
|
||||
projection = GRAPH_ALLOC(gfxCtx, sizeof(Mtx));
|
||||
LogUtils_CheckNullPointer("projection", projection, "../z_view.c", 744);
|
||||
LOG_UTILS_CHECK_NULL_POINTER("projection", projection, "../z_view.c", 744);
|
||||
view->projectionPtr = projection;
|
||||
|
||||
guOrtho(projection, -(f32)gScreenWidth * 0.5f, (f32)gScreenWidth * 0.5f, -(f32)gScreenHeight * 0.5f,
|
||||
|
@ -435,7 +435,7 @@ s32 View_ApplyOrthoToOverlay(View* view) {
|
|||
OPEN_DISPS(gfxCtx, "../z_view.c", 777);
|
||||
|
||||
vp = GRAPH_ALLOC(gfxCtx, sizeof(Vp));
|
||||
LogUtils_CheckNullPointer("vp", vp, "../z_view.c", 781);
|
||||
LOG_UTILS_CHECK_NULL_POINTER("vp", vp, "../z_view.c", 781);
|
||||
View_ViewportToVp(vp, &view->viewport);
|
||||
view->vp = *vp;
|
||||
|
||||
|
@ -445,7 +445,7 @@ s32 View_ApplyOrthoToOverlay(View* view) {
|
|||
gSPViewport(OVERLAY_DISP++, vp);
|
||||
|
||||
projection = GRAPH_ALLOC(gfxCtx, sizeof(Mtx));
|
||||
LogUtils_CheckNullPointer("projection", projection, "../z_view.c", 791);
|
||||
LOG_UTILS_CHECK_NULL_POINTER("projection", projection, "../z_view.c", 791);
|
||||
view->projectionPtr = projection;
|
||||
|
||||
guOrtho(projection, -(f32)gScreenWidth * 0.5f, (f32)gScreenWidth * 0.5f, -(f32)gScreenHeight * 0.5f,
|
||||
|
@ -476,7 +476,7 @@ s32 View_ApplyPerspectiveToOverlay(View* view) {
|
|||
OPEN_DISPS(gfxCtx, "../z_view.c", 816);
|
||||
|
||||
vp = GRAPH_ALLOC(gfxCtx, sizeof(Vp));
|
||||
LogUtils_CheckNullPointer("vp", vp, "../z_view.c", 821);
|
||||
LOG_UTILS_CHECK_NULL_POINTER("vp", vp, "../z_view.c", 821);
|
||||
View_ViewportToVp(vp, &view->viewport);
|
||||
view->vp = *vp;
|
||||
|
||||
|
@ -486,7 +486,7 @@ s32 View_ApplyPerspectiveToOverlay(View* view) {
|
|||
gSPViewport(OVERLAY_DISP++, vp);
|
||||
|
||||
projection = GRAPH_ALLOC(gfxCtx, sizeof(Mtx));
|
||||
LogUtils_CheckNullPointer("projection", projection, "../z_view.c", 833);
|
||||
LOG_UTILS_CHECK_NULL_POINTER("projection", projection, "../z_view.c", 833);
|
||||
view->projectionPtr = projection;
|
||||
|
||||
width = view->viewport.rightX - view->viewport.leftX;
|
||||
|
@ -501,7 +501,7 @@ s32 View_ApplyPerspectiveToOverlay(View* view) {
|
|||
gSPMatrix(OVERLAY_DISP++, projection, G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_PROJECTION);
|
||||
|
||||
viewing = GRAPH_ALLOC(gfxCtx, sizeof(Mtx));
|
||||
LogUtils_CheckNullPointer("viewing", viewing, "../z_view.c", 848);
|
||||
LOG_UTILS_CHECK_NULL_POINTER("viewing", viewing, "../z_view.c", 848);
|
||||
view->viewingPtr = viewing;
|
||||
|
||||
// This check avoids a divide-by-zero in guLookAt if eye == at
|
||||
|
@ -552,7 +552,7 @@ s32 View_ApplyTo(View* view, s32 mask, Gfx** gfxP) {
|
|||
|
||||
if (mask & VIEW_VIEWPORT) {
|
||||
vp = GRAPH_ALLOC(gfxCtx, sizeof(Vp));
|
||||
LogUtils_CheckNullPointer("vp", vp, "../z_view.c", 910);
|
||||
LOG_UTILS_CHECK_NULL_POINTER("vp", vp, "../z_view.c", 910);
|
||||
View_ViewportToVp(vp, &view->viewport);
|
||||
|
||||
view->vp = *vp;
|
||||
|
@ -565,7 +565,7 @@ s32 View_ApplyTo(View* view, s32 mask, Gfx** gfxP) {
|
|||
|
||||
if (mask & VIEW_PROJECTION_ORTHO) {
|
||||
projection = GRAPH_ALLOC(gfxCtx, sizeof(Mtx));
|
||||
LogUtils_CheckNullPointer("projection", projection, "../z_view.c", 921);
|
||||
LOG_UTILS_CHECK_NULL_POINTER("projection", projection, "../z_view.c", 921);
|
||||
view->projectionPtr = projection;
|
||||
|
||||
guOrtho(projection, -(f32)gScreenWidth * 0.5f, (f32)gScreenWidth * 0.5f, -(f32)gScreenHeight * 0.5f,
|
||||
|
@ -576,7 +576,7 @@ s32 View_ApplyTo(View* view, s32 mask, Gfx** gfxP) {
|
|||
gSPMatrix(gfx++, projection, G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_PROJECTION);
|
||||
} else if (mask & (VIEW_PROJECTION_PERSPECTIVE | VIEW_VIEWPORT)) {
|
||||
projection = GRAPH_ALLOC(gfxCtx, sizeof(Mtx));
|
||||
LogUtils_CheckNullPointer("projection", projection, "../z_view.c", 932);
|
||||
LOG_UTILS_CHECK_NULL_POINTER("projection", projection, "../z_view.c", 932);
|
||||
view->projectionPtr = projection;
|
||||
|
||||
width = view->viewport.rightX - view->viewport.leftX;
|
||||
|
@ -593,7 +593,7 @@ s32 View_ApplyTo(View* view, s32 mask, Gfx** gfxP) {
|
|||
|
||||
if (mask & VIEW_VIEWING) {
|
||||
viewing = GRAPH_ALLOC(gfxCtx, sizeof(Mtx));
|
||||
LogUtils_CheckNullPointer("viewing", viewing, "../z_view.c", 948);
|
||||
LOG_UTILS_CHECK_NULL_POINTER("viewing", viewing, "../z_view.c", 948);
|
||||
view->viewingPtr = viewing;
|
||||
|
||||
View_ErrorCheckEyePosition(view->eye.x, view->eye.y, view->eye.z);
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
|
||||
.section .text
|
||||
|
||||
.incbin "baserom.z64", 0x40, 0xFC0
|
||||
.incbin "baseroms/gc-eu-mq-dbg/baserom-decompressed.z64", 0x40, 0xFC0
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
#include "z_bg_bombwall.h"
|
||||
#include "assets/objects/gameplay_field_keep/gameplay_field_keep.h"
|
||||
|
||||
#define FLAGS ACTOR_FLAG_22
|
||||
#define FLAGS ACTOR_FLAG_IGNORE_POINT_LIGHTS
|
||||
|
||||
void BgBombwall_Init(Actor* thisx, PlayState* play);
|
||||
void BgBombwall_Destroy(Actor* thisx, PlayState* play);
|
||||
|
|
|
@ -55,7 +55,7 @@ void BgGndDarkmeiro_Init(Actor* thisx, PlayState* play2) {
|
|||
switch (this->dyna.actor.params & 0xFF) {
|
||||
case DARKMEIRO_INVISIBLE_PATH:
|
||||
this->dyna.actor.draw = BgGndDarkmeiro_DrawInvisiblePath;
|
||||
this->dyna.actor.flags |= ACTOR_FLAG_7;
|
||||
this->dyna.actor.flags |= ACTOR_FLAG_REACT_TO_LENS;
|
||||
break;
|
||||
case DARKMEIRO_CLEAR_BLOCK:
|
||||
CollisionHeader_GetVirtual(&gClearBlockCol, &colHeader);
|
||||
|
|
|
@ -40,9 +40,9 @@ void BgGndNisekabe_Update(Actor* thisx, PlayState* play) {
|
|||
BgGndNisekabe* this = (BgGndNisekabe*)thisx;
|
||||
|
||||
if (play->actorCtx.lensActive) {
|
||||
this->actor.flags |= ACTOR_FLAG_7;
|
||||
this->actor.flags |= ACTOR_FLAG_REACT_TO_LENS;
|
||||
} else {
|
||||
this->actor.flags &= ~ACTOR_FLAG_7;
|
||||
this->actor.flags &= ~ACTOR_FLAG_REACT_TO_LENS;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -55,7 +55,7 @@ void BgGndNisekabe_Draw(Actor* thisx, PlayState* play) {
|
|||
BgGndNisekabe* this = (BgGndNisekabe*)thisx;
|
||||
u32 index = this->actor.params & 0xFF;
|
||||
|
||||
if (CHECK_FLAG_ALL(this->actor.flags, ACTOR_FLAG_7)) {
|
||||
if (CHECK_FLAG_ALL(this->actor.flags, ACTOR_FLAG_REACT_TO_LENS)) {
|
||||
Gfx_DrawDListXlu(play, dLists[index]);
|
||||
} else {
|
||||
Gfx_DrawDListOpa(play, dLists[index]);
|
||||
|
|
|
@ -292,9 +292,9 @@ void BgHakaGate_FalseSkull(BgHakaGate* this, PlayState* play) {
|
|||
Math_StepToS(&this->vFlameScale, 350, 20);
|
||||
}
|
||||
if (play->actorCtx.lensActive) {
|
||||
this->dyna.actor.flags |= ACTOR_FLAG_7;
|
||||
this->dyna.actor.flags |= ACTOR_FLAG_REACT_TO_LENS;
|
||||
} else {
|
||||
this->dyna.actor.flags &= ~ACTOR_FLAG_7;
|
||||
this->dyna.actor.flags &= ~ACTOR_FLAG_REACT_TO_LENS;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -345,7 +345,7 @@ void BgHakaGate_Draw(Actor* thisx, PlayState* play) {
|
|||
BgHakaGate* this = (BgHakaGate*)thisx;
|
||||
MtxF currentMtxF;
|
||||
|
||||
if (CHECK_FLAG_ALL(thisx->flags, ACTOR_FLAG_7)) {
|
||||
if (CHECK_FLAG_ALL(thisx->flags, ACTOR_FLAG_REACT_TO_LENS)) {
|
||||
Gfx_DrawDListXlu(play, object_haka_objects_DL_00F1B0);
|
||||
} else {
|
||||
Gfx_SetupDL_25Opa(play->state.gfxCtx);
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
#include "assets/objects/object_hakach_objects/object_hakach_objects.h"
|
||||
#include "assets/objects/object_haka_objects/object_haka_objects.h"
|
||||
|
||||
#define FLAGS (ACTOR_FLAG_4 | ACTOR_FLAG_5 | ACTOR_FLAG_7)
|
||||
#define FLAGS (ACTOR_FLAG_4 | ACTOR_FLAG_5 | ACTOR_FLAG_REACT_TO_LENS)
|
||||
|
||||
void BgHakaMegane_Init(Actor* thisx, PlayState* play);
|
||||
void BgHakaMegane_Destroy(Actor* thisx, PlayState* play);
|
||||
|
@ -109,10 +109,10 @@ void func_8087DBF0(BgHakaMegane* this, PlayState* play) {
|
|||
Actor* thisx = &this->dyna.actor;
|
||||
|
||||
if (play->actorCtx.lensActive) {
|
||||
thisx->flags |= ACTOR_FLAG_7;
|
||||
thisx->flags |= ACTOR_FLAG_REACT_TO_LENS;
|
||||
DynaPoly_DisableCollision(play, &play->colCtx.dyna, this->dyna.bgId);
|
||||
} else {
|
||||
thisx->flags &= ~ACTOR_FLAG_7;
|
||||
thisx->flags &= ~ACTOR_FLAG_REACT_TO_LENS;
|
||||
DynaPoly_EnableCollision(play, &play->colCtx.dyna, this->dyna.bgId);
|
||||
}
|
||||
}
|
||||
|
@ -129,7 +129,7 @@ void BgHakaMegane_Update(Actor* thisx, PlayState* play) {
|
|||
void BgHakaMegane_Draw(Actor* thisx, PlayState* play) {
|
||||
BgHakaMegane* this = (BgHakaMegane*)thisx;
|
||||
|
||||
if (CHECK_FLAG_ALL(thisx->flags, ACTOR_FLAG_7)) {
|
||||
if (CHECK_FLAG_ALL(thisx->flags, ACTOR_FLAG_REACT_TO_LENS)) {
|
||||
Gfx_DrawDListXlu(play, sDLists[thisx->params]);
|
||||
} else {
|
||||
Gfx_DrawDListOpa(play, sDLists[thisx->params]);
|
||||
|
|
|
@ -72,7 +72,7 @@ void BgHakaMeganeBG_Init(Actor* thisx, PlayState* play) {
|
|||
|
||||
if (thisx->params == 0) {
|
||||
CollisionHeader_GetVirtual(&object_haka_objects_Col_009168, &colHeader);
|
||||
thisx->flags |= ACTOR_FLAG_7;
|
||||
thisx->flags |= ACTOR_FLAG_REACT_TO_LENS;
|
||||
this->unk_16A = 20;
|
||||
this->actionFunc = func_8087DFF8;
|
||||
} else if (thisx->params == 3) {
|
||||
|
|
|
@ -142,7 +142,7 @@ void BgHakaSgami_Init(Actor* thisx, PlayState* play) {
|
|||
thisx->params = (thisx->params >> 8) & 0xFF;
|
||||
|
||||
if (this->unk_151 != 0) {
|
||||
thisx->flags |= ACTOR_FLAG_7;
|
||||
thisx->flags |= ACTOR_FLAG_REACT_TO_LENS;
|
||||
}
|
||||
|
||||
Collider_InitTris(play, colliderScythe);
|
||||
|
|
|
@ -41,9 +41,9 @@ void BgMenkuriNisekabe_Update(Actor* thisx, PlayState* play) {
|
|||
BgMenkuriNisekabe* this = (BgMenkuriNisekabe*)thisx;
|
||||
|
||||
if (play->actorCtx.lensActive) {
|
||||
this->actor.flags |= ACTOR_FLAG_7;
|
||||
this->actor.flags |= ACTOR_FLAG_REACT_TO_LENS;
|
||||
} else {
|
||||
this->actor.flags &= ~ACTOR_FLAG_7;
|
||||
this->actor.flags &= ~ACTOR_FLAG_REACT_TO_LENS;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -51,7 +51,7 @@ void BgMenkuriNisekabe_Draw(Actor* thisx, PlayState* play) {
|
|||
BgMenkuriNisekabe* this = (BgMenkuriNisekabe*)thisx;
|
||||
u32 index = this->actor.params & 0xFF;
|
||||
|
||||
if (CHECK_FLAG_ALL(this->actor.flags, ACTOR_FLAG_7)) {
|
||||
if (CHECK_FLAG_ALL(this->actor.flags, ACTOR_FLAG_REACT_TO_LENS)) {
|
||||
Gfx_DrawDListXlu(play, sDLists[index]);
|
||||
} else {
|
||||
Gfx_DrawDListOpa(play, sDLists[index]);
|
||||
|
|
|
@ -74,7 +74,7 @@ void BgSpot02Objects_Init(Actor* thisx, PlayState* play) {
|
|||
} else if (thisx->params == 1) {
|
||||
this->actionFunc = func_808AC8FC;
|
||||
CollisionHeader_GetVirtual(&object_spot02_objects_Col_0128D8, &colHeader);
|
||||
thisx->flags |= ACTOR_FLAG_22;
|
||||
thisx->flags |= ACTOR_FLAG_IGNORE_POINT_LIGHTS;
|
||||
} else {
|
||||
if (play->sceneId == SCENE_GRAVEYARD) {
|
||||
this->actionFunc = func_808AC908;
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
#include "overlays/effects/ovl_Effect_Ss_Kakera/z_eff_ss_kakera.h"
|
||||
#include "assets/objects/gameplay_field_keep/gameplay_field_keep.h"
|
||||
|
||||
#define FLAGS ACTOR_FLAG_22
|
||||
#define FLAGS ACTOR_FLAG_IGNORE_POINT_LIGHTS
|
||||
|
||||
void BgSpot08Bakudankabe_Init(Actor* thisx, PlayState* play);
|
||||
void BgSpot08Bakudankabe_Destroy(Actor* thisx, PlayState* play);
|
||||
|
|
|
@ -1878,8 +1878,8 @@ void func_80902348(BossGanon2* this, PlayState* play) {
|
|||
}
|
||||
}
|
||||
|
||||
void func_80902524(BossGanon2* this, PlayState* play) {
|
||||
s8 temp_v0_4;
|
||||
void BossGanon2_CollisionCheck(BossGanon2* this, PlayState* play) {
|
||||
s8 health;
|
||||
ColliderElement* acHitElem;
|
||||
s16 i;
|
||||
u8 phi_v1_2;
|
||||
|
@ -1909,11 +1909,11 @@ void func_80902524(BossGanon2* this, PlayState* play) {
|
|||
Actor_PlaySfx(&this->actor, NA_SE_EN_MGANON_DAMAGE);
|
||||
Audio_StopSfxById(NA_SE_EN_MGANON_UNARI);
|
||||
this->actor.colChkInfo.health -= 2;
|
||||
temp_v0_4 = this->actor.colChkInfo.health;
|
||||
if (temp_v0_4 < 0x15 && this->unk_334 == 0) {
|
||||
health = this->actor.colChkInfo.health;
|
||||
if (health <= 20 && this->unk_334 == 0) {
|
||||
func_80900818(this, play);
|
||||
} else {
|
||||
if (temp_v0_4 <= 0) {
|
||||
if (health <= 0) {
|
||||
func_80901020(this, play);
|
||||
} else {
|
||||
func_80900210(this, play);
|
||||
|
@ -1943,13 +1943,13 @@ void func_80902524(BossGanon2* this, PlayState* play) {
|
|||
}
|
||||
}
|
||||
this->actor.colChkInfo.health -= phi_v1_2;
|
||||
temp_v0_4 = this->actor.colChkInfo.health;
|
||||
if ((temp_v0_4 < 0x15) && (this->unk_334 == 0)) {
|
||||
health = this->actor.colChkInfo.health;
|
||||
if ((health <= 20) && (this->unk_334 == 0)) {
|
||||
func_80900818(this, play);
|
||||
} else if ((temp_v0_4 <= 0) && (phi_v1_2 >= 2)) {
|
||||
} else if ((health <= 0) && (phi_v1_2 >= 2)) {
|
||||
func_80901020(this, play);
|
||||
} else {
|
||||
if (temp_v0_4 <= 0) {
|
||||
if (health <= 0) {
|
||||
this->actor.colChkInfo.health = 1;
|
||||
}
|
||||
func_80900210(this, play);
|
||||
|
@ -2067,7 +2067,7 @@ void BossGanon2_Update(Actor* thisx, PlayState* play) {
|
|||
func_80902348(this, play);
|
||||
CollisionCheck_SetOC(play, &play->colChkCtx, &this->unk_424.base);
|
||||
if (this->actionFunc != func_8090120C) {
|
||||
func_80902524(this, play);
|
||||
BossGanon2_CollisionCheck(this, play);
|
||||
CollisionCheck_SetAC(play, &play->colChkCtx, &this->unk_424.base);
|
||||
CollisionCheck_SetOC(play, &play->colChkCtx, &this->unk_444.base);
|
||||
CollisionCheck_SetAC(play, &play->colChkCtx, &this->unk_444.base);
|
||||
|
|
|
@ -581,7 +581,7 @@ void BossSst_HeadIntro(BossSst* this, PlayState* play) {
|
|||
sSubCamEye.y += 400.0f * 0.01f;
|
||||
sSubCamEye.z += 1550.0f * 0.01f;
|
||||
this->vVanish = true;
|
||||
this->actor.flags |= ACTOR_FLAG_7;
|
||||
this->actor.flags |= ACTOR_FLAG_REACT_TO_LENS;
|
||||
} else if (revealStateTimer < 40) {
|
||||
sSubCamAt.x += 125.0f * 0.01f;
|
||||
sSubCamAt.y += 350.0f * 0.01f;
|
||||
|
@ -819,7 +819,7 @@ void BossSst_HeadSetupStunned(BossSst* this) {
|
|||
this->colliderJntSph.base.atFlags &= ~(AT_ON | AT_HIT);
|
||||
this->colliderCyl.base.acFlags &= ~AC_ON;
|
||||
this->vVanish = false;
|
||||
this->actor.flags &= ~ACTOR_FLAG_7;
|
||||
this->actor.flags &= ~ACTOR_FLAG_REACT_TO_LENS;
|
||||
BossSst_HeadSfx(this, NA_SE_EN_SHADEST_FREEZE);
|
||||
this->actionFunc = BossSst_HeadStunned;
|
||||
}
|
||||
|
@ -2646,9 +2646,9 @@ void BossSst_UpdateHead(Actor* thisx, PlayState* play) {
|
|||
this->actionFunc(this, play);
|
||||
if (this->vVanish) {
|
||||
if (!play->actorCtx.lensActive || (thisx->colorFilterTimer != 0)) {
|
||||
this->actor.flags &= ~ACTOR_FLAG_7;
|
||||
this->actor.flags &= ~ACTOR_FLAG_REACT_TO_LENS;
|
||||
} else {
|
||||
this->actor.flags |= ACTOR_FLAG_7;
|
||||
this->actor.flags |= ACTOR_FLAG_REACT_TO_LENS;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2668,7 +2668,7 @@ void BossSst_UpdateHead(Actor* thisx, PlayState* play) {
|
|||
}
|
||||
|
||||
BossSst_MoveAround(this);
|
||||
if ((!this->vVanish || CHECK_FLAG_ALL(this->actor.flags, ACTOR_FLAG_7)) &&
|
||||
if ((!this->vVanish || CHECK_FLAG_ALL(this->actor.flags, ACTOR_FLAG_REACT_TO_LENS)) &&
|
||||
((this->actionFunc == BossSst_HeadReadyCharge) || (this->actionFunc == BossSst_HeadCharge) ||
|
||||
(this->actionFunc == BossSst_HeadFrozenHand) || (this->actionFunc == BossSst_HeadStunned) ||
|
||||
(this->actionFunc == BossSst_HeadVulnerable) || (this->actionFunc == BossSst_HeadDamage))) {
|
||||
|
@ -2777,7 +2777,7 @@ s32 BossSst_OverrideHeadDraw(PlayState* play, s32 limbIndex, Gfx** dList, Vec3f*
|
|||
s32 timer12;
|
||||
f32 shakeMod;
|
||||
|
||||
if (!CHECK_FLAG_ALL(this->actor.flags, ACTOR_FLAG_7) && this->vVanish) {
|
||||
if (!CHECK_FLAG_ALL(this->actor.flags, ACTOR_FLAG_REACT_TO_LENS) && this->vVanish) {
|
||||
*dList = NULL;
|
||||
} else if (this->actionFunc == BossSst_HeadThrash) { // Animation modifications for death cutscene
|
||||
shakeAmp = (this->timer / 10) + 1;
|
||||
|
@ -2868,7 +2868,7 @@ void BossSst_DrawHead(Actor* thisx, PlayState* play) {
|
|||
|
||||
OPEN_DISPS(play->state.gfxCtx, "../z_boss_sst.c", 6810);
|
||||
|
||||
if (!CHECK_FLAG_ALL(this->actor.flags, ACTOR_FLAG_7)) {
|
||||
if (!CHECK_FLAG_ALL(this->actor.flags, ACTOR_FLAG_REACT_TO_LENS)) {
|
||||
Gfx_SetupDL_25Opa(play->state.gfxCtx);
|
||||
gDPSetPrimColor(POLY_OPA_DISP++, 0x00, 0x80, sBodyColor.r, sBodyColor.g, sBodyColor.b, 255);
|
||||
if (!sBodyStatic) {
|
||||
|
@ -2895,7 +2895,7 @@ void BossSst_DrawHead(Actor* thisx, PlayState* play) {
|
|||
Matrix_RotateY(-randYaw, MTXMODE_APPLY);
|
||||
}
|
||||
|
||||
if (!CHECK_FLAG_ALL(this->actor.flags, ACTOR_FLAG_7)) {
|
||||
if (!CHECK_FLAG_ALL(this->actor.flags, ACTOR_FLAG_REACT_TO_LENS)) {
|
||||
POLY_OPA_DISP =
|
||||
SkelAnime_DrawFlex(play, this->skelAnime.skeleton, this->skelAnime.jointTable, this->skelAnime.dListCount,
|
||||
BossSst_OverrideHeadDraw, BossSst_PostHeadDraw, this, POLY_OPA_DISP);
|
||||
|
|
|
@ -160,7 +160,7 @@ void EnBox_Init(Actor* thisx, PlayState* play2) {
|
|||
this->dyna.actor.flags |= ACTOR_FLAG_4;
|
||||
} else {
|
||||
if (this->type == ENBOX_TYPE_4 || this->type == ENBOX_TYPE_6) {
|
||||
this->dyna.actor.flags |= ACTOR_FLAG_7;
|
||||
this->dyna.actor.flags |= ACTOR_FLAG_REACT_TO_LENS;
|
||||
}
|
||||
EnBox_SetupAction(this, EnBox_WaitOpen);
|
||||
this->movementFlags |= ENBOX_MOVE_IMMOBILE;
|
||||
|
@ -438,7 +438,7 @@ void EnBox_WaitOpen(EnBox* this, PlayState* play) {
|
|||
void EnBox_Open(EnBox* this, PlayState* play) {
|
||||
u16 sfxId;
|
||||
|
||||
this->dyna.actor.flags &= ~ACTOR_FLAG_7;
|
||||
this->dyna.actor.flags &= ~ACTOR_FLAG_REACT_TO_LENS;
|
||||
|
||||
if (SkelAnime_Update(&this->skelanime)) {
|
||||
if (this->unk_1F4 > 0) {
|
||||
|
@ -621,11 +621,11 @@ void EnBox_Draw(Actor* thisx, PlayState* play) {
|
|||
OPEN_DISPS(play->state.gfxCtx, "../z_en_box.c", 1581);
|
||||
|
||||
/*
|
||||
this->dyna.actor.flags & ACTOR_FLAG_7 is set by Init (if type is 4 or 6)
|
||||
this->dyna.actor.flags & ACTOR_FLAG_REACT_TO_LENS is set by Init (if type is 4 or 6)
|
||||
and cleared by Open
|
||||
*/
|
||||
if ((this->alpha == 255 && !(this->type == ENBOX_TYPE_4 || this->type == ENBOX_TYPE_6)) ||
|
||||
(!CHECK_FLAG_ALL(this->dyna.actor.flags, ACTOR_FLAG_7) &&
|
||||
(!CHECK_FLAG_ALL(this->dyna.actor.flags, ACTOR_FLAG_REACT_TO_LENS) &&
|
||||
(this->type == ENBOX_TYPE_4 || this->type == ENBOX_TYPE_6))) {
|
||||
gDPPipeSync(POLY_OPA_DISP++);
|
||||
gDPSetEnvColor(POLY_OPA_DISP++, 0, 0, 0, 255);
|
||||
|
|
|
@ -191,7 +191,7 @@ void EnDh_SetupWait(EnDh* this) {
|
|||
this->actor.shape.yOffset = -15000.0f;
|
||||
this->dirtWaveSpread = this->actor.speed = 0.0f;
|
||||
this->actor.world.rot.y = this->actor.shape.rot.y;
|
||||
this->actor.flags |= ACTOR_FLAG_7;
|
||||
this->actor.flags |= ACTOR_FLAG_REACT_TO_LENS;
|
||||
this->dirtWavePhase = this->actionState = this->actor.params = ENDH_WAIT_UNDERGROUND;
|
||||
EnDh_SetupAction(this, EnDh_Wait);
|
||||
}
|
||||
|
@ -208,7 +208,7 @@ void EnDh_Wait(EnDh* this, PlayState* play) {
|
|||
case 0:
|
||||
this->actor.flags |= ACTOR_FLAG_0;
|
||||
this->actor.shape.rot.y = this->actor.yawTowardsPlayer;
|
||||
this->actor.flags &= ~ACTOR_FLAG_7;
|
||||
this->actor.flags &= ~ACTOR_FLAG_REACT_TO_LENS;
|
||||
this->actionState++;
|
||||
this->drawDirtWave++;
|
||||
Actor_PlaySfx(&this->actor, NA_SE_EN_DEADHAND_HIDE);
|
||||
|
|
|
@ -147,7 +147,7 @@ void EnFirefly_Init(Actor* thisx, PlayState* play) {
|
|||
CollisionCheck_SetInfo(&this->actor.colChkInfo, &sDamageTable, &sColChkInfoInit);
|
||||
|
||||
if ((this->actor.params & 0x8000) != 0) {
|
||||
this->actor.flags |= ACTOR_FLAG_7;
|
||||
this->actor.flags |= ACTOR_FLAG_REACT_TO_LENS;
|
||||
if (1) {}
|
||||
this->actor.draw = EnFirefly_DrawInvisible;
|
||||
this->actor.params &= 0x7FFF;
|
||||
|
|
|
@ -138,7 +138,7 @@ void EnFloormas_Init(Actor* thisx, PlayState* play2) {
|
|||
// s16 cast needed
|
||||
this->actor.params &= (s16) ~(SPAWN_INVISIBLE);
|
||||
if (invisble) {
|
||||
this->actor.flags |= ACTOR_FLAG_7;
|
||||
this->actor.flags |= ACTOR_FLAG_REACT_TO_LENS;
|
||||
this->actor.draw = EnFloormas_DrawHighlighted;
|
||||
}
|
||||
|
||||
|
@ -280,7 +280,7 @@ void EnFloormas_SetupLand(EnFloormas* this) {
|
|||
void EnFloormas_SetupSplit(EnFloormas* this) {
|
||||
Actor_SetScale(&this->actor, 0.004f);
|
||||
this->actor.flags |= ACTOR_FLAG_4;
|
||||
if (CHECK_FLAG_ALL(this->actor.flags, ACTOR_FLAG_7)) {
|
||||
if (CHECK_FLAG_ALL(this->actor.flags, ACTOR_FLAG_REACT_TO_LENS)) {
|
||||
this->actor.draw = EnFloormas_DrawHighlighted;
|
||||
} else {
|
||||
this->actor.draw = EnFloormas_Draw;
|
||||
|
|
|
@ -18,7 +18,8 @@ typedef enum {
|
|||
/* 0 */ HONOTRAP_EYE_OPEN,
|
||||
/* 1 */ HONOTRAP_EYE_HALF,
|
||||
/* 2 */ HONOTRAP_EYE_CLOSE,
|
||||
/* 3 */ HONOTRAP_EYE_SHUT
|
||||
/* 3 */ HONOTRAP_EYE_SHUT,
|
||||
/* 4 */ HONOTRAP_EYE_MAX
|
||||
} EnHonotrapEyeState;
|
||||
|
||||
void EnHonotrap_Init(Actor* thisx, PlayState* play);
|
||||
|
@ -35,8 +36,8 @@ void EnHonotrap_EyeAttack(EnHonotrap* this, PlayState* play);
|
|||
void EnHonotrap_SetupEyeClose(EnHonotrap* this);
|
||||
void EnHonotrap_EyeClose(EnHonotrap* this, PlayState* play);
|
||||
|
||||
void EnHonotrap_SetupFlame(EnHonotrap* this);
|
||||
void EnHonotrap_Flame(EnHonotrap* this, PlayState* play);
|
||||
void EnHonotrap_SetupFlameGrow(EnHonotrap* this);
|
||||
void EnHonotrap_FlameGrow(EnHonotrap* this, PlayState* play);
|
||||
void EnHonotrap_SetupFlameDrop(EnHonotrap* this);
|
||||
void EnHonotrap_FlameDrop(EnHonotrap* this, PlayState* play);
|
||||
|
||||
|
@ -138,17 +139,17 @@ void EnHonotrap_FlameCollisionCheck(EnHonotrap* this, PlayState* play) {
|
|||
}
|
||||
|
||||
void EnHonotrap_GetNormal(Vec3f* normal, Vec3f* vec) {
|
||||
f32 mag = Math3D_Vec3fMagnitude(vec);
|
||||
f32 magnitude = Math3D_Vec3fMagnitude(vec);
|
||||
|
||||
if (mag < 0.001f) {
|
||||
if (magnitude < 0.001f) {
|
||||
PRINTF("Warning : vector size zero (%s %d)\n", "../z_en_honotrap.c", 328, normal);
|
||||
|
||||
normal->x = normal->y = 0.0f;
|
||||
normal->z = 1.0f;
|
||||
} else {
|
||||
normal->x = vec->x * (1.0f / mag);
|
||||
normal->y = vec->y * (1.0f / mag);
|
||||
normal->z = vec->z * (1.0f / mag);
|
||||
normal->x = vec->x * (1.0f / magnitude);
|
||||
normal->y = vec->y * (1.0f / magnitude);
|
||||
normal->z = vec->z * (1.0f / magnitude);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -198,9 +199,9 @@ void EnHonotrap_InitFlame(Actor* thisx, PlayState* play) {
|
|||
this->targetPos = GET_PLAYER(play)->actor.world.pos;
|
||||
this->targetPos.y += 10.0f;
|
||||
this->flameScroll = Rand_ZeroOne() * 511.0f;
|
||||
EnHonotrap_SetupFlame(this);
|
||||
EnHonotrap_SetupFlameGrow(this);
|
||||
Actor_PlaySfx(&this->actor, NA_SE_EV_FLAME_IGNITION);
|
||||
if (this->actor.params == HONOTRAP_FLAME_DROP) {
|
||||
if (this->actor.params == HONOTRAP_TYPE_FLAME_DROP) {
|
||||
this->actor.room = -1;
|
||||
this->collider.cyl.dim.radius = 12;
|
||||
this->collider.cyl.dim.height = 30;
|
||||
|
@ -210,7 +211,7 @@ void EnHonotrap_InitFlame(Actor* thisx, PlayState* play) {
|
|||
|
||||
void EnHonotrap_Init(Actor* thisx, PlayState* play) {
|
||||
Actor_ProcessInitChain(thisx, sInitChain);
|
||||
if (thisx->params == HONOTRAP_EYE) {
|
||||
if (thisx->params == HONOTRAP_TYPE_EYE) {
|
||||
EnHonotrap_InitEye(thisx, play);
|
||||
} else {
|
||||
EnHonotrap_InitFlame(thisx, play);
|
||||
|
@ -221,7 +222,7 @@ void EnHonotrap_Destroy(Actor* thisx, PlayState* play) {
|
|||
s32 pad;
|
||||
EnHonotrap* this = (EnHonotrap*)thisx;
|
||||
|
||||
if (this->actor.params == HONOTRAP_EYE) {
|
||||
if (this->actor.params == HONOTRAP_TYPE_EYE) {
|
||||
Collider_DestroyTris(play, &this->collider.tris);
|
||||
} else {
|
||||
Collider_DestroyCylinder(play, &this->collider.cyl);
|
||||
|
@ -236,11 +237,14 @@ void EnHonotrap_SetupEyeIdle(EnHonotrap* this) {
|
|||
void EnHonotrap_EyeIdle(EnHonotrap* this, PlayState* play) {
|
||||
if (this->actor.child != NULL) {
|
||||
this->timer = 200;
|
||||
} else if ((this->timer <= 0) && (this->actor.xzDistToPlayer < 750.0f) && (0.0f > this->actor.yDistToPlayer) &&
|
||||
(this->actor.yDistToPlayer > -700.0f) &&
|
||||
(-0x4000 < (this->actor.yawTowardsPlayer - this->actor.shape.rot.y)) &&
|
||||
((this->actor.yawTowardsPlayer - this->actor.shape.rot.y) < 0x4000)) {
|
||||
EnHonotrap_SetupEyeOpen(this);
|
||||
} else if ((this->timer <= 0) && (this->actor.xzDistToPlayer < 750.0f)) {
|
||||
if ((this->actor.yDistToPlayer < 0.0f) && (this->actor.yDistToPlayer > -700.0f)) {
|
||||
s32 angle = this->actor.yawTowardsPlayer - this->actor.shape.rot.y;
|
||||
|
||||
if ((angle > -0x4000) && (angle < 0x4000)) {
|
||||
EnHonotrap_SetupEyeOpen(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -252,18 +256,14 @@ void EnHonotrap_SetupEyeOpen(EnHonotrap* this) {
|
|||
}
|
||||
|
||||
void EnHonotrap_EyeOpen(EnHonotrap* this, PlayState* play) {
|
||||
f32 cos;
|
||||
f32 sin;
|
||||
|
||||
this->eyeState--;
|
||||
if (this->eyeState <= HONOTRAP_EYE_OPEN) {
|
||||
EnHonotrap_SetupEyeAttack(this);
|
||||
sin = Math_SinS(this->actor.shape.rot.y);
|
||||
cos = Math_CosS(this->actor.shape.rot.y);
|
||||
Actor_SpawnAsChild(&play->actorCtx, &this->actor, play, ACTOR_EN_HONOTRAP,
|
||||
(sin * 12.0f) + this->actor.home.pos.x, this->actor.home.pos.y - 10.0f,
|
||||
(cos * 12.0f) + this->actor.home.pos.z, this->actor.home.rot.x, this->actor.home.rot.y,
|
||||
this->actor.home.rot.z, HONOTRAP_FLAME_MOVE);
|
||||
Actor_SpawnAsChild(
|
||||
&play->actorCtx, &this->actor, play, ACTOR_EN_HONOTRAP,
|
||||
(Math_SinS(this->actor.shape.rot.y) * 12.0f) + this->actor.home.pos.x, this->actor.home.pos.y - 10.0f,
|
||||
(Math_CosS(this->actor.shape.rot.y) * 12.0f) + this->actor.home.pos.z, this->actor.home.rot.x,
|
||||
this->actor.home.rot.y, this->actor.home.rot.z, HONOTRAP_TYPE_FLAME_MOVE);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -290,20 +290,19 @@ void EnHonotrap_EyeClose(EnHonotrap* this, PlayState* play) {
|
|||
}
|
||||
}
|
||||
|
||||
void EnHonotrap_SetupFlame(EnHonotrap* this) {
|
||||
this->actionFunc = EnHonotrap_Flame;
|
||||
void EnHonotrap_SetupFlameGrow(EnHonotrap* this) {
|
||||
this->actionFunc = EnHonotrap_FlameGrow;
|
||||
}
|
||||
|
||||
void EnHonotrap_Flame(EnHonotrap* this, PlayState* play) {
|
||||
s32 pad;
|
||||
s32 ready =
|
||||
Math_StepToF(&this->actor.scale.x, (this->actor.params == HONOTRAP_FLAME_MOVE) ? 0.004f : 0.0048f, 0.0006f);
|
||||
void EnHonotrap_FlameGrow(EnHonotrap* this, PlayState* play) {
|
||||
f32 targetScale = (this->actor.params == HONOTRAP_TYPE_FLAME_MOVE) ? 0.004f : 0.0048f;
|
||||
s32 targetReached = Math_StepToF(&this->actor.scale.x, targetScale, 0.0006f);
|
||||
|
||||
this->actor.scale.z = this->actor.scale.y = this->actor.scale.x;
|
||||
if (ready) {
|
||||
if (this->actor.params == HONOTRAP_FLAME_MOVE) {
|
||||
if (targetReached) {
|
||||
if (this->actor.params == HONOTRAP_TYPE_FLAME_MOVE) {
|
||||
EnHonotrap_SetupFlameMove(this);
|
||||
} else {
|
||||
} else { // HONOTRAP_TYPE_FLAME_DROP
|
||||
EnHonotrap_SetupFlameDrop(this);
|
||||
}
|
||||
}
|
||||
|
@ -324,49 +323,46 @@ void EnHonotrap_FlameDrop(EnHonotrap* this, PlayState* play) {
|
|||
}
|
||||
this->actor.velocity.x = this->actor.velocity.y = this->actor.velocity.z = 0.0f;
|
||||
EnHonotrap_SetupFlameVanish(this);
|
||||
} else {
|
||||
if (this->actor.velocity.y > 0.0f) {
|
||||
this->actor.world.pos.x += this->actor.velocity.x;
|
||||
this->actor.world.pos.z += this->actor.velocity.z;
|
||||
Actor_UpdateBgCheckInfo(play, &this->actor, 7.0f, 12.0f, 0.0f,
|
||||
UPDBGCHECKINFO_FLAG_0 | UPDBGCHECKINFO_FLAG_2);
|
||||
}
|
||||
if (!Math_StepToF(&this->actor.world.pos.y, this->actor.floorHeight + 1.0f, this->actor.velocity.y)) {
|
||||
this->actor.velocity.y += 1.0f;
|
||||
} else {
|
||||
this->actor.velocity.y = 0.0f;
|
||||
}
|
||||
EnHonotrap_FlameCollisionCheck(this, play);
|
||||
return;
|
||||
}
|
||||
if (this->actor.velocity.y > 0.0f) {
|
||||
this->actor.world.pos.x += this->actor.velocity.x;
|
||||
this->actor.world.pos.z += this->actor.velocity.z;
|
||||
Actor_UpdateBgCheckInfo(play, &this->actor, 7.0f, 12.0f, 0.0f, UPDBGCHECKINFO_FLAG_0 | UPDBGCHECKINFO_FLAG_2);
|
||||
}
|
||||
if (!Math_StepToF(&this->actor.world.pos.y, this->actor.floorHeight + 1.0f, this->actor.velocity.y)) {
|
||||
this->actor.velocity.y += 1.0f;
|
||||
} else {
|
||||
this->actor.velocity.y = 0.0f;
|
||||
}
|
||||
EnHonotrap_FlameCollisionCheck(this, play);
|
||||
}
|
||||
|
||||
void EnHonotrap_SetupFlameMove(EnHonotrap* this) {
|
||||
f32 distFrac;
|
||||
f32 distInverse;
|
||||
|
||||
this->actionFunc = EnHonotrap_FlameMove;
|
||||
|
||||
distFrac = 1.0f / (Actor_WorldDistXYZToPoint(&this->actor, &this->targetPos) + 1.0f);
|
||||
this->actor.velocity.x = (this->targetPos.x - this->actor.world.pos.x) * distFrac;
|
||||
this->actor.velocity.y = (this->targetPos.y - this->actor.world.pos.y) * distFrac;
|
||||
this->actor.velocity.z = (this->targetPos.z - this->actor.world.pos.z) * distFrac;
|
||||
distInverse = 1.0f / (Actor_WorldDistXYZToPoint(&this->actor, &this->targetPos) + 1.0f);
|
||||
this->actor.velocity.x = (this->targetPos.x - this->actor.world.pos.x) * distInverse;
|
||||
this->actor.velocity.y = (this->targetPos.y - this->actor.world.pos.y) * distInverse;
|
||||
this->actor.velocity.z = (this->targetPos.z - this->actor.world.pos.z) * distInverse;
|
||||
this->speedMod = 0.0f;
|
||||
|
||||
this->timer = 160;
|
||||
}
|
||||
|
||||
void EnHonotrap_FlameMove(EnHonotrap* this, PlayState* play) {
|
||||
s32 pad;
|
||||
Actor* thisx = &this->actor;
|
||||
Vec3f speed;
|
||||
s32 ready;
|
||||
s32 targetReached;
|
||||
|
||||
Math_StepToF(&this->speedMod, 13.0f, 0.5f);
|
||||
speed.x = fabsf(this->speedMod * this->actor.velocity.x);
|
||||
speed.y = fabsf(this->speedMod * this->actor.velocity.y);
|
||||
speed.z = fabsf(this->speedMod * this->actor.velocity.z);
|
||||
ready = true;
|
||||
ready &= Math_StepToF(&this->actor.world.pos.x, this->targetPos.x, speed.x);
|
||||
ready &= Math_StepToF(&this->actor.world.pos.y, this->targetPos.y, speed.y);
|
||||
ready &= Math_StepToF(&this->actor.world.pos.z, this->targetPos.z, speed.z);
|
||||
speed.x = fabsf(this->speedMod * thisx->velocity.x);
|
||||
speed.y = fabsf(this->speedMod * thisx->velocity.y);
|
||||
speed.z = fabsf(this->speedMod * thisx->velocity.z);
|
||||
targetReached = true;
|
||||
targetReached &= Math_StepToF(&thisx->world.pos.x, this->targetPos.x, speed.x);
|
||||
targetReached &= Math_StepToF(&thisx->world.pos.y, this->targetPos.y, speed.y);
|
||||
targetReached &= Math_StepToF(&thisx->world.pos.z, this->targetPos.z, speed.z);
|
||||
Actor_UpdateBgCheckInfo(play, &this->actor, 7.0f, 10.0f, 0.0f,
|
||||
UPDBGCHECKINFO_FLAG_0 | UPDBGCHECKINFO_FLAG_2 | UPDBGCHECKINFO_FLAG_3 |
|
||||
UPDBGCHECKINFO_FLAG_4);
|
||||
|
@ -382,19 +378,20 @@ void EnHonotrap_FlameMove(EnHonotrap* this, PlayState* play) {
|
|||
shieldVec.z = -player->shieldMf.zz;
|
||||
EnHonotrap_GetNormal(&shieldNorm, &shieldVec);
|
||||
|
||||
tempVel = this->actor.velocity;
|
||||
Math3D_Vec3fReflect(&tempVel, &shieldNorm, &this->actor.velocity);
|
||||
this->actor.speed = this->speedMod * 0.5f;
|
||||
this->actor.world.rot.y = Math_Atan2S(this->actor.velocity.z, this->actor.velocity.x);
|
||||
tempVel = thisx->velocity;
|
||||
Math3D_Vec3fReflect(&tempVel, &shieldNorm, &thisx->velocity);
|
||||
thisx->speed = this->speedMod * 0.5f;
|
||||
thisx->world.rot.y = Math_Atan2S(thisx->velocity.z, thisx->velocity.x);
|
||||
EnHonotrap_SetupFlameVanish(this);
|
||||
} else if (this->collider.tris.base.atFlags & AT_HIT) {
|
||||
this->actor.velocity.y = this->actor.speed = 0.0f;
|
||||
thisx->speed = 0.0f;
|
||||
thisx->velocity.y = 0.0f;
|
||||
EnHonotrap_SetupFlameVanish(this);
|
||||
} else if (this->timer <= 0) {
|
||||
EnHonotrap_SetupFlameVanish(this);
|
||||
} else {
|
||||
EnHonotrap_FlameCollisionCheck(this, play);
|
||||
if (ready) {
|
||||
if (targetReached) {
|
||||
EnHonotrap_SetupFlameChase(this);
|
||||
}
|
||||
}
|
||||
|
@ -402,10 +399,9 @@ void EnHonotrap_FlameMove(EnHonotrap* this, PlayState* play) {
|
|||
|
||||
void EnHonotrap_SetupFlameChase(EnHonotrap* this) {
|
||||
this->actionFunc = EnHonotrap_FlameChase;
|
||||
|
||||
this->actor.velocity.x = this->actor.velocity.y = this->actor.velocity.z = this->actor.speed = 0.0f;
|
||||
this->actor.speed = 0.0f;
|
||||
this->actor.velocity.x = this->actor.velocity.y = this->actor.velocity.z = 0.0f;
|
||||
this->actor.world.rot.x = this->actor.world.rot.y = this->actor.world.rot.z = 0;
|
||||
|
||||
this->timer = 100;
|
||||
}
|
||||
|
||||
|
@ -448,28 +444,27 @@ void EnHonotrap_SetupFlameVanish(EnHonotrap* this) {
|
|||
|
||||
void EnHonotrap_FlameVanish(EnHonotrap* this, PlayState* play) {
|
||||
s32 pad;
|
||||
s32 ready = Math_StepToF(&this->actor.scale.x, 0.0001f, 0.00015f);
|
||||
s32 targetReached = Math_StepToF(&this->actor.scale.x, 0.0001f, 0.00015f);
|
||||
|
||||
this->actor.scale.z = this->actor.scale.y = this->actor.scale.x;
|
||||
Actor_MoveXZGravity(&this->actor);
|
||||
Actor_UpdateBgCheckInfo(play, &this->actor, 7.0f, 10.0f, 0.0f,
|
||||
UPDBGCHECKINFO_FLAG_0 | UPDBGCHECKINFO_FLAG_2 | UPDBGCHECKINFO_FLAG_3 |
|
||||
UPDBGCHECKINFO_FLAG_4);
|
||||
if (ready) {
|
||||
if (targetReached) {
|
||||
Actor_Kill(&this->actor);
|
||||
}
|
||||
}
|
||||
|
||||
void EnHonotrap_Update(Actor* thisx, PlayState* play) {
|
||||
static Vec3f velocity = { 0.0f, 0.0f, 0.0f };
|
||||
static Vec3f accel = { 0.0f, 0.1f, 0.0f };
|
||||
s32 pad;
|
||||
static Vec3f sVelocity = { 0.0f, 0.0f, 0.0f };
|
||||
static Vec3f sAccel = { 0.0f, 0.1f, 0.0f };
|
||||
EnHonotrap* this = (EnHonotrap*)thisx;
|
||||
|
||||
if (this->timer > 0) {
|
||||
this->timer--;
|
||||
}
|
||||
if (this->actor.params == HONOTRAP_EYE) {
|
||||
if (this->actor.params == HONOTRAP_TYPE_EYE) {
|
||||
if ((this->actor.child != NULL) && (this->actor.child->update == NULL)) {
|
||||
this->actor.child = NULL;
|
||||
}
|
||||
|
@ -481,9 +476,9 @@ void EnHonotrap_Update(Actor* thisx, PlayState* play) {
|
|||
Actor_PlaySfx(&this->actor, NA_SE_EV_BURN_OUT - SFX_FLAG);
|
||||
}
|
||||
this->actionFunc(this, play);
|
||||
if (this->actor.params == HONOTRAP_EYE) {
|
||||
if (this->actor.params == HONOTRAP_TYPE_EYE) {
|
||||
if (this->collider.tris.base.acFlags & AC_HIT) {
|
||||
EffectSsBomb2_SpawnLayered(play, &this->actor.world.pos, &velocity, &accel, 15, 8);
|
||||
EffectSsBomb2_SpawnLayered(play, &this->actor.world.pos, &sVelocity, &sAccel, 15, 8);
|
||||
Actor_Kill(&this->actor);
|
||||
} else if (this->eyeState < HONOTRAP_EYE_SHUT) {
|
||||
this->collider.tris.base.acFlags &= ~AC_HIT;
|
||||
|
@ -493,7 +488,7 @@ void EnHonotrap_Update(Actor* thisx, PlayState* play) {
|
|||
}
|
||||
|
||||
void EnHonotrap_DrawEye(Actor* thisx, PlayState* play) {
|
||||
static void* eyeTextures[] = {
|
||||
static void* sSilverEyeTextures[HONOTRAP_EYE_MAX] = {
|
||||
gEyeSwitchSilverOpenTex,
|
||||
gEyeSwitchSilverHalfTex,
|
||||
gEyeSwitchSilverClosedTex,
|
||||
|
@ -504,7 +499,7 @@ void EnHonotrap_DrawEye(Actor* thisx, PlayState* play) {
|
|||
OPEN_DISPS(play->state.gfxCtx, "../z_en_honotrap.c", 982);
|
||||
|
||||
Gfx_SetupDL_25Opa(play->state.gfxCtx);
|
||||
gSPSegment(POLY_OPA_DISP++, 0x08, SEGMENTED_TO_VIRTUAL(eyeTextures[this->eyeState]));
|
||||
gSPSegment(POLY_OPA_DISP++, 0x08, SEGMENTED_TO_VIRTUAL(sSilverEyeTextures[this->eyeState]));
|
||||
gSPMatrix(POLY_OPA_DISP++, MATRIX_NEW(play->state.gfxCtx, "../z_en_honotrap.c", 987),
|
||||
G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
|
||||
gSPDisplayList(POLY_OPA_DISP++, gEyeSwitch2DL);
|
||||
|
@ -520,10 +515,9 @@ void EnHonotrap_DrawFlame(Actor* thisx, PlayState* play) {
|
|||
|
||||
Gfx_SetupDL_25Xlu(play->state.gfxCtx);
|
||||
this->flameScroll -= 20;
|
||||
this->flameScroll &= 0x1FF;
|
||||
gSPSegment(
|
||||
POLY_XLU_DISP++, 0x08,
|
||||
Gfx_TwoTexScroll(play->state.gfxCtx, G_TX_RENDERTILE, 0, 0, 0x20, 0x40, 1, 0, this->flameScroll, 0x20, 0x80));
|
||||
this->flameScroll %= (128U << 2);
|
||||
gSPSegment(POLY_XLU_DISP++, 0x08,
|
||||
Gfx_TwoTexScroll(play->state.gfxCtx, G_TX_RENDERTILE, 0, 0, 32, 64, 1, 0, this->flameScroll, 32, 128));
|
||||
gDPSetPrimColor(POLY_XLU_DISP++, 0x80, 0x80, 255, 200, 0, 255);
|
||||
gDPSetEnvColor(POLY_XLU_DISP++, 255, 0, 0, 0);
|
||||
Matrix_RotateY(BINANG_TO_RAD((s16)(Camera_GetCamDirYaw(GET_ACTIVE_CAM(play)) - this->actor.shape.rot.y + 0x8000)),
|
||||
|
@ -537,11 +531,12 @@ void EnHonotrap_DrawFlame(Actor* thisx, PlayState* play) {
|
|||
|
||||
void EnHonotrap_Draw(Actor* thisx, PlayState* play) {
|
||||
switch (thisx->params) {
|
||||
case HONOTRAP_EYE:
|
||||
case HONOTRAP_TYPE_EYE:
|
||||
EnHonotrap_DrawEye(thisx, play);
|
||||
break;
|
||||
case HONOTRAP_FLAME_MOVE:
|
||||
case HONOTRAP_FLAME_DROP:
|
||||
|
||||
case HONOTRAP_TYPE_FLAME_MOVE:
|
||||
case HONOTRAP_TYPE_FLAME_DROP:
|
||||
EnHonotrap_DrawFlame(thisx, play);
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -10,10 +10,10 @@ typedef void (*EnHonotrapActionFunc)(struct EnHonotrap*, PlayState*);
|
|||
|
||||
typedef union {
|
||||
struct {
|
||||
ColliderTris tris;
|
||||
ColliderTrisElement elements[2];
|
||||
/* 0x00 */ ColliderTris tris;
|
||||
/* 0x20 */ ColliderTrisElement elements[2];
|
||||
};
|
||||
ColliderCylinder cyl;
|
||||
/* 0x00 */ ColliderCylinder cyl;
|
||||
} EnHonotrapCollider; // size = 0xD8
|
||||
|
||||
typedef struct EnHonotrap {
|
||||
|
@ -30,9 +30,9 @@ typedef struct EnHonotrap {
|
|||
} EnHonotrap; // size = 0x0244
|
||||
|
||||
typedef enum {
|
||||
HONOTRAP_EYE,
|
||||
HONOTRAP_FLAME_MOVE,
|
||||
HONOTRAP_FLAME_DROP
|
||||
HONOTRAP_TYPE_EYE,
|
||||
HONOTRAP_TYPE_FLAME_MOVE,
|
||||
HONOTRAP_TYPE_FLAME_DROP
|
||||
} EnHonotrapType;
|
||||
|
||||
#endif
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
#include "z_en_po_desert.h"
|
||||
#include "assets/objects/object_po_field/object_po_field.h"
|
||||
|
||||
#define FLAGS (ACTOR_FLAG_4 | ACTOR_FLAG_7 | ACTOR_FLAG_IGNORE_QUAKE)
|
||||
#define FLAGS (ACTOR_FLAG_4 | ACTOR_FLAG_REACT_TO_LENS | ACTOR_FLAG_IGNORE_QUAKE)
|
||||
|
||||
void EnPoDesert_Init(Actor* thisx, PlayState* play);
|
||||
void EnPoDesert_Destroy(Actor* thisx, PlayState* play);
|
||||
|
@ -197,11 +197,11 @@ void EnPoDesert_Update(Actor* thisx, PlayState* play) {
|
|||
Collider_UpdateCylinder(&this->actor, &this->collider);
|
||||
CollisionCheck_SetOC(play, &play->colChkCtx, &this->collider.base);
|
||||
if (play->actorCtx.lensActive) {
|
||||
this->actor.flags |= ACTOR_FLAG_0 | ACTOR_FLAG_7;
|
||||
this->actor.flags |= ACTOR_FLAG_0 | ACTOR_FLAG_REACT_TO_LENS;
|
||||
this->actor.shape.shadowDraw = ActorShadow_DrawCircle;
|
||||
} else {
|
||||
this->actor.shape.shadowDraw = NULL;
|
||||
this->actor.flags &= ~(ACTOR_FLAG_0 | ACTOR_FLAG_7);
|
||||
this->actor.flags &= ~(ACTOR_FLAG_0 | ACTOR_FLAG_REACT_TO_LENS);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -214,7 +214,7 @@ s32 EnPoDesert_OverrideLimbDraw(PlayState* play, s32 limbIndex, Gfx** dList, Vec
|
|||
mtxScale = this->actionTimer / 16.0f;
|
||||
Matrix_Scale(mtxScale, mtxScale, mtxScale, MTXMODE_APPLY);
|
||||
}
|
||||
if (!CHECK_FLAG_ALL(this->actor.flags, ACTOR_FLAG_7)) {
|
||||
if (!CHECK_FLAG_ALL(this->actor.flags, ACTOR_FLAG_REACT_TO_LENS)) {
|
||||
*dList = NULL;
|
||||
}
|
||||
return false;
|
||||
|
@ -234,7 +234,7 @@ void EnPoDesert_PostLimbDraw(PlayState* play, s32 limbIndex, Gfx** dList, Vec3s*
|
|||
color.r = (s16)(rand * 30.0f) + 225;
|
||||
color.g = (s16)(rand * 100.0f) + 155;
|
||||
color.b = (s16)(rand * 160.0f) + 95;
|
||||
if (CHECK_FLAG_ALL(this->actor.flags, ACTOR_FLAG_7)) {
|
||||
if (CHECK_FLAG_ALL(this->actor.flags, ACTOR_FLAG_REACT_TO_LENS)) {
|
||||
gDPPipeSync((*gfxP)++);
|
||||
gDPSetEnvColor((*gfxP)++, color.r, color.g, color.b, 255);
|
||||
gSPMatrix((*gfxP)++, MATRIX_NEW(play->state.gfxCtx, "../z_en_po_desert.c", 523),
|
||||
|
|
|
@ -204,7 +204,7 @@ void EnPoRelay_Race(EnPoRelay* this, PlayState* play) {
|
|||
Actor_Spawn(&play->actorCtx, play, ACTOR_EN_HONOTRAP,
|
||||
Math_CosS(this->unk_19A) * speedXZ + this->actor.world.pos.x, this->actor.world.pos.y,
|
||||
Math_SinS(this->unk_19A) * speedXZ + this->actor.world.pos.z, 0,
|
||||
(this->unk_19A + 0x8000) - (0x2000 * multiplier), 0, HONOTRAP_FLAME_DROP);
|
||||
(this->unk_19A + 0x8000) - (0x2000 * multiplier), 0, HONOTRAP_TYPE_FLAME_DROP);
|
||||
}
|
||||
}
|
||||
Math_SmoothStepToS(&this->actor.world.rot.y, this->unk_19A, 2, 0x1000, 0x100);
|
||||
|
|
|
@ -181,7 +181,7 @@ void EnRd_Init(Actor* thisx, PlayState* play) {
|
|||
SkelAnime_Update(&this->skelAnime);
|
||||
|
||||
if (this->actor.params == REDEAD_TYPE_INVISIBLE) {
|
||||
this->actor.flags |= ACTOR_FLAG_7;
|
||||
this->actor.flags |= ACTOR_FLAG_REACT_TO_LENS;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -790,7 +790,7 @@ void EnSt_Init(Actor* thisx, PlayState* play) {
|
|||
this->blureIdx = EnSt_CreateBlureEffect(play);
|
||||
EnSt_InitColliders(this, play);
|
||||
if (thisx->params == 2) {
|
||||
this->actor.flags |= ACTOR_FLAG_7;
|
||||
this->actor.flags |= ACTOR_FLAG_REACT_TO_LENS;
|
||||
}
|
||||
if (this->actor.params == 1) {
|
||||
this->actor.naviEnemyId = NAVI_ENEMY_BIG_SKULLTULA;
|
||||
|
|
|
@ -306,7 +306,7 @@ void EnTest_Init(Actor* thisx, PlayState* play) {
|
|||
}
|
||||
|
||||
if (this->actor.params == STALFOS_TYPE_INVISIBLE) {
|
||||
this->actor.flags |= ACTOR_FLAG_7;
|
||||
this->actor.flags |= ACTOR_FLAG_REACT_TO_LENS;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1810,10 +1810,10 @@ void EnTest_Update(Actor* thisx, PlayState* play) {
|
|||
|
||||
if (this->actor.params == STALFOS_TYPE_INVISIBLE) {
|
||||
if (play->actorCtx.lensActive) {
|
||||
this->actor.flags |= ACTOR_FLAG_0 | ACTOR_FLAG_7;
|
||||
this->actor.flags |= ACTOR_FLAG_0 | ACTOR_FLAG_REACT_TO_LENS;
|
||||
this->actor.shape.shadowDraw = ActorShadow_DrawFeet;
|
||||
} else {
|
||||
this->actor.flags &= ~(ACTOR_FLAG_0 | ACTOR_FLAG_7);
|
||||
this->actor.flags &= ~(ACTOR_FLAG_0 | ACTOR_FLAG_REACT_TO_LENS);
|
||||
this->actor.shape.shadowDraw = NULL;
|
||||
}
|
||||
}
|
||||
|
@ -1836,7 +1836,8 @@ s32 EnTest_OverrideLimbDraw(PlayState* play, s32 limbIndex, Gfx** dList, Vec3f*
|
|||
CLOSE_DISPS(play->state.gfxCtx, "../z_en_test.c", 3587);
|
||||
}
|
||||
|
||||
if ((this->actor.params == STALFOS_TYPE_INVISIBLE) && !CHECK_FLAG_ALL(this->actor.flags, ACTOR_FLAG_7)) {
|
||||
if ((this->actor.params == STALFOS_TYPE_INVISIBLE) &&
|
||||
!CHECK_FLAG_ALL(this->actor.flags, ACTOR_FLAG_REACT_TO_LENS)) {
|
||||
*dList = NULL;
|
||||
}
|
||||
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
#include "assets/objects/gameplay_keep/gameplay_keep.h"
|
||||
#include "terminal.h"
|
||||
|
||||
#define FLAGS ACTOR_FLAG_22
|
||||
#define FLAGS ACTOR_FLAG_IGNORE_POINT_LIGHTS
|
||||
|
||||
void ObjBean_Init(Actor* thisx, PlayState* play);
|
||||
void ObjBean_Destroy(Actor* thisx, PlayState* play);
|
||||
|
|
|
@ -3,11 +3,7 @@
|
|||
import argparse
|
||||
from pathlib import Path
|
||||
|
||||
try:
|
||||
import mapfile_parser
|
||||
except ImportError:
|
||||
print("Missing dependency mapfile_parser, install it with `python3 -m pip install 'mapfile-parser>=1.2.1,<2.0.0'`")
|
||||
exit(1)
|
||||
import mapfile_parser
|
||||
|
||||
|
||||
def symInfoMain():
|
||||
|
|
|
@ -13,7 +13,7 @@ asm_dir = root_dir + "asm/non_matchings/overlays/actors"
|
|||
build_dir = root_dir + "build/gc-eu-mq-dbg/"
|
||||
|
||||
def read_rom():
|
||||
with open("baserom.z64", "rb") as f:
|
||||
with open("baseroms/gc-eu-mq-dbg/baserom-decompressed.z64", "rb") as f:
|
||||
return f.read()
|
||||
|
||||
|
||||
|
|
342
tools/compress.py
Normal file
342
tools/compress.py
Normal file
|
@ -0,0 +1,342 @@
|
|||
# SPDX-FileCopyrightText: 2024 zeldaret
|
||||
# SPDX-License-Identifier: CC0-1.0
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import argparse
|
||||
from pathlib import Path
|
||||
import dataclasses
|
||||
import struct
|
||||
import time
|
||||
import multiprocessing
|
||||
import multiprocessing.pool
|
||||
|
||||
import crunch64
|
||||
|
||||
|
||||
STRUCT_IIII = struct.Struct(">IIII")
|
||||
|
||||
|
||||
@dataclasses.dataclass
|
||||
class DmaEntry:
|
||||
"""
|
||||
A Python counterpart to the dmadata entry struct:
|
||||
```c
|
||||
typedef struct {
|
||||
/* 0x00 */ uintptr_t vromStart;
|
||||
/* 0x04 */ uintptr_t vromEnd;
|
||||
/* 0x08 */ uintptr_t romStart;
|
||||
/* 0x0C */ uintptr_t romEnd;
|
||||
} DmaEntry;
|
||||
```
|
||||
"""
|
||||
|
||||
vromStart: int
|
||||
vromEnd: int
|
||||
romStart: int
|
||||
romEnd: int
|
||||
|
||||
def __repr__(self):
|
||||
return (
|
||||
"DmaEntry("
|
||||
f"vromStart=0x{self.vromStart:08X}, "
|
||||
f"vromEnd=0x{self.vromEnd:08X}, "
|
||||
f"romStart=0x{self.romStart:08X}, "
|
||||
f"romEnd=0x{self.romEnd:08X}"
|
||||
")"
|
||||
)
|
||||
|
||||
SIZE_BYTES = STRUCT_IIII.size
|
||||
|
||||
def to_bin(self, data: memoryview):
|
||||
STRUCT_IIII.pack_into(
|
||||
data,
|
||||
0,
|
||||
self.vromStart,
|
||||
self.vromEnd,
|
||||
self.romStart,
|
||||
self.romEnd,
|
||||
)
|
||||
|
||||
@staticmethod
|
||||
def from_bin(data: memoryview):
|
||||
return DmaEntry(*STRUCT_IIII.unpack_from(data))
|
||||
|
||||
|
||||
DMA_ENTRY_ZERO = DmaEntry(0, 0, 0, 0)
|
||||
|
||||
|
||||
def align(v: int):
|
||||
v += 0xF
|
||||
return v // 0x10 * 0x10
|
||||
|
||||
|
||||
@dataclasses.dataclass
|
||||
class RomSegment:
|
||||
vromStart: int
|
||||
vromEnd: int
|
||||
is_compressed: bool
|
||||
data: memoryview | None
|
||||
data_async: multiprocessing.pool.AsyncResult | None
|
||||
|
||||
@property
|
||||
def uncompressed_size(self):
|
||||
return self.vromEnd - self.vromStart
|
||||
|
||||
|
||||
# Make interrupting the compression with ^C less jank
|
||||
# https://stackoverflow.com/questions/72967793/keyboardinterrupt-with-python-multiprocessing-pool
|
||||
def set_sigint_ignored():
|
||||
import signal
|
||||
|
||||
signal.signal(signal.SIGINT, signal.SIG_IGN)
|
||||
|
||||
|
||||
def compress_rom(
|
||||
rom_data: memoryview,
|
||||
dmadata_offset_start: int,
|
||||
dmadata_offset_end: int,
|
||||
compress_entries_indices: set[int],
|
||||
n_threads: int = None,
|
||||
):
|
||||
"""
|
||||
rom_data: the uncompressed rom data
|
||||
dmadata_offset_start: the offset in the rom where the dmadata starts (inclusive)
|
||||
dmadata_offset_end: the offset in the rom where the dmadata ends (exclusive)
|
||||
compress_entries_indices: the indices in the dmadata of the segments that should be compressed
|
||||
n_threads: how many cores to use for compression
|
||||
"""
|
||||
|
||||
# Segments of the compressed rom (not all are compressed)
|
||||
compressed_rom_segments: list[RomSegment] = []
|
||||
|
||||
with multiprocessing.Pool(n_threads, initializer=set_sigint_ignored) as p:
|
||||
# Extract each segment from the input rom
|
||||
for entry_index, dmadata_offset in enumerate(
|
||||
range(dmadata_offset_start, dmadata_offset_end, DmaEntry.SIZE_BYTES)
|
||||
):
|
||||
dma_entry = DmaEntry.from_bin(rom_data[dmadata_offset:])
|
||||
if dma_entry == DMA_ENTRY_ZERO:
|
||||
continue
|
||||
|
||||
segment_rom_start = dma_entry.romStart
|
||||
segment_rom_end = dma_entry.romStart + (
|
||||
dma_entry.vromEnd - dma_entry.vromStart
|
||||
)
|
||||
segment_data_uncompressed = rom_data[segment_rom_start:segment_rom_end]
|
||||
|
||||
is_compressed = entry_index in compress_entries_indices
|
||||
|
||||
if is_compressed:
|
||||
segment_data = None
|
||||
segment_data_async = p.apply_async(
|
||||
crunch64.yaz0.compress,
|
||||
(bytes(segment_data_uncompressed),),
|
||||
)
|
||||
else:
|
||||
segment_data = segment_data_uncompressed
|
||||
segment_data_async = None
|
||||
|
||||
compressed_rom_segments.append(
|
||||
RomSegment(
|
||||
dma_entry.vromStart,
|
||||
dma_entry.vromEnd,
|
||||
is_compressed,
|
||||
segment_data,
|
||||
segment_data_async,
|
||||
)
|
||||
)
|
||||
|
||||
# Technically optional but required for matching.
|
||||
compressed_rom_segments.sort(key=lambda segment: segment.vromStart)
|
||||
|
||||
# Wait on compression of all compressed segments
|
||||
waiting_on_segments = [
|
||||
segment for segment in compressed_rom_segments if segment.is_compressed
|
||||
]
|
||||
total_uncompressed_size_of_data_to_compress = sum(
|
||||
segment.uncompressed_size for segment in waiting_on_segments
|
||||
)
|
||||
uncompressed_size_of_data_compressed_so_far = 0
|
||||
while waiting_on_segments:
|
||||
# Show progress
|
||||
progress = (
|
||||
uncompressed_size_of_data_compressed_so_far
|
||||
/ total_uncompressed_size_of_data_to_compress
|
||||
)
|
||||
print(f"Compressing... {progress * 100:.1f}%", end="\r")
|
||||
|
||||
# The segments for which the compression is not finished yet are
|
||||
# added to this list
|
||||
still_waiting_on_segments = []
|
||||
got_some_results = False
|
||||
for segment in waiting_on_segments:
|
||||
assert segment.data is None
|
||||
assert segment.data_async is not None
|
||||
|
||||
try:
|
||||
compressed_data = segment.data_async.get(0)
|
||||
except multiprocessing.TimeoutError:
|
||||
# Compression not finished yet
|
||||
still_waiting_on_segments.append(segment)
|
||||
else:
|
||||
# Compression finished!
|
||||
assert isinstance(compressed_data, bytes)
|
||||
segment.data = memoryview(compressed_data)
|
||||
uncompressed_size_of_data_compressed_so_far += (
|
||||
segment.uncompressed_size
|
||||
)
|
||||
got_some_results = True
|
||||
segment.data_async = None
|
||||
|
||||
if not got_some_results and still_waiting_on_segments:
|
||||
# Nothing happened this wait iteration, idle a bit
|
||||
time.sleep(0.010)
|
||||
|
||||
waiting_on_segments = still_waiting_on_segments
|
||||
|
||||
print("Putting together the compressed rom...")
|
||||
|
||||
# Put together the compressed rom
|
||||
compressed_rom_size = sum(
|
||||
align(len(segment.data)) for segment in compressed_rom_segments
|
||||
)
|
||||
pad_to_multiple_of = 8 * 2**20 # 8 MiB
|
||||
compressed_rom_size_padded = (
|
||||
(compressed_rom_size + pad_to_multiple_of - 1)
|
||||
// pad_to_multiple_of
|
||||
* pad_to_multiple_of
|
||||
)
|
||||
compressed_rom_data = memoryview(bytearray(compressed_rom_size_padded))
|
||||
compressed_rom_dma_entries: list[DmaEntry] = []
|
||||
rom_offset = 0
|
||||
for segment in compressed_rom_segments:
|
||||
assert segment.data is not None
|
||||
|
||||
segment_rom_start = rom_offset
|
||||
segment_rom_end = align(segment_rom_start + len(segment.data))
|
||||
|
||||
i = segment_rom_start + len(segment.data)
|
||||
assert i <= len(compressed_rom_data)
|
||||
compressed_rom_data[segment_rom_start:i] = segment.data
|
||||
|
||||
compressed_rom_dma_entries.append(
|
||||
DmaEntry(
|
||||
segment.vromStart,
|
||||
segment.vromEnd,
|
||||
segment_rom_start,
|
||||
segment_rom_end if segment.is_compressed else 0,
|
||||
)
|
||||
)
|
||||
|
||||
rom_offset = segment_rom_end
|
||||
|
||||
assert rom_offset == compressed_rom_size
|
||||
# Pad the compressed rom with the pattern matching the baseroms
|
||||
for i in range(compressed_rom_size, compressed_rom_size_padded):
|
||||
compressed_rom_data[i] = i % 256
|
||||
|
||||
# Write the new dmadata
|
||||
dmadata_offset = dmadata_offset_start
|
||||
for dma_entry in compressed_rom_dma_entries:
|
||||
assert dmadata_offset + DmaEntry.SIZE_BYTES <= dmadata_offset_end
|
||||
|
||||
dma_entry.to_bin(compressed_rom_data[dmadata_offset:])
|
||||
|
||||
dmadata_offset += DmaEntry.SIZE_BYTES
|
||||
|
||||
return compressed_rom_data
|
||||
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument(
|
||||
"--in",
|
||||
dest="in_rom",
|
||||
required=True,
|
||||
help="path to an uncompressed rom to be compressed",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--out",
|
||||
dest="out_rom",
|
||||
required=True,
|
||||
help="path of the compressed rom to write out",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--dma-range",
|
||||
dest="dma_range",
|
||||
required=True,
|
||||
help=(
|
||||
"The dmadata location in the rom, in format"
|
||||
" 'start_inclusive-end_exclusive' and using hexadecimal offsets"
|
||||
" (e.g. '0x12f70-0x19030')."
|
||||
),
|
||||
)
|
||||
parser.add_argument(
|
||||
"--compress",
|
||||
dest="compress_ranges",
|
||||
required=True,
|
||||
help=(
|
||||
"The indices in the dmadata of the entries to be compressed,"
|
||||
" where 0 is the first entry."
|
||||
" It is a comma-separated list of individual indices and inclusive ranges."
|
||||
" e.g. '0-1,3,5,6-9' is all indices from 0 to 9 (included) except 2 and 4."
|
||||
),
|
||||
)
|
||||
parser.add_argument(
|
||||
"--threads",
|
||||
dest="n_threads",
|
||||
type=int,
|
||||
default=1,
|
||||
help="how many cores to use for parallel compression",
|
||||
)
|
||||
args = parser.parse_args()
|
||||
|
||||
in_rom_p = Path(args.in_rom)
|
||||
if not in_rom_p.exists():
|
||||
parser.error(f"Input rom file {in_rom_p} doesn't exist.")
|
||||
|
||||
out_rom_p = Path(args.out_rom)
|
||||
|
||||
dma_range_str: str = args.dma_range
|
||||
dma_range_ends_str = dma_range_str.split("-")
|
||||
assert len(dma_range_ends_str) == 2, dma_range_str
|
||||
dmadata_offset_start, dmadata_offset_end = (
|
||||
int(v_str, 16) for v_str in dma_range_ends_str
|
||||
)
|
||||
assert dmadata_offset_start < dmadata_offset_end, dma_range_str
|
||||
|
||||
compress_ranges_str: str = args.compress_ranges
|
||||
compress_entries_indices = set()
|
||||
for compress_range_str in compress_ranges_str.split(","):
|
||||
compress_range_ends_str = compress_range_str.split("-")
|
||||
assert len(compress_range_ends_str) <= 2, (
|
||||
compress_range_ends_str,
|
||||
compress_range_str,
|
||||
compress_ranges_str,
|
||||
)
|
||||
compress_range_ends = [int(v_str) for v_str in compress_range_ends_str]
|
||||
if len(compress_range_ends) == 1:
|
||||
compress_entries_indices.add(compress_range_ends[0])
|
||||
else:
|
||||
assert len(compress_range_ends) == 2
|
||||
compress_range_first, compress_range_last = compress_range_ends
|
||||
compress_entries_indices.update(
|
||||
range(compress_range_first, compress_range_last + 1)
|
||||
)
|
||||
|
||||
n_threads = args.n_threads
|
||||
|
||||
in_rom_data = in_rom_p.read_bytes()
|
||||
out_rom_data = compress_rom(
|
||||
memoryview(in_rom_data),
|
||||
dmadata_offset_start,
|
||||
dmadata_offset_end,
|
||||
compress_entries_indices,
|
||||
n_threads,
|
||||
)
|
||||
out_rom_p.write_bytes(out_rom_data)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
|
@ -496,7 +496,7 @@ def main():
|
|||
|
||||
script_dir = os.path.dirname(os.path.realpath(__file__))
|
||||
cs_data = None
|
||||
with open(script_dir + "/../baserom/" + file_result.name, "rb") as ovl_file:
|
||||
with open(script_dir + "/../baseroms/gc-eu-mq-dbg/segments/" + file_result.name, "rb") as ovl_file:
|
||||
ovl_file.seek(file_result.offset)
|
||||
cs_data = [i[0] for i in struct.iter_unpack(">I", bytearray(ovl_file.read()))]
|
||||
if cs_data is not None:
|
||||
|
|
273
tools/decompress_baserom.py
Executable file
273
tools/decompress_baserom.py
Executable file
|
@ -0,0 +1,273 @@
|
|||
#!/usr/bin/env python3
|
||||
|
||||
# SPDX-FileCopyrightText: © 2024 ZeldaRET
|
||||
# SPDX-License-Identifier: CC0-1.0
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import hashlib
|
||||
import io
|
||||
import struct
|
||||
from pathlib import Path
|
||||
import argparse
|
||||
|
||||
import crunch64
|
||||
import ipl3checksum
|
||||
import zlib
|
||||
|
||||
|
||||
def decompress_zlib(data: bytes) -> bytes:
|
||||
decomp = zlib.decompressobj(-zlib.MAX_WBITS)
|
||||
output = bytearray()
|
||||
output.extend(decomp.decompress(data))
|
||||
while decomp.unconsumed_tail:
|
||||
output.extend(decomp.decompress(decomp.unconsumed_tail))
|
||||
output.extend(decomp.flush())
|
||||
return bytes(output)
|
||||
|
||||
|
||||
def decompress(data: bytes, is_zlib_compressed: bool) -> bytes:
|
||||
if is_zlib_compressed:
|
||||
return decompress_zlib(data)
|
||||
return crunch64.yaz0.decompress(data)
|
||||
|
||||
|
||||
FILE_TABLE_OFFSET = {
|
||||
"gc-eu-mq-dbg": 0x12F70,
|
||||
}
|
||||
|
||||
VERSIONS_MD5S = {
|
||||
"gc-eu-mq-dbg": "f0b7f35375f9cc8ca1b2d59d78e35405",
|
||||
}
|
||||
|
||||
|
||||
def round_up(n, shift):
|
||||
mod = 1 << shift
|
||||
return (n + mod - 1) >> shift << shift
|
||||
|
||||
|
||||
def as_word_list(b) -> list[int]:
|
||||
return [i[0] for i in struct.iter_unpack(">I", b)]
|
||||
|
||||
|
||||
def read_dmadata_entry(file_content: bytearray, addr: int) -> list[int]:
|
||||
return as_word_list(file_content[addr : addr + 0x10])
|
||||
|
||||
|
||||
def read_dmadata(file_content: bytearray, start) -> list[list[int]]:
|
||||
dmadata = []
|
||||
addr = start
|
||||
entry = read_dmadata_entry(file_content, addr)
|
||||
i = 0
|
||||
while any([e != 0 for e in entry]):
|
||||
dmadata.append(entry)
|
||||
addr += 0x10
|
||||
i += 1
|
||||
entry = read_dmadata_entry(file_content, addr)
|
||||
return dmadata
|
||||
|
||||
|
||||
def update_crc(decompressed: io.BytesIO) -> io.BytesIO:
|
||||
print("Recalculating crc...")
|
||||
calculated_checksum = ipl3checksum.CICKind.CIC_X105.calculateChecksum(
|
||||
bytes(decompressed.getbuffer())
|
||||
)
|
||||
new_crc = struct.pack(f">II", calculated_checksum[0], calculated_checksum[1])
|
||||
|
||||
decompressed.seek(0x10)
|
||||
decompressed.write(new_crc)
|
||||
return decompressed
|
||||
|
||||
|
||||
def decompress_rom(
|
||||
file_content: bytearray, dmadata_addr: int, dmadata: list[list[int]], version: str
|
||||
) -> bytearray:
|
||||
rom_segments = {} # vrom start : data s.t. len(data) == vrom_end - vrom_start
|
||||
new_dmadata = bytearray() # new dmadata: {vrom start , vrom end , vrom start , 0}
|
||||
|
||||
decompressed = io.BytesIO(b"")
|
||||
|
||||
for v_start, v_end, p_start, p_end in dmadata:
|
||||
if p_start == 0xFFFFFFFF and p_end == 0xFFFFFFFF:
|
||||
new_dmadata.extend(struct.pack(">IIII", v_start, v_end, p_start, p_end))
|
||||
continue
|
||||
if p_end == 0: # uncompressed
|
||||
rom_segments.update(
|
||||
{v_start: file_content[p_start : p_start + v_end - v_start]}
|
||||
)
|
||||
else: # compressed
|
||||
rom_segments.update(
|
||||
{
|
||||
v_start: decompress(
|
||||
file_content[p_start:p_end], version in {"ique-cn", "ique-zh"}
|
||||
)
|
||||
}
|
||||
)
|
||||
new_dmadata.extend(struct.pack(">IIII", v_start, v_end, v_start, 0))
|
||||
|
||||
# write rom segments to vaddrs
|
||||
for vrom_st, data in rom_segments.items():
|
||||
decompressed.seek(vrom_st)
|
||||
decompressed.write(data)
|
||||
# write new dmadata
|
||||
decompressed.seek(dmadata_addr)
|
||||
decompressed.write(new_dmadata)
|
||||
# pad to size
|
||||
padding_end = round_up(dmadata[-1][1], 14)
|
||||
decompressed.seek(padding_end - 1)
|
||||
decompressed.write(bytearray([0]))
|
||||
# re-calculate crc
|
||||
return bytearray(update_crc(decompressed).getbuffer())
|
||||
|
||||
|
||||
def get_str_hash(byte_array):
|
||||
return str(hashlib.md5(byte_array).hexdigest())
|
||||
|
||||
|
||||
def check_existing_rom(rom_path: Path, correct_str_hash: str):
|
||||
# If the baserom exists and is correct, we don't need to change anything
|
||||
if rom_path.exists():
|
||||
if get_str_hash(rom_path.read_bytes()) == correct_str_hash:
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
def word_swap(file_content: bytearray) -> bytearray:
|
||||
words = str(int(len(file_content) / 4))
|
||||
little_byte_format = "<" + words + "I"
|
||||
big_byte_format = ">" + words + "I"
|
||||
tmp = struct.unpack_from(little_byte_format, file_content, 0)
|
||||
struct.pack_into(big_byte_format, file_content, 0, *tmp)
|
||||
return file_content
|
||||
|
||||
|
||||
def byte_swap(file_content: bytearray) -> bytearray:
|
||||
halfwords = str(int(len(file_content) / 2))
|
||||
little_byte_format = "<" + halfwords + "H"
|
||||
big_byte_format = ">" + halfwords + "H"
|
||||
tmp = struct.unpack_from(little_byte_format, file_content, 0)
|
||||
struct.pack_into(big_byte_format, file_content, 0, *tmp)
|
||||
return file_content
|
||||
|
||||
|
||||
def per_version_fixes(file_content: bytearray, version: str) -> bytearray:
|
||||
if version == "gc-eu-mq-dbg":
|
||||
# Strip the overdump
|
||||
print("Stripping overdump...")
|
||||
file_content = file_content[0:0x3600000]
|
||||
|
||||
# Patch the header
|
||||
print("Patching header...")
|
||||
file_content[0x3E] = 0x50
|
||||
return file_content
|
||||
|
||||
|
||||
def pad_rom(file_content: bytearray, dmadata: list[list[int]]) -> bytearray:
|
||||
padding_start = round_up(dmadata[-1][1], 12)
|
||||
padding_end = round_up(dmadata[-1][1], 14)
|
||||
print(f"Padding from {padding_start:X} to {padding_end:X}...")
|
||||
for i in range(padding_start, padding_end):
|
||||
file_content[i] = 0xFF
|
||||
return file_content
|
||||
|
||||
# Determine if we have a ROM file
|
||||
ROM_FILE_EXTENSIONS = ["z64", "n64", "v64"]
|
||||
|
||||
def find_baserom(version: str) -> Path | None:
|
||||
for rom_file_ext_lower in ROM_FILE_EXTENSIONS:
|
||||
for rom_file_ext in (rom_file_ext_lower, rom_file_ext_lower.upper()):
|
||||
rom_file_name_candidate = Path(f"baseroms/{version}/baserom.{rom_file_ext}")
|
||||
if rom_file_name_candidate.exists():
|
||||
return rom_file_name_candidate
|
||||
return None
|
||||
|
||||
|
||||
def main():
|
||||
description = "Convert a rom that uses dmadata to an uncompressed one."
|
||||
|
||||
parser = argparse.ArgumentParser(description=description)
|
||||
parser.add_argument("version", help="Version of the game to decompress.", choices=list(VERSIONS_MD5S.keys()))
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
version = args.version
|
||||
|
||||
uncompressed_path = Path(f"baseroms/{version}/baserom-decompressed.z64")
|
||||
|
||||
file_table_offset = FILE_TABLE_OFFSET[version]
|
||||
correct_str_hash = VERSIONS_MD5S[version]
|
||||
|
||||
if check_existing_rom(uncompressed_path, correct_str_hash):
|
||||
print("Found valid baserom - exiting early")
|
||||
return
|
||||
|
||||
rom_file_name = find_baserom(version)
|
||||
|
||||
if rom_file_name is None:
|
||||
path_list = [
|
||||
f"baseroms/{version}/baserom.{rom_file_ext}" for rom_file_ext in ROM_FILE_EXTENSIONS
|
||||
]
|
||||
print(f"Error: Could not find {','.join(path_list)}.")
|
||||
exit(1)
|
||||
|
||||
# Read in the original ROM
|
||||
print(f"File '{rom_file_name}' found.")
|
||||
|
||||
file_content = bytearray(rom_file_name.read_bytes())
|
||||
|
||||
# Check if ROM needs to be byte/word swapped
|
||||
# Little-endian
|
||||
if file_content[0] == 0x40:
|
||||
# Word Swap ROM
|
||||
print("ROM needs to be word swapped...")
|
||||
file_content = word_swap(file_content)
|
||||
print("Word swapping done.")
|
||||
|
||||
# Byte-swapped
|
||||
elif file_content[0] == 0x37:
|
||||
# Byte Swap ROM
|
||||
print("ROM needs to be byte swapped...")
|
||||
file_content = byte_swap(file_content)
|
||||
print("Byte swapping done.")
|
||||
|
||||
file_content = per_version_fixes(file_content, version)
|
||||
|
||||
dmadata = read_dmadata(file_content, file_table_offset)
|
||||
# Decompress
|
||||
if any(
|
||||
[
|
||||
b != 0
|
||||
for b in file_content[
|
||||
file_table_offset + 0xAC : file_table_offset + 0xAC + 0x4
|
||||
]
|
||||
]
|
||||
):
|
||||
print("Decompressing rom...")
|
||||
file_content = decompress_rom(file_content, file_table_offset, dmadata, version)
|
||||
|
||||
file_content = pad_rom(file_content, dmadata)
|
||||
|
||||
# Check to see if the ROM is a "vanilla" ROM
|
||||
str_hash = get_str_hash(file_content)
|
||||
if str_hash != correct_str_hash:
|
||||
print(
|
||||
f"Error: Expected a hash of {correct_str_hash} but got {str_hash}. The baserom has probably been tampered, find a new one"
|
||||
)
|
||||
|
||||
if version == "gc-eu-mq-dbg":
|
||||
if str_hash == "32fe2770c0f9b1a9cd2a4d449348c1cb":
|
||||
print(
|
||||
"The provided baserom is a rom which has been edited with ZeldaEdit and is not suitable for use with decomp. Find a new one."
|
||||
)
|
||||
|
||||
exit(1)
|
||||
|
||||
# Write out our new ROM
|
||||
print(f"Writing new ROM {uncompressed_path}.")
|
||||
uncompressed_path.write_bytes(file_content)
|
||||
|
||||
print("Done!")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
|
@ -166,7 +166,7 @@ item_ids = {
|
|||
|
||||
def disas_elfmsgs(start):
|
||||
baserom = None
|
||||
with open("baserom.z64", "rb") as infile:
|
||||
with open("baseroms/gc-eu-mq-dbg/baserom-decompressed.z64", "rb") as infile:
|
||||
baserom = bytearray(infile.read())
|
||||
|
||||
branches = []
|
||||
|
|
16
tools/dmadata_range.sh
Executable file
16
tools/dmadata_range.sh
Executable file
|
@ -0,0 +1,16 @@
|
|||
#!/bin/sh
|
||||
|
||||
NM=$1
|
||||
ELF=$2
|
||||
|
||||
# dmadata_syms contents look like:
|
||||
# ffffffff80015850 T _dmadataSegmentTextStart
|
||||
# 00000000 A _dmadataSegmentTextSize
|
||||
# 00011a40 A _dmadataSegmentRomStart
|
||||
# ffffffff8001b920 T _dmadataSegmentRoDataEnd
|
||||
dmadata_syms=`$NM $ELF --no-sort --radix=x --format=bsd | grep dmadata`
|
||||
|
||||
_dmadataSegmentRomStart=`echo "$dmadata_syms" | grep '\b_dmadataSegmentRomStart\b' | cut -d' ' -f1`
|
||||
_dmadataSegmentRomEnd=` echo "$dmadata_syms" | grep '\b_dmadataSegmentRomEnd\b' | cut -d' ' -f1`
|
||||
|
||||
echo 0x"$_dmadataSegmentRomStart"-0x"$_dmadataSegmentRomEnd"
|
|
@ -20,22 +20,53 @@ static void write_dmadata_table(FILE *fout)
|
|||
fprintf(fout, "DEFINE_DMA_ENTRY(%s, \"%s\")\n", g_segments[i].name, g_segments[i].name);
|
||||
}
|
||||
|
||||
static void write_compress_ranges(FILE *fout)
|
||||
{
|
||||
int i;
|
||||
bool continue_list = false;
|
||||
int stride_first = -1;
|
||||
|
||||
for (i = 0; i < g_segmentsCount; i++) {
|
||||
if (g_segments[i].compress) {
|
||||
if (stride_first == -1)
|
||||
stride_first = i;
|
||||
}
|
||||
if (!g_segments[i].compress || i == g_segmentsCount - 1) {
|
||||
if (stride_first != -1) {
|
||||
int stride_last = i - 1;
|
||||
if (continue_list) {
|
||||
fprintf(fout, ",");
|
||||
}
|
||||
if (stride_first == stride_last) {
|
||||
fprintf(fout, "%d", stride_first);
|
||||
} else {
|
||||
fprintf(fout, "%d-%d", stride_first, stride_last);
|
||||
}
|
||||
continue_list = true;
|
||||
stride_first = -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void usage(const char *execname)
|
||||
{
|
||||
fprintf(stderr, "zelda64 dmadata generation tool v0.01\n"
|
||||
"usage: %s SPEC_FILE DMADATA_TABLE\n"
|
||||
"usage: %s SPEC_FILE DMADATA_TABLE COMPRESS_RANGES\n"
|
||||
"SPEC_FILE file describing the organization of object files into segments\n"
|
||||
"DMADATA_TABLE filename of output dmadata table header\n",
|
||||
"DMADATA_TABLE filename of output dmadata table header\n"
|
||||
"COMPRESS_RANGES filename to write which files are compressed (e.g. 0-5,7,10-20)\n",
|
||||
execname);
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
FILE *dmaout;
|
||||
FILE *compress_ranges_out;
|
||||
void *spec;
|
||||
size_t size;
|
||||
|
||||
if (argc != 3)
|
||||
if (argc != 4)
|
||||
{
|
||||
usage(argv[0]);
|
||||
return 1;
|
||||
|
@ -49,6 +80,13 @@ int main(int argc, char **argv)
|
|||
util_fatal_error("failed to open file '%s' for writing", argv[2]);
|
||||
write_dmadata_table(dmaout);
|
||||
fclose(dmaout);
|
||||
|
||||
compress_ranges_out = fopen(argv[3], "w");
|
||||
if (compress_ranges_out == NULL)
|
||||
util_fatal_error("failed to open file '%s' for writing", argv[3]);
|
||||
write_compress_ranges(compress_ranges_out);
|
||||
fclose(compress_ranges_out);
|
||||
|
||||
free_rom_spec(g_segments, g_segmentsCount);
|
||||
free(spec);
|
||||
|
||||
|
|
|
@ -282,7 +282,7 @@ def read_tables():
|
|||
global staff_message_entry_table
|
||||
|
||||
baserom = None
|
||||
with open("baserom.z64","rb") as infile:
|
||||
with open("baseroms/gc-eu-mq-dbg/baserom-decompressed.z64","rb") as infile:
|
||||
baserom = infile.read()
|
||||
|
||||
nes_message_entry_table = as_message_table_entry(baserom[nes_message_entry_table_addr:ger_message_entry_table_addr])
|
||||
|
@ -326,7 +326,7 @@ def dump_all_text():
|
|||
nes_offset = segmented_to_physical(entry[3])
|
||||
nes_length = next_entry[3] - entry[3]
|
||||
nes_text = ""
|
||||
with open("baserom/nes_message_data_static","rb") as infile:
|
||||
with open("baseroms/gc-eu-mq-dbg/segments/nes_message_data_static","rb") as infile:
|
||||
infile.seek(nes_offset)
|
||||
nes_text = fixup_message(decode(infile.read(nes_length), entry[1]).replace("\x00","",-1))
|
||||
|
||||
|
@ -337,13 +337,13 @@ def dump_all_text():
|
|||
next_entry = combined_message_entry_table[i+2]
|
||||
ger_offset = segmented_to_physical(entry[4])
|
||||
ger_length = next_entry[4] - entry[4]
|
||||
with open("baserom/ger_message_data_static","rb") as infile:
|
||||
with open("baseroms/gc-eu-mq-dbg/segments/ger_message_data_static","rb") as infile:
|
||||
infile.seek(ger_offset)
|
||||
ger_text = fixup_message(decode(infile.read(ger_length), entry[1]).replace("\x00","",-1))
|
||||
|
||||
fra_offset = segmented_to_physical(entry[5])
|
||||
fra_length = next_entry[5] - entry[5]
|
||||
with open("baserom/fra_message_data_static","rb") as infile:
|
||||
with open("baseroms/gc-eu-mq-dbg/segments/fra_message_data_static","rb") as infile:
|
||||
infile.seek(fra_offset)
|
||||
fra_text = fixup_message(decode(infile.read(fra_length), entry[1]).replace("\x00","",-1))
|
||||
|
||||
|
@ -352,7 +352,7 @@ def dump_all_text():
|
|||
return messages
|
||||
|
||||
def dump_staff_text():
|
||||
staff_message_data_static_size = path.getsize("baserom/staff_message_data_static")
|
||||
staff_message_data_static_size = path.getsize("baseroms/gc-eu-mq-dbg/segments/staff_message_data_static")
|
||||
# text id, ypos, type, staff
|
||||
messages = []
|
||||
for i,entry in enumerate(staff_message_entry_table,0):
|
||||
|
@ -361,7 +361,7 @@ def dump_staff_text():
|
|||
staff_offset = segmented_to_physical(entry[3])
|
||||
# hacky way to ensure the staff message entry table is read all the way to the end
|
||||
staff_length = (staff_message_data_static_size if entry[0] == 0x052F else segmented_to_physical(next_entry[3])) - segmented_to_physical(entry[3])
|
||||
with open("baserom/staff_message_data_static","rb") as infile:
|
||||
with open("baseroms/gc-eu-mq-dbg/segments/staff_message_data_static","rb") as infile:
|
||||
infile.seek(staff_offset)
|
||||
messages.append((entry[0], entry[1], entry[2], fixup_message(decode(infile.read(staff_length), entry[1]).replace("\x00","",-1))))
|
||||
else:
|
||||
|
|
|
@ -387,7 +387,7 @@ def GetColliderInit(address, type, num, path):
|
|||
else:
|
||||
return("ItemInit type must specify number of elements")
|
||||
|
||||
ovlFile = open(path + "/baserom/" + fileResult.name, "rb")
|
||||
ovlFile = open(path + "/baseroms/gc-eu-mq-dbg/segments/" + fileResult.name, "rb")
|
||||
ovlData = bytearray(ovlFile.read())
|
||||
ovlFile.close()
|
||||
|
||||
|
@ -470,7 +470,7 @@ print(GetColliderInitFull(args.address, args.type, args.num, repo))
|
|||
|
||||
# script_dir = os.path.dirname(os.path.realpath(__file__))
|
||||
|
||||
# ovlFile = open(script_dir + "/../../baserom/" + fileResult.name, "rb")
|
||||
# ovlFile = open(script_dir + "/../../baseroms/" + fileResult.name, "rb")
|
||||
# ovlData = bytearray(ovlFile.read())
|
||||
# ovlFile.close()
|
||||
|
||||
|
|
|
@ -132,7 +132,7 @@ def get_damage_bytes(address, repo):
|
|||
|
||||
print(file_result)
|
||||
|
||||
with open(repo + os.sep + "baserom" + os.sep + file_result.name, "rb") as ovl_file:
|
||||
with open(repo + os.sep + "baseroms/gc-eu-mq-dbg/segments" + os.sep + file_result.name, "rb") as ovl_file:
|
||||
ovl_data = bytearray(ovl_file.read())
|
||||
|
||||
damage_data = ovl_data[file_result.offset:file_result.offset+0x20]
|
||||
|
|
|
@ -72,7 +72,7 @@ repo = scriptDir + os.sep + ".." + os.sep + ".."
|
|||
|
||||
|
||||
kaleido_scope_data = []
|
||||
with open(repo + "/baserom/ovl_kaleido_scope", "rb") as file:
|
||||
with open(repo + "/baseroms/gc-eu-mq-dbg/segments/ovl_kaleido_scope", "rb") as file:
|
||||
kaleido_scope_data = bytearray(file.read())
|
||||
|
||||
scenemaps = []
|
||||
|
|
|
@ -97,7 +97,7 @@ repo = scriptDir + os.sep + ".." + os.sep + ".."
|
|||
|
||||
|
||||
map_mark_data = []
|
||||
with open(repo + "/baserom/ovl_map_mark_data", "rb") as file:
|
||||
with open(repo + "/baseroms/gc-eu-mq-dbg/segments/ovl_map_mark_data", "rb") as file:
|
||||
map_mark_data = bytearray(file.read())
|
||||
|
||||
scenemaps = []
|
||||
|
|
|
@ -127,6 +127,7 @@ static const char *const stmtNames[] =
|
|||
[STMT_after] = "after",
|
||||
[STMT_align] = "align",
|
||||
[STMT_beginseg] = "beginseg",
|
||||
[STMT_compress] = "compress",
|
||||
[STMT_endseg] = "endseg",
|
||||
[STMT_entry] = "entry",
|
||||
[STMT_flags] = "flags",
|
||||
|
@ -216,10 +217,13 @@ bool parse_segment_statement(struct Segment *currSeg, STMTId stmt, char* args, i
|
|||
currSeg->includes[currSeg->includesCount - 1].linkerPadding = 0;
|
||||
currSeg->includes[currSeg->includesCount - 1].dataWithRodata = (stmt == STMT_include_data_with_rodata);
|
||||
break;
|
||||
case STMT_increment:
|
||||
case STMT_increment:
|
||||
if (!parse_number(args, &currSeg->increment))
|
||||
util_fatal_error("line %i: expected number after 'increment'", lineNum);
|
||||
break;
|
||||
case STMT_compress:
|
||||
currSeg->compress = true;
|
||||
break;
|
||||
case STMT_pad_text:
|
||||
currSeg->includes[currSeg->includesCount - 1].linkerPadding += 0x10;
|
||||
break;
|
||||
|
|
|
@ -9,6 +9,7 @@ typedef enum {
|
|||
STMT_after,
|
||||
STMT_align,
|
||||
STMT_beginseg,
|
||||
STMT_compress,
|
||||
STMT_endseg,
|
||||
STMT_entry,
|
||||
STMT_flags,
|
||||
|
@ -48,6 +49,7 @@ typedef struct Segment {
|
|||
uint32_t number;
|
||||
struct Include* includes;
|
||||
int includesCount;
|
||||
bool compress;
|
||||
} Segment;
|
||||
|
||||
void parse_rom_spec(char* spec, struct Segment** segments, int* segment_count);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue