diff --git a/Makefile b/Makefile
index d61da33ca..885fad63d 100644
--- a/Makefile
+++ b/Makefile
@@ -383,7 +383,8 @@ CPP := gcc -E
MKLDSCRIPT := tools/mkldscript
MKDMADATA := tools/mkdmadata
ELF2ROM := tools/elf2rom
-ZAPD := tools/ZAPD/ZAPD.out
+BIN2C := tools/bin2c
+N64TEXCONV := tools/assets/n64texconv/n64texconv
FADO := tools/fado/fado.elf
PYTHON ?= $(VENV)/bin/python3
FLIPS := tools/Flips/flips
@@ -950,22 +951,22 @@ $(BUILD_DIR)/src/overlays/%_reloc.o: $(BUILD_DIR)/spec
$(V)$(AS) $(ASFLAGS) $(@:.o=.s) -o $@
$(BUILD_DIR)/assets/%.inc.c: assets/%.png
- $(V)$(ZAPD) btex -eh -tt $(subst .,,$(suffix $*)) -i $< -o $@
+ $(V)$(N64TEXCONV) $(subst .,,$(suffix $*)) "$(findstring u32,$(subst .,,$(suffix $(basename $*))))" $< $@ $(@:.inc.c=.pal.inc.c)
$(BUILD_DIR)/assets/%.inc.c: $(EXTRACTED_DIR)/assets/%.png
- $(V)$(ZAPD) btex -eh -tt $(subst .,,$(suffix $*)) -i $< -o $@
+ $(V)$(N64TEXCONV) $(subst .,,$(suffix $*)) "$(findstring u32,$(subst .,,$(suffix $(basename $*))))" $< $@ $(@:.inc.c=.pal.inc.c)
$(BUILD_DIR)/assets/%.bin.inc.c: assets/%.bin
- $(V)$(ZAPD) bblb -eh -i $< -o $@
+ $(V)$(BIN2C) -t 1 $< $@
$(BUILD_DIR)/assets/%.bin.inc.c: $(EXTRACTED_DIR)/assets/%.bin
- $(V)$(ZAPD) bblb -eh -i $< -o $@
+ $(V)$(BIN2C) -t 1 $< $@
$(BUILD_DIR)/assets/%.jpg.inc.c: assets/%.jpg
- $(V)$(ZAPD) bren -eh -i $< -o $@
+ $(V)$(N64TEXCONV) JFIF "" $< $@
$(BUILD_DIR)/assets/%.jpg.inc.c: $(EXTRACTED_DIR)/assets/%.jpg
- $(V)$(ZAPD) bren -eh -i $< -o $@
+ $(V)$(N64TEXCONV) JFIF "" $< $@
F3DEX3/f3dzex2.code:
$(V)$(PYTHON) tools/data_extractor.py --start 0xBCD0F0 --size 0x1630 --input $(BASEROM_DIR)/baserom-decompressed.z64 --output $@
diff --git a/assets/xml/objects/gameplay_field_keep.xml b/assets/xml/objects/gameplay_field_keep.xml
index 011e8f7fc..3c0f18d74 100644
--- a/assets/xml/objects/gameplay_field_keep.xml
+++ b/assets/xml/objects/gameplay_field_keep.xml
@@ -29,7 +29,7 @@
-
+
diff --git a/assets/xml/objects/gameplay_keep.xml b/assets/xml/objects/gameplay_keep.xml
index dcb7e2960..008497601 100644
--- a/assets/xml/objects/gameplay_keep.xml
+++ b/assets/xml/objects/gameplay_keep.xml
@@ -759,7 +759,7 @@
-
+
@@ -848,7 +848,7 @@
-
+
diff --git a/assets/xml/objects/gameplay_keep_pal.xml b/assets/xml/objects/gameplay_keep_pal.xml
index fbea0efd0..c7485d73f 100644
--- a/assets/xml/objects/gameplay_keep_pal.xml
+++ b/assets/xml/objects/gameplay_keep_pal.xml
@@ -753,7 +753,7 @@
-
+
@@ -843,7 +843,7 @@
-
+
diff --git a/assets/xml/objects/object_am.xml b/assets/xml/objects/object_am.xml
index 0a4b88ddf..2467baf6a 100644
--- a/assets/xml/objects/object_am.xml
+++ b/assets/xml/objects/object_am.xml
@@ -5,5 +5,6 @@
+
diff --git a/assets/xml/objects/object_ani.xml b/assets/xml/objects/object_ani.xml
index 25ad7af35..d83aa7656 100644
--- a/assets/xml/objects/object_ani.xml
+++ b/assets/xml/objects/object_ani.xml
@@ -51,6 +51,8 @@
+
+
diff --git a/assets/xml/objects/object_box.xml b/assets/xml/objects/object_box.xml
index 34162fc94..7ab9d9e7f 100644
--- a/assets/xml/objects/object_box.xml
+++ b/assets/xml/objects/object_box.xml
@@ -5,7 +5,9 @@
+
+
@@ -19,11 +21,7 @@
-
+
-
-
-
-
diff --git a/assets/xml/objects/object_bv.xml b/assets/xml/objects/object_bv.xml
index e2c2ce920..5a8e6c594 100644
--- a/assets/xml/objects/object_bv.xml
+++ b/assets/xml/objects/object_bv.xml
@@ -7,7 +7,7 @@
-
+
diff --git a/assets/xml/objects/object_bv_pal.xml b/assets/xml/objects/object_bv_pal.xml
index 204273fc0..8de749266 100644
--- a/assets/xml/objects/object_bv_pal.xml
+++ b/assets/xml/objects/object_bv_pal.xml
@@ -7,7 +7,7 @@
-
+
diff --git a/assets/xml/objects/object_door_killer.xml b/assets/xml/objects/object_door_killer.xml
index a37f590d6..fbee0e5f7 100644
--- a/assets/xml/objects/object_door_killer.xml
+++ b/assets/xml/objects/object_door_killer.xml
@@ -12,6 +12,6 @@
-
+
diff --git a/assets/xml/objects/object_fd.xml b/assets/xml/objects/object_fd.xml
index a28919d8e..4a5ce9faf 100644
--- a/assets/xml/objects/object_fd.xml
+++ b/assets/xml/objects/object_fd.xml
@@ -19,9 +19,10 @@
-
-
-
+
+
+
+
diff --git a/assets/xml/objects/object_fd2.xml b/assets/xml/objects/object_fd2.xml
index b3fbdcb21..8d2b3dcdb 100644
--- a/assets/xml/objects/object_fd2.xml
+++ b/assets/xml/objects/object_fd2.xml
@@ -21,9 +21,10 @@
-
-
-
+
+
+
+
diff --git a/assets/xml/objects/object_fd_pal.xml b/assets/xml/objects/object_fd_pal.xml
index 776a2ee49..be375399f 100644
--- a/assets/xml/objects/object_fd_pal.xml
+++ b/assets/xml/objects/object_fd_pal.xml
@@ -19,9 +19,10 @@
-
-
-
+
+
+
+
diff --git a/assets/xml/objects/object_gi_medal.xml b/assets/xml/objects/object_gi_medal.xml
index 28e5b1e68..d2cb6191d 100644
--- a/assets/xml/objects/object_gi_medal.xml
+++ b/assets/xml/objects/object_gi_medal.xml
@@ -2,10 +2,25 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/assets/xml/objects/object_gnd.xml b/assets/xml/objects/object_gnd.xml
index 53d2bbde4..d073b8b97 100644
--- a/assets/xml/objects/object_gnd.xml
+++ b/assets/xml/objects/object_gnd.xml
@@ -44,11 +44,11 @@
-
-
-
-
-
+
+
+
+
+
diff --git a/assets/xml/objects/object_hintnuts.xml b/assets/xml/objects/object_hintnuts.xml
index f7da2e8f5..d3595d85e 100644
--- a/assets/xml/objects/object_hintnuts.xml
+++ b/assets/xml/objects/object_hintnuts.xml
@@ -1,7 +1,7 @@
-
+
diff --git a/assets/xml/objects/object_hni.xml b/assets/xml/objects/object_hni.xml
index 6b317eb7a..763f6892c 100644
--- a/assets/xml/objects/object_hni.xml
+++ b/assets/xml/objects/object_hni.xml
@@ -16,7 +16,7 @@
-
+
diff --git a/assets/xml/objects/object_ik.xml b/assets/xml/objects/object_ik.xml
index 5d86e1075..50f47e9d7 100644
--- a/assets/xml/objects/object_ik.xml
+++ b/assets/xml/objects/object_ik.xml
@@ -1,8 +1,8 @@
-
-
-
+
+
+
@@ -29,7 +29,10 @@
+
+
+
diff --git a/assets/xml/objects/object_jya_obj.xml b/assets/xml/objects/object_jya_obj.xml
index fc3d53ccd..50c2700db 100644
--- a/assets/xml/objects/object_jya_obj.xml
+++ b/assets/xml/objects/object_jya_obj.xml
@@ -29,7 +29,7 @@
-
+
diff --git a/assets/xml/objects/object_kingdodongo.xml b/assets/xml/objects/object_kingdodongo.xml
index 32c28766b..3ada2822c 100644
--- a/assets/xml/objects/object_kingdodongo.xml
+++ b/assets/xml/objects/object_kingdodongo.xml
@@ -101,7 +101,15 @@
-
+
+
+
+
+
+
+
+
+
diff --git a/assets/xml/objects/object_kingdodongo_pal.xml b/assets/xml/objects/object_kingdodongo_pal.xml
index 1aa1735cb..a0790a6db 100644
--- a/assets/xml/objects/object_kingdodongo_pal.xml
+++ b/assets/xml/objects/object_kingdodongo_pal.xml
@@ -101,7 +101,15 @@
-
+
+
+
+
+
+
+
+
+
diff --git a/assets/xml/objects/object_lightbox.xml b/assets/xml/objects/object_lightbox.xml
index 552a79d7c..c67059b89 100644
--- a/assets/xml/objects/object_lightbox.xml
+++ b/assets/xml/objects/object_lightbox.xml
@@ -1,12 +1,11 @@
-
-
-
+
+
-
+
-
+
diff --git a/assets/xml/objects/object_link_child.xml b/assets/xml/objects/object_link_child.xml
index 640228441..36baf5aa6 100644
--- a/assets/xml/objects/object_link_child.xml
+++ b/assets/xml/objects/object_link_child.xml
@@ -123,8 +123,9 @@
-
-
+
+
+
@@ -175,11 +176,12 @@
+
+
-
diff --git a/assets/xml/objects/object_medal.xml b/assets/xml/objects/object_medal.xml
index 533872a55..eeb433c40 100644
--- a/assets/xml/objects/object_medal.xml
+++ b/assets/xml/objects/object_medal.xml
@@ -6,7 +6,7 @@
-
+
diff --git a/assets/xml/objects/object_mori_tex.xml b/assets/xml/objects/object_mori_tex.xml
index 79f1f0b4c..756347bcc 100644
--- a/assets/xml/objects/object_mori_tex.xml
+++ b/assets/xml/objects/object_mori_tex.xml
@@ -1,12 +1,12 @@
-
+
-
+
diff --git a/assets/xml/objects/object_oA3.xml b/assets/xml/objects/object_oA3.xml
index a492bd875..176ad0931 100644
--- a/assets/xml/objects/object_oA3.xml
+++ b/assets/xml/objects/object_oA3.xml
@@ -1,7 +1,6 @@
-
-
+
diff --git a/assets/xml/objects/object_oE1.xml b/assets/xml/objects/object_oE1.xml
index 4d5b1663f..5b3234893 100644
--- a/assets/xml/objects/object_oE1.xml
+++ b/assets/xml/objects/object_oE1.xml
@@ -56,7 +56,8 @@
-
+
+
diff --git a/assets/xml/objects/object_oE11.xml b/assets/xml/objects/object_oE11.xml
index 04f6f186d..26ff739cd 100644
--- a/assets/xml/objects/object_oE11.xml
+++ b/assets/xml/objects/object_oE11.xml
@@ -3,7 +3,8 @@
-
+
+
diff --git a/assets/xml/objects/object_oE12.xml b/assets/xml/objects/object_oE12.xml
index a5fa39fd2..4b89954e0 100644
--- a/assets/xml/objects/object_oE12.xml
+++ b/assets/xml/objects/object_oE12.xml
@@ -3,7 +3,8 @@
-
+
+
diff --git a/assets/xml/objects/object_oE2.xml b/assets/xml/objects/object_oE2.xml
index af62ad6d1..ea3ba91fc 100644
--- a/assets/xml/objects/object_oE2.xml
+++ b/assets/xml/objects/object_oE2.xml
@@ -56,7 +56,8 @@
-
+
+
diff --git a/assets/xml/objects/object_oE3.xml b/assets/xml/objects/object_oE3.xml
index 95227da38..4a6cb3d92 100644
--- a/assets/xml/objects/object_oE3.xml
+++ b/assets/xml/objects/object_oE3.xml
@@ -56,13 +56,14 @@
-
+
+
-
+
-
+
diff --git a/assets/xml/objects/object_oE5.xml b/assets/xml/objects/object_oE5.xml
index 040fb8d73..c05917dc9 100644
--- a/assets/xml/objects/object_oE5.xml
+++ b/assets/xml/objects/object_oE5.xml
@@ -52,9 +52,9 @@
-
-
-
+
+
+
diff --git a/assets/xml/objects/object_oE6.xml b/assets/xml/objects/object_oE6.xml
index 95bb602b6..d253130af 100644
--- a/assets/xml/objects/object_oE6.xml
+++ b/assets/xml/objects/object_oE6.xml
@@ -3,7 +3,8 @@
-
+
+
diff --git a/assets/xml/objects/object_oE7.xml b/assets/xml/objects/object_oE7.xml
index b3e588d4c..2b6b5cf31 100644
--- a/assets/xml/objects/object_oE7.xml
+++ b/assets/xml/objects/object_oE7.xml
@@ -7,7 +7,8 @@
-
+
+
diff --git a/assets/xml/objects/object_oE8.xml b/assets/xml/objects/object_oE8.xml
index be5de2494..8b1333fa9 100644
--- a/assets/xml/objects/object_oE8.xml
+++ b/assets/xml/objects/object_oE8.xml
@@ -3,7 +3,8 @@
-
+
+
diff --git a/assets/xml/objects/object_oE9.xml b/assets/xml/objects/object_oE9.xml
index 8ea7ee18c..e43cee426 100644
--- a/assets/xml/objects/object_oE9.xml
+++ b/assets/xml/objects/object_oE9.xml
@@ -3,7 +3,8 @@
-
+
+
diff --git a/assets/xml/objects/object_ossan.xml b/assets/xml/objects/object_ossan.xml
index 963053f3f..7e51c33bc 100644
--- a/assets/xml/objects/object_ossan.xml
+++ b/assets/xml/objects/object_ossan.xml
@@ -1,6 +1,9 @@
+
+
+
diff --git a/assets/xml/objects/object_rl.xml b/assets/xml/objects/object_rl.xml
index bbe0246ac..8453935b1 100644
--- a/assets/xml/objects/object_rl.xml
+++ b/assets/xml/objects/object_rl.xml
@@ -12,8 +12,6 @@
-
-
@@ -22,13 +20,12 @@
-
-
+
diff --git a/assets/xml/objects/object_sa.xml b/assets/xml/objects/object_sa.xml
index 8a6384040..e87cd793d 100644
--- a/assets/xml/objects/object_sa.xml
+++ b/assets/xml/objects/object_sa.xml
@@ -66,7 +66,7 @@
-
+
diff --git a/assets/xml/objects/object_sb.xml b/assets/xml/objects/object_sb.xml
index 64d3bb005..3adf2c17e 100644
--- a/assets/xml/objects/object_sb.xml
+++ b/assets/xml/objects/object_sb.xml
@@ -4,8 +4,9 @@
-
-
+
+
+
diff --git a/assets/xml/objects/object_skb.xml b/assets/xml/objects/object_skb.xml
index 5b5efb484..1220ddf6d 100644
--- a/assets/xml/objects/object_skb.xml
+++ b/assets/xml/objects/object_skb.xml
@@ -55,10 +55,15 @@
-
-
-
-
+
+
+
+
+
+
+
+
+
diff --git a/assets/xml/objects/object_skj.xml b/assets/xml/objects/object_skj.xml
index 38636256f..958301d2e 100644
--- a/assets/xml/objects/object_skj.xml
+++ b/assets/xml/objects/object_skj.xml
@@ -41,27 +41,25 @@
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
diff --git a/assets/xml/objects/object_spot02_objects.xml b/assets/xml/objects/object_spot02_objects.xml
index 65f45ff51..3dfaf227d 100644
--- a/assets/xml/objects/object_spot02_objects.xml
+++ b/assets/xml/objects/object_spot02_objects.xml
@@ -3,7 +3,6 @@
-
diff --git a/assets/xml/objects/object_spot17_obj.xml b/assets/xml/objects/object_spot17_obj.xml
index d4239d8d2..73a4ca520 100644
--- a/assets/xml/objects/object_spot17_obj.xml
+++ b/assets/xml/objects/object_spot17_obj.xml
@@ -7,6 +7,6 @@
-
+
diff --git a/assets/xml/objects/object_st.xml b/assets/xml/objects/object_st.xml
index 983b9e2ea..9556f081d 100644
--- a/assets/xml/objects/object_st.xml
+++ b/assets/xml/objects/object_st.xml
@@ -22,7 +22,9 @@
-
+
+
+
diff --git a/assets/xml/objects/object_ta.xml b/assets/xml/objects/object_ta.xml
index 5e446bf5c..4f339fc95 100644
--- a/assets/xml/objects/object_ta.xml
+++ b/assets/xml/objects/object_ta.xml
@@ -66,7 +66,6 @@
-
-
+
diff --git a/assets/xml/objects/object_tk.xml b/assets/xml/objects/object_tk.xml
index ffa44c548..5c9d0a0a6 100644
--- a/assets/xml/objects/object_tk.xml
+++ b/assets/xml/objects/object_tk.xml
@@ -8,7 +8,8 @@
-
+
+
diff --git a/assets/xml/objects/object_toki_objects.xml b/assets/xml/objects/object_toki_objects.xml
index cd07e60d2..3cada31f8 100644
--- a/assets/xml/objects/object_toki_objects.xml
+++ b/assets/xml/objects/object_toki_objects.xml
@@ -12,7 +12,8 @@
-
+
+
diff --git a/assets/xml/objects/object_tr.xml b/assets/xml/objects/object_tr.xml
index 986a88cc5..827b85bfe 100644
--- a/assets/xml/objects/object_tr.xml
+++ b/assets/xml/objects/object_tr.xml
@@ -9,7 +9,9 @@
-
+
+
+
@@ -97,7 +99,9 @@
-
+
+
+
diff --git a/assets/xml/objects/object_tw.xml b/assets/xml/objects/object_tw.xml
index c6b9ec609..c528fb451 100644
--- a/assets/xml/objects/object_tw.xml
+++ b/assets/xml/objects/object_tw.xml
@@ -106,9 +106,11 @@
-
-
+
+
+
+
@@ -130,9 +132,11 @@
-
-
+
+
+
+
diff --git a/assets/xml/objects/object_wf.xml b/assets/xml/objects/object_wf.xml
index 96ea84103..d5d70639d 100644
--- a/assets/xml/objects/object_wf.xml
+++ b/assets/xml/objects/object_wf.xml
@@ -122,6 +122,7 @@
+
diff --git a/assets/xml/objects/object_wood02.xml b/assets/xml/objects/object_wood02.xml
index 5dd80a17b..bdcc2d2e3 100644
--- a/assets/xml/objects/object_wood02.xml
+++ b/assets/xml/objects/object_wood02.xml
@@ -20,7 +20,7 @@
-
+
diff --git a/assets/xml/objects/object_zl4.xml b/assets/xml/objects/object_zl4.xml
index e87a65465..99cc12ea2 100644
--- a/assets/xml/objects/object_zl4.xml
+++ b/assets/xml/objects/object_zl4.xml
@@ -39,19 +39,21 @@
-
-
-
-
+
+
+
+
+
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
diff --git a/assets/xml/scenes/indoors/tokinoma.xml b/assets/xml/scenes/indoors/tokinoma.xml
index 4d83fe390..fb62d9c2c 100644
--- a/assets/xml/scenes/indoors/tokinoma.xml
+++ b/assets/xml/scenes/indoors/tokinoma.xml
@@ -1,5 +1,6 @@
+
@@ -12,7 +13,6 @@
-
diff --git a/assets/xml/scenes/indoors/tokinoma_pal_n64.xml b/assets/xml/scenes/indoors/tokinoma_pal_n64.xml
index eb98a321a..9c0a97099 100644
--- a/assets/xml/scenes/indoors/tokinoma_pal_n64.xml
+++ b/assets/xml/scenes/indoors/tokinoma_pal_n64.xml
@@ -1,5 +1,6 @@
+
diff --git a/assets/xml/scenes/overworld/spot20.xml b/assets/xml/scenes/overworld/spot20.xml
index 3d305508a..d3dd77a41 100644
--- a/assets/xml/scenes/overworld/spot20.xml
+++ b/assets/xml/scenes/overworld/spot20.xml
@@ -1,5 +1,6 @@
+
diff --git a/assets/xml/scenes/overworld/spot20_pal.xml b/assets/xml/scenes/overworld/spot20_pal.xml
index 0ba9380e1..297b1c316 100644
--- a/assets/xml/scenes/overworld/spot20_pal.xml
+++ b/assets/xml/scenes/overworld/spot20_pal.xml
@@ -1,5 +1,6 @@
+
diff --git a/assets/xml/textures/map_48x85_static.xml b/assets/xml/textures/map_48x85_static.xml
index 2788498a8..b8795bd07 100644
--- a/assets/xml/textures/map_48x85_static.xml
+++ b/assets/xml/textures/map_48x85_static.xml
@@ -1,72 +1,74 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/include/buffers.h b/include/buffers.h
new file mode 100644
index 000000000..80277fbbd
--- /dev/null
+++ b/include/buffers.h
@@ -0,0 +1,16 @@
+#ifndef BUFFERS_H
+#define BUFFERS_H
+
+#include "gfx.h"
+#include "macros.h"
+#include "ultra64.h"
+#include "config.h"
+
+extern u16 gZBuffer[SCREEN_HEIGHT][SCREEN_WIDTH]; // 0x25800 bytes
+extern u64 gGfxSPTaskOutputBuffer[0x3000]; // 0x18000 bytes
+extern u64 gGfxSPTaskYieldBuffer[OS_YIELD_DATA_SIZE / sizeof(u64)]; // 0xC00 bytes
+extern u64 gGfxSPTaskStack[SP_DRAM_STACK_SIZE64]; // 0x400 bytes
+extern GfxPool gGfxPools[2]; // 0x24820 bytes
+extern u8 gAudioHeap[AUDIO_HEAP_SIZE]; // 0x38000 bytes
+
+#endif
diff --git a/include/debug_arena.h b/include/debug_arena.h
new file mode 100644
index 000000000..ffc19a6c0
--- /dev/null
+++ b/include/debug_arena.h
@@ -0,0 +1,38 @@
+#ifndef DEBUG_ARENA_H
+#define DEBUG_ARENA_H
+
+#include "ultra64/ultratypes.h"
+
+void* DebugArena_Malloc(u32 size);
+void* DebugArena_MallocR(u32 size);
+void* DebugArena_Realloc(void* ptr, u32 newSize);
+void DebugArena_Free(void* ptr);
+void* DebugArena_Calloc(u32 num, u32 size);
+void DebugArena_GetSizes(u32* outMaxFree, u32* outFree, u32* outAlloc);
+void DebugArena_Check(void);
+void DebugArena_Init(void* start, u32 size);
+void DebugArena_Cleanup(void);
+s32 DebugArena_IsInitialized(void);
+
+#if IS_DEBUG_HEAP_ENABLED
+
+#define DEBUG_ARENA_MALLOC(size, ...) DebugArena_MallocDebug(size, __FILE__, __LINE__)
+#define DEBUG_ARENA_MALLOC_R(size, ...) DebugArena_MallocRDebug(size, __FILE__, __LINE__)
+#define DEBUG_ARENA_FREE(size, ...) DebugArena_FreeDebug(size, __FILE__, __LINE__)
+
+void DebugArena_CheckPointer(void* ptr, u32 size, const char* name, const char* action);
+void* DebugArena_MallocDebug(u32 size, const char* file, int line);
+void* DebugArena_MallocRDebug(u32 size, const char* file, int line);
+void* DebugArena_ReallocDebug(void* ptr, u32 newSize, const char* file, int line);
+void DebugArena_FreeDebug(void* ptr, const char* file, int line);
+void DebugArena_Display(void);
+
+#else
+
+#define DEBUG_ARENA_MALLOC(size, ...) DebugArena_Malloc(size)
+#define DEBUG_ARENA_MALLOC_R(size, ...) DebugArena_MallocR(size)
+#define DEBUG_ARENA_FREE(size, ...) DebugArena_Free(size)
+
+#endif
+
+#endif
diff --git a/include/fault.h b/include/fault.h
index 8f1979520..7418246f4 100644
--- a/include/fault.h
+++ b/include/fault.h
@@ -3,7 +3,7 @@
#include "ultra64.h"
#include "attributes.h"
-#include "padmgr.h"
+#include "libu64/pad.h"
#if !PLATFORM_N64
// These are the same as the 3-bit ansi color codes
diff --git a/include/functions.h b/include/functions.h
index 400941253..3ec423d55 100644
--- a/include/functions.h
+++ b/include/functions.h
@@ -30,40 +30,9 @@ void ActorOverlayTable_LogPrint(void);
void ActorOverlayTable_Init(void);
void ActorOverlayTable_Cleanup(void);
void SaveContext_Init(void);
-s32 func_800635D0(s32);
-void Regs_Init(void);
-void DebugCamera_ScreenText(u8 x, u8 y, const char* text); // ENABLE_NO_CLIP
-void DebugCamera_ScreenTextColored(u8 x, u8 y, u8 colorIndex, const char* text); // ENABLE_CAMERA_DEBUGGER
-#if DEBUG_FEATURES
-void Regs_UpdateEditor(Input* input); // ENABLE_REG_EDITOR
-#endif
-void Debug_DrawText(GraphicsContext* gfxCtx); // ENABLE_CAMERA_DEBUGGER || ENABLE_REG_EDITOR
void* MemCpy(void* dest, const void* src, s32 len);
-u16 QuestHint_GetSariaTextId(PlayState* play);
-u16 QuestHint_GetNaviTextId(PlayState* play);
-u16 MaskReaction_GetTextId(PlayState* play, u32 maskReactionSet);
-void CutsceneFlags_UnsetAll(PlayState* play);
-void CutsceneFlags_Set(PlayState* play, s16 flag);
-void CutsceneFlags_Unset(PlayState* play, s16 flag);
-s32 CutsceneFlags_Get(PlayState* play, s16 flag);
-
-s32 Kanji_OffsetFromShiftJIS(s32 character);
-#if PLATFORM_IQUE
-void Font_LoadCharCHN(Font* font, u16 character, u16 codePointIndex);
-#endif
-void Font_LoadCharWide(Font* font, u16 character, u16 codePointIndex);
-void Font_LoadChar(Font* font, u8 character, u16 codePointIndex);
-void Font_LoadMessageBoxIcon(Font* font, u16 icon);
-void Font_LoadOrderedFont(Font* font);
-
-void Health_InitMeter(PlayState* play);
-void Health_UpdateMeter(PlayState* play);
-void Health_DrawMeter(PlayState* play);
-void Health_UpdateBeatingHeart(PlayState* play);
-u32 Health_IsCritical(void);
-
void MapMark_Init(PlayState* play);
void MapMark_ClearPointers(PlayState* play);
void MapMark_Draw(PlayState* play);
@@ -72,55 +41,11 @@ void PreNmiBuff_SetReset(PreNmiBuff* this);
u32 PreNmiBuff_IsResetting(PreNmiBuff* this);
void Sched_FlushTaskQueue(void);
-Path* Path_GetByIndex(PlayState* play, s16 index, s16 max);
-f32 Path_OrientAndGetDistSq(Actor* actor, Path* path, s16 waypoint, s16* yaw);
-void Path_CopyLastPoint(Path* path, Vec3f* dest);
-
void PreNMI_Init(GameState* thisx);
-void func_80095AA0(PlayState* play, Room* room, Input* input, s32 arg3);
-void Room_DrawBackground2D(Gfx** gfxP, void* tex, void* tlut, u16 width, u16 height, u8 fmt, u8 siz, u16 tlutMode,
- u16 tlutCount, f32 offsetX, f32 offsetY);
-void Room_Init(PlayState* play, Room* room);
-u32 Room_SetupFirstRoom(PlayState* play, RoomContext* roomCtx);
-s32 Room_RequestNewRoom(PlayState* play, RoomContext* roomCtx, s32 roomNum);
-s32 Room_ProcessRoomRequest(PlayState* play, RoomContext* roomCtx);
-void Room_Draw(PlayState* play, Room* room, u32 flags);
-void Room_FinishRoomChange(PlayState* play, RoomContext* roomCtx);
void Sample_Destroy(GameState* thisx);
void Sample_Init(GameState* thisx);
-void Skin_UpdateVertices(MtxF* mtx, SkinVertex* skinVertices, SkinLimbModif* modifEntry, Vtx* vtxBuf, Vec3f* pos);
-void Skin_DrawAnimatedLimb(GraphicsContext* gfxCtx, Skin* skin, s32 limbIndex, s32 arg3, s32 drawFlags);
-void Skin_DrawLimb(GraphicsContext* gfxCtx, Skin* skin, s32 limbIndex, Gfx* dlistOverride, s32 drawFlags);
-void func_800A6330(Actor* actor, PlayState* play, Skin* skin, SkinPostDraw postDraw, s32 setTranslation);
-void func_800A6360(Actor* actor, PlayState* play, Skin* skin, SkinPostDraw postDraw,
- SkinOverrideLimbDraw overrideLimbDraw, s32 setTranslation);
-void func_800A6394(Actor* actor, PlayState* play, Skin* skin, SkinPostDraw postDraw,
- SkinOverrideLimbDraw overrideLimbDraw, s32 setTranslation, s32 arg6);
-void func_800A63CC(Actor* actor, PlayState* play, Skin* skin, SkinPostDraw postDraw,
- SkinOverrideLimbDraw overrideLimbDraw, s32 setTranslation, s32 arg6, s32 drawFlags);
-void Skin_GetLimbPos(Skin* skin, s32 limbIndex, Vec3f* offset, Vec3f* dst);
-void Skin_Init(PlayState* play, Skin* skin, SkeletonHeader* skeletonHeader, AnimationHeader* animationHeader);
-void Skin_Free(PlayState* play, Skin* skin);
-s32 Skin_ApplyAnimTransformations(Skin* skin, MtxF* limbMatrices, Actor* actor, s32 setTranslation);
-
-void Sram_InitNewSave(void);
-void Sram_InitDebugSave(void);
-void Sram_OpenSave(SramContext* sramCtx);
-void Sram_WriteSave(SramContext* sramCtx);
-void Sram_VerifyAndLoadAllSaves(FileSelectState* fileSelect, SramContext* sramCtx);
-void Sram_InitSave(FileSelectState* fileSelect, SramContext* sramCtx);
-void Sram_EraseSave(FileSelectState* fileSelect, SramContext* sramCtx);
-void Sram_CopySave(FileSelectState* fileSelect, SramContext* sramCtx);
-void Sram_WriteSramHeader(SramContext* sramCtx);
-void Sram_InitSram(GameState* gameState, SramContext* sramCtx);
-void Sram_Alloc(GameState* gameState, SramContext* sramCtx);
-void Sram_Init(PlayState* play, SramContext* sramCtx);
-void SsSram_Init(s32 addr, u8 handleType, u8 handleDomain, u8 handleLatency, u8 handlePageSize, u8 handleRelDuration,
- u8 handlePulse, u32 handleSpeed);
-void SsSram_Dma(void* dramAddr, size_t size, s32 direction);
-void SsSram_ReadWrite(s32 addr, void* dramAddr, size_t size, s32 direction);
void ViMode_LogPrint(OSViMode* osViMode);
void ViMode_Configure(ViMode* viMode, s32 type, s32 tvType, s32 loRes, s32 antialiasOff, s32 modeN, s32 fb16Bit,
s32 width, s32 height, s32 leftAdjust, s32 rightAdjust, s32 upperAdjust, s32 lowerAdjust);
@@ -175,9 +100,6 @@ void DebugCamera_Enable(DebugCam* debugCam, Camera* cam);
void DebugCamera_Update(DebugCam* debugCam, Camera* cam);
void DebugCamera_Reset(Camera* cam, DebugCam* debugCam);
-void func_800BB0A0(f32 u, Vec3f* pos, f32* roll, f32* viewAngle, f32* point0, f32* point1, f32* point2, f32* point3);
-s32 func_800BB2B4(Vec3f* pos, f32* roll, f32* fov, CutsceneCameraPoint* point, s16* keyFrame, f32* curFrame);
-
void PreRender_SetValuesSave(PreRender* this, u32 width, u32 height, void* fbuf, void* zbuf, void* cvg);
void PreRender_Init(PreRender* this);
void PreRender_SetValues(PreRender* this, u32 width, u32 height, void* fbuf, void* zbuf);
@@ -194,26 +116,6 @@ void func_800C213C(PreRender* this, Gfx** gfxP);
void PreRender_RestoreFramebuffer(PreRender* this, Gfx** gfxP);
void PreRender_CopyImageRegion(PreRender* this, Gfx** gfxP);
void PreRender_ApplyFilters(PreRender* this);
-void GameState_SetFBFilter(Gfx** gfxP);
-
-void GameState_Draw(GameState* gameState, GraphicsContext* gfxCtx);
-void GameState_SetFrameBuffer(GraphicsContext* gfxCtx);
-void GameState_ReqPadData(GameState* gameState);
-void GameState_Update(GameState* gameState);
-void GameState_InitArena(GameState* gameState, size_t size);
-void GameState_Realloc(GameState* gameState, size_t size);
-void GameState_Init(GameState* gameState, GameStateFunc init, GraphicsContext* gfxCtx);
-void GameState_Destroy(GameState* gameState);
-GameStateFunc GameState_GetInit(GameState* gameState);
-u32 GameState_IsRunning(GameState* gameState);
-#if DEBUG_FEATURES
-void* GameState_Alloc(GameState* gameState, size_t size, const char* file, int line);
-void* GameAlloc_MallocDebug(GameAlloc* this, u32 size, const char* file, int line);
-#endif
-void* GameAlloc_Malloc(GameAlloc* this, u32 size);
-void GameAlloc_Free(GameAlloc* this, void* data);
-void GameAlloc_Cleanup(GameAlloc* this);
-void GameAlloc_Init(GameAlloc* this);
void Graph_InitTHGA(GraphicsContext* gfxCtx);
GameStateOverlay* Graph_GetNextGameState(GameState* gameState);
void Graph_Init(GraphicsContext* gfxCtx);
@@ -230,40 +132,13 @@ void SysCfb_Init(s32 n64dd);
void* SysCfb_GetFbPtr(s32 idx);
void* SysCfb_GetFbEnd(void);
-u64* SysUcode_GetUCodeBoot(void);
-size_t SysUcode_GetUCodeBootSize(void);
-u64* SysUcode_GetUCode(void);
-u64* SysUcode_GetUCodeData(void);
-#if ENABLE_F3DEX3
-void SysUcode_LoadNewUcodeIfChanged();
-#endif
NORETURN void func_800D31A0(void);
void func_800D31F0(void);
void func_800D3210(void);
-void* DebugArena_Malloc(u32 size);
-void* DebugArena_MallocR(u32 size);
-void* DebugArena_Realloc(void* ptr, u32 newSize);
-void DebugArena_Free(void* ptr);
-void* DebugArena_Calloc(u32 num, u32 size);
-void DebugArena_GetSizes(u32* outMaxFree, u32* outFree, u32* outAlloc);
-void DebugArena_Check(void);
-void DebugArena_Init(void* start, u32 size);
-void DebugArena_Cleanup(void);
-s32 DebugArena_IsInitialized(void);
-#if IS_DEBUG_HEAP_ENABLED
-void DebugArena_CheckPointer(void* ptr, u32 size, const char* name, const char* action);
-void* DebugArena_MallocDebug(u32 size, const char* file, int line);
-void* DebugArena_MallocRDebug(u32 size, const char* file, int line);
-void* DebugArena_ReallocDebug(void* ptr, u32 newSize, const char* file, int line);
-void DebugArena_FreeDebug(void* ptr, const char* file, int line);
-void DebugArena_Display(void);
-#endif
void RcpUtils_PrintRegisterStatus(void);
void RcpUtils_Reset(void);
void* Overlay_AllocateAndLoad(uintptr_t vromStart, uintptr_t vromEnd, void* vramStart, void* vramEnd);
-void MtxConv_F2L(Mtx* m1, MtxF* m2);
-void MtxConv_L2F(MtxF* m1, Mtx* m2);
void Overlay_Relocate(void* allocatedRamAddr, OverlayRelocationSection* ovlRelocs, void* vramStart);
size_t Overlay_Load(uintptr_t vromStart, uintptr_t vromEnd, void* vramStart, void* vramEnd, void* allocatedRamAddr);
// ? func_800FC800(?);
diff --git a/include/gamealloc.h b/include/gamealloc.h
new file mode 100644
index 000000000..d9f8bfd4d
--- /dev/null
+++ b/include/gamealloc.h
@@ -0,0 +1,31 @@
+#ifndef GAMEALLOC_H
+#define GAMEALLOC_H
+
+#include "ultra64/ultratypes.h"
+
+typedef struct GameAllocEntry {
+ /* 0x00 */ struct GameAllocEntry* next;
+ /* 0x04 */ struct GameAllocEntry* prev;
+ /* 0x08 */ u32 size;
+ /* 0x0C */ u32 unk_0C;
+} GameAllocEntry; // size = 0x10
+
+typedef struct GameAlloc {
+ /* 0x00 */ GameAllocEntry base;
+ /* 0x10 */ GameAllocEntry* head;
+} GameAlloc; // size = 0x14
+
+#if DEBUG_FEATURES
+
+#define GAME_ALLOC_MALLOC(alloc, size, ...) GameAlloc_MallocDebug(alloc, size, __FILE__, __LINE__)
+void* GameAlloc_MallocDebug(GameAlloc* this, u32 size, const char* file, int line);
+#else
+#define GAME_ALLOC_MALLOC(alloc, size, ...) GameAlloc_Malloc(alloc, size)
+#endif
+
+void* GameAlloc_Malloc(GameAlloc* this, u32 size);
+void GameAlloc_Free(GameAlloc* this, void* data);
+void GameAlloc_Cleanup(GameAlloc* this);
+void GameAlloc_Init(GameAlloc* this);
+
+#endif
diff --git a/include/gfx.h b/include/gfx.h
index a69290249..8ecd6af74 100644
--- a/include/gfx.h
+++ b/include/gfx.h
@@ -58,6 +58,8 @@ typedef struct GraphicsContext {
#endif
} GraphicsContext; // size = 0x300
+extern Gfx gEmptyDL[];
+
Gfx* Gfx_SetFog(Gfx* gfx, s32 r, s32 g, s32 b, s32 a, s32 near, s32 far);
Gfx* Gfx_SetFogWithSync(Gfx* gfx, s32 r, s32 g, s32 b, s32 a, s32 near, s32 far);
Gfx* Gfx_SetFog2(Gfx* gfx, s32 r, s32 g, s32 b, s32 a, s32 near, s32 far);
diff --git a/include/kanread.h b/include/kanread.h
new file mode 100644
index 000000000..bea4831c8
--- /dev/null
+++ b/include/kanread.h
@@ -0,0 +1,8 @@
+#ifndef KANREAD_H
+#define KANREAD_H
+
+#include "ultra64/ultratypes.h"
+
+s32 Kanji_OffsetFromShiftJIS(s32 sjis);
+
+#endif
diff --git a/include/libc64/malloc.h b/include/libc64/malloc.h
index 86b58d17c..52aad9fed 100644
--- a/include/libc64/malloc.h
+++ b/include/libc64/malloc.h
@@ -16,11 +16,19 @@ void SystemArena_Cleanup(void);
s32 SystemArena_IsInitialized(void);
#if DEBUG_FEATURES
+#define SYSTEM_ARENA_MALLOC(size, ...) SystemArena_MallocDebug(size, __FILE__, __LINE__)
+#define SYSTEM_ARENA_MALLOC_R(size, ...) SystemArena_MallocRDebug(size, __FILE__, __LINE__)
+#define SYSTEM_ARENA_FREE(size, ...) SystemArena_FreeDebug(size, __FILE__, __LINE__)
+
void* SystemArena_MallocDebug(u32 size, const char* file, int line);
void* SystemArena_MallocRDebug(u32 size, const char* file, int line);
void* SystemArena_ReallocDebug(void* ptr, u32 newSize, const char* file, int line);
void SystemArena_FreeDebug(void* ptr, const char* file, int line);
void SystemArena_Display(void);
+#else
+#define SYSTEM_ARENA_MALLOC(size, ...) SystemArena_Malloc(size)
+#define SYSTEM_ARENA_MALLOC_R(size, ...) SystemArena_MallocR(size)
+#define SYSTEM_ARENA_FREE(size, ...) SystemArena_Free(size)
#endif
extern Arena gSystemArena;
diff --git a/include/libu64/debug.h b/include/libu64/debug.h
index 598c90195..b98911fab 100644
--- a/include/libu64/debug.h
+++ b/include/libu64/debug.h
@@ -3,12 +3,33 @@
#include "ultra64.h"
+#if DEBUG_FEATURES
+#define LOG(exp, value, format, ...) \
+ do { \
+ LogUtils_LogThreadId(__FILE__, __LINE__); \
+ osSyncPrintf(exp " = " format "\n", value); \
+ } while (0)
+#else
+#define LOG(exp, value, format, ...) (void)(value)
+#endif
+
+#define LOG_STRING(string, ...) LOG(#string, string, "%s", __VA_ARGS__)
+#define LOG_ADDRESS(exp, value, ...) LOG(exp, value, "%08x", __VA_ARGS__)
+#define LOG_TIME(exp, value, ...) LOG(exp, value, "%lld", __VA_ARGS__)
+#define LOG_NUM(exp, value, ...) LOG(exp, value, "%d", __VA_ARGS__)
+#define LOG_HEX(exp, value, ...) LOG(exp, value, "%x", __VA_ARGS__)
+#define LOG_HEX32(exp, value, ...) LOG(exp, value, "%08x", __VA_ARGS__)
+#define LOG_FLOAT(exp, value, ...) LOG(exp, value, "%f", __VA_ARGS__)
+
#if PLATFORM_N64 || DEBUG_FEATURES
f32 LogUtils_CheckFloatRange(const char* exp, int line, const char* valueName, f32 value, const char* minName, f32 min,
const char* maxName, f32 max);
#endif
#if DEBUG_FEATURES
+#define LOG_UTILS_CHECK_NULL_POINTER(exp, ptr, ...) LogUtils_CheckNullPointer(exp, ptr, __FILE__, __LINE__)
+#define LOG_UTILS_CHECK_VALID_POINTER(exp, ptr, ...) LogUtils_CheckValidPointer(exp, ptr, __FILE__, __LINE__)
+
s32 LogUtils_CheckIntRange(const char* exp, int line, const char* valueName, s32 value, const char* minName, s32 min,
const char* maxName, s32 max);
void LogUtils_LogHexDump(void* ptr, s32 size0);
@@ -17,6 +38,11 @@ void LogUtils_CheckBoundary(const char* name, s32 value, s32 unk, const char* fi
void LogUtils_CheckNullPointer(const char* exp, void* ptr, const char* file, int line);
void LogUtils_CheckValidPointer(const char* exp, void* ptr, const char* file, int line);
void LogUtils_LogThreadId(const char* name, int line);
+#else
+
+#define LOG_UTILS_CHECK_NULL_POINTER(exp, ptr, ...) (void)0
+#define LOG_UTILS_CHECK_VALID_POINTER(exp, ptr, ...) (void)0
+
#endif
void LogUtils_HungupThread(const char* name, int line);
diff --git a/include/libu64/mtxuty-cvt.h b/include/libu64/mtxuty-cvt.h
new file mode 100644
index 000000000..636978bb6
--- /dev/null
+++ b/include/libu64/mtxuty-cvt.h
@@ -0,0 +1,9 @@
+#ifndef LIBU64_MTXUTY_CVT_H
+#define LIBU64_MTXUTY_CVT_H
+
+#include "ultra64.h"
+
+void MtxConv_F2L(Mtx* m1, MtxF* m2);
+void MtxConv_L2F(MtxF* m1, Mtx* m2);
+
+#endif
diff --git a/include/macros.h b/include/macros.h
index f9ce9930c..747d95a50 100644
--- a/include/macros.h
+++ b/include/macros.h
@@ -4,6 +4,9 @@
#include "terminal.h"
#include "versions.h"
+#define SCREEN_WIDTH 320
+#define SCREEN_HEIGHT 240
+
#ifndef AVOID_UB
#define BAD_RETURN(type) type
#else
@@ -87,24 +90,6 @@
#define PRINTF_RST() (void)0
#endif
-#if DEBUG_FEATURES
-#define LOG(exp, value, format, ...) \
- do { \
- LogUtils_LogThreadId(__FILE__, __LINE__); \
- osSyncPrintf(exp " = " format "\n", value); \
- } while (0)
-#else
-#define LOG(exp, value, format, ...) (void)(value)
-#endif
-
-#define LOG_STRING(string, ...) LOG(#string, string, "%s", __VA_ARGS__)
-#define LOG_ADDRESS(exp, value, ...) LOG(exp, value, "%08x", __VA_ARGS__)
-#define LOG_TIME(exp, value, ...) LOG(exp, value, "%lld", __VA_ARGS__)
-#define LOG_NUM(exp, value, ...) LOG(exp, value, "%d", __VA_ARGS__)
-#define LOG_HEX(exp, value, ...) LOG(exp, value, "%x", __VA_ARGS__)
-#define LOG_HEX32(exp, value, ...) LOG(exp, value, "%08x", __VA_ARGS__)
-#define LOG_FLOAT(exp, value, ...) LOG(exp, value, "%f", __VA_ARGS__)
-
#define SET_NEXT_GAMESTATE(curState, newInit, newStruct) \
if (1) { \
GameState* state = curState; \
@@ -114,36 +99,12 @@
} (void)0
#if DEBUG_FEATURES
-
#define DMA_REQUEST_SYNC(ram, vrom, size, ...) DmaMgr_RequestSyncDebug(ram, vrom, size, __FILE__, __LINE__)
#define DMA_REQUEST_ASYNC(req, ram, vrom, size, unk5, queue, msg, ...) DmaMgr_RequestAsyncDebug(req, ram, vrom, size, unk5, queue, msg, __FILE__, __LINE__)
-#define GAME_STATE_ALLOC(gameState, size, ...) GameState_Alloc(gameState, size, __FILE__, __LINE__)
-#define DEBUG_ARENA_MALLOC(size, ...) DebugArena_MallocDebug(size, __FILE__, __LINE__)
-#define DEBUG_ARENA_MALLOC_R(size, ...) DebugArena_MallocRDebug(size, __FILE__, __LINE__)
-#define DEBUG_ARENA_FREE(size, ...) DebugArena_FreeDebug(size, __FILE__, __LINE__)
-#define SYSTEM_ARENA_MALLOC(size, ...) SystemArena_MallocDebug(size, __FILE__, __LINE__)
-#define SYSTEM_ARENA_MALLOC_R(size, ...) SystemArena_MallocRDebug(size, __FILE__, __LINE__)
-#define SYSTEM_ARENA_FREE(size, ...) SystemArena_FreeDebug(size, __FILE__, __LINE__)
-#define LOG_UTILS_CHECK_NULL_POINTER(exp, ptr, ...) LogUtils_CheckNullPointer(exp, ptr, __FILE__, __LINE__)
-#define LOG_UTILS_CHECK_VALID_POINTER(exp, ptr, ...) LogUtils_CheckValidPointer(exp, ptr, __FILE__, __LINE__)
-#define GAME_ALLOC_MALLOC(alloc, size, ...) GameAlloc_MallocDebug(alloc, size, __FILE__, __LINE__)
-
#else
-
#define DMA_REQUEST_SYNC(ram, vrom, size, ...) DmaMgr_RequestSync(ram, vrom, size)
#define DMA_REQUEST_ASYNC(req, ram, vrom, size, unk5, queue, msg, ...) DmaMgr_RequestAsync(req, ram, vrom, size, unk5, queue, msg)
-#define GAME_STATE_ALLOC(gameState, size, ...) THA_AllocTailAlign16(&(gameState)->tha, size)
-#define DEBUG_ARENA_MALLOC(size, ...) DebugArena_Malloc(size)
-#define DEBUG_ARENA_MALLOC_R(size, ...) DebugArena_MallocR(size)
-#define DEBUG_ARENA_FREE(size, ...) DebugArena_Free(size)
-#define SYSTEM_ARENA_MALLOC(size, ...) SystemArena_Malloc(size)
-#define SYSTEM_ARENA_MALLOC_R(size, ...) SystemArena_MallocR(size)
-#define SYSTEM_ARENA_FREE(size, ...) SystemArena_Free(size)
-#define LOG_UTILS_CHECK_NULL_POINTER(exp, ptr, ...) (void)0
-#define LOG_UTILS_CHECK_VALID_POINTER(exp, ptr, ...) (void)0
-#define GAME_ALLOC_MALLOC(alloc, size, ...) GameAlloc_Malloc(alloc, size)
-
-#endif /* DEBUG_FEATURES */
+#endif
#if PLATFORM_N64 || DEBUG_FEATURES
#define HUNGUP_AND_CRASH(...) Fault_AddHungupAndCrash(__FILE__, __LINE__)
diff --git a/include/rainbow.h b/include/rainbow.h
index 62d46b51d..c1e060571 100644
--- a/include/rainbow.h
+++ b/include/rainbow.h
@@ -39,4 +39,6 @@ void Rainbow_Update(Rainbow* this);
void osSyncPrintf(const char* fmt, ...);
+extern Rainbow gRainbow;
+
#endif
diff --git a/include/regs.h b/include/regs.h
index 3f3be0659..8c0c74c5d 100644
--- a/include/regs.h
+++ b/include/regs.h
@@ -2,6 +2,7 @@
#define REGS_H
#include "config.h"
+#include "ultra64.h"
#include "versions.h"
#define REG_GROUPS 29 // number of REG groups, i.e. REG, SREG, OREG, etc.
diff --git a/include/segment_symbols.h b/include/segment_symbols.h
index 6912df33f..dfc031221 100644
--- a/include/segment_symbols.h
+++ b/include/segment_symbols.h
@@ -1,8 +1,8 @@
#ifndef SEGMENT_SYMBOLS_H
#define SEGMENT_SYMBOLS_H
+#include "ultra64/ultratypes.h"
#include "versions.h"
-#include "z64.h"
#include "config.h"
#define DECLARE_SEGMENT(name) \
diff --git a/include/sys_ucode.h b/include/sys_ucode.h
new file mode 100644
index 000000000..fa690d478
--- /dev/null
+++ b/include/sys_ucode.h
@@ -0,0 +1,11 @@
+#ifndef SYS_UCODE_H
+#define SYS_UCODE_H
+
+#include "ultra64.h"
+
+u64* SysUcode_GetUCodeBoot(void);
+size_t SysUcode_GetUCodeBootSize(void);
+u64* SysUcode_GetUCode(void);
+u64* SysUcode_GetUCodeData(void);
+
+#endif
diff --git a/include/ultra64/rcp.h b/include/ultra64/rcp.h
index 8fb8a523e..63c1f5eee 100644
--- a/include/ultra64/rcp.h
+++ b/include/ultra64/rcp.h
@@ -539,6 +539,8 @@
#define VI_PAL_CLOCK 49656530 /* Hz = 49.656530 MHz */
#define VI_MPAL_CLOCK 48628316 /* Hz = 48.628316 MHz */
+// Custom PAL60 VI mode
+#define VI_CUSTOM_PAL60_LAN1 56
/**
* Audio Interface (AI) Registers
diff --git a/include/variables.h b/include/variables.h
index a27ee1f20..bb5640042 100644
--- a/include/variables.h
+++ b/include/variables.h
@@ -12,8 +12,6 @@
extern Debug gDebug;
#endif
-extern Mtx D_01000000;
-
extern void* osRomBase;
extern s32 osTvType;
extern u32 osRomType;
@@ -78,18 +76,14 @@ extern u32 __osBaseCounter;
extern u32 __osViIntrCount;
extern u32 __osTimerCounter;
extern EffectSsOverlay gEffectSsOverlayTable[EFFECT_SS_TYPE_MAX];
-extern Gfx D_80116280[];
extern ActorOverlay gActorOverlayTable[ACTOR_ID_MAX]; // original name: "actor_dlftbls" 801162A0
extern s32 gMaxActorId; // original name: "MaxProfile"
-extern s32 gDebugCamEnabled; // ENABLE_CAMERA_DEBUGGER
extern GameStateOverlay gGameStateOverlayTable[GAMESTATE_ID_MAX];
extern s32 gZeldaArenaLogSeverity;
extern MapData gMapDataTable;
extern s16 gSpoilingItems[3];
extern s16 gSpoilingItemReverts[3];
-extern Gfx gEmptyDL[];
-
extern u16 gSramSlotOffsets[];
// 4 16-colors palettes
extern u64 gMojiFontTLUTs[4][4]; // original name: "moji_tlut"
@@ -164,26 +158,6 @@ extern u8 gSequenceFontTable[];
extern u8 gSequenceTable[];
extern AudioTable gSampleBankTable;
-extern u8 gUseCutsceneCam;
-extern u16 D_8015FCCC;
-extern char D_8015FCD0[20];
-extern u8 D_8015FCE4;
-extern u16 gCamAtSplinePointsAppliedFrame;
-extern u16 gCamEyePointAppliedFrame;
-extern u16 gCamAtPointAppliedFrame;
-
-extern LightningStrike gLightningStrike;
-// TODO: These variables are here for BSS ordering but ideally they should not
-// be extern. This could be fixed by putting more stuff (e.g. struct definitions)
-// between gLightningStrike and gCustomLensFlareOn.
-extern s16 sLightningFlashAlpha;
-extern s16 sSunDepthTestX;
-extern s16 sSunDepthTestY;
-extern u8 gCustomLensFlareOn;
-extern Vec3f gCustomLensFlarePos;
-extern s16 gLensFlareScale;
-extern f32 gLensFlareColorIntensity;
-extern s16 gLensFlareGlareStrength;
extern MapData* gMapData;
extern f32 gBossMarkScale;
extern u32 D_8016139C;
@@ -227,14 +201,6 @@ extern u8 __osContLastCmd;
extern u8 __osMaxControllers;
extern __OSInode __osPfsInodeCache;
extern OSPifRam __osPfsPifRam;
-extern u16 gZBuffer[SCREEN_HEIGHT][SCREEN_WIDTH]; // 0x25800 bytes
-extern u64 gGfxSPTaskOutputBuffer[0x3000]; // 0x18000 bytes
-extern u64 gGfxSPTaskYieldBuffer[OS_YIELD_DATA_SIZE / sizeof(u64)]; // 0xC00 bytes
-extern u64 gGfxSPTaskStack[SP_DRAM_STACK_SIZE64]; // 0x400 bytes
-extern GfxPool gGfxPools[2]; // 0x24820 bytes
-extern u8 gAudioHeap[AUDIO_HEAP_SIZE]; // 0x38000 bytes
-
-extern Rainbow gRainbow;
extern u8 gRDPTimingsExist; // This variable being 1 indicates that the game is running on console or an extremely accurate emulator that can be affected by RDP lag.
diff --git a/include/z64.h b/include/z64.h
index e742a26c3..7089ff37c 100644
--- a/include/z64.h
+++ b/include/z64.h
@@ -8,56 +8,28 @@
#include "audiomgr.h"
#include "controller.h"
#include "versions.h"
-#include "z64save.h"
-#include "z64light.h"
-#include "z64bgcheck.h"
-#include "z64actor.h"
#include "z64player.h"
#include "z64audio.h"
-#include "z64object.h"
#include "z64ocarina.h"
-#include "z64camera.h"
-#include "z64environment.h"
-#include "z64cutscene.h"
-#include "z64collision_check.h"
#include "z64curve.h"
-#include "z64scene.h"
#include "z64effect.h"
-#include "z64game_over.h"
-#include "z64inventory.h"
-#include "z64item.h"
#include "z64animation.h"
#include "z64animation_legacy.h"
-#include "z64dma.h"
#include "letterbox.h"
#include "z64math.h"
#include "z64map_mark.h"
-#include "z64message.h"
-#include "z64olib.h"
#include "one_point_cutscene.h"
-#include "z64pause.h"
#include "z64play.h"
#include "z64skin.h"
#include "z64skin_matrix.h"
-#include "z64game.h"
-#include "z64transition.h"
-#include "z64transition_instances.h"
-#include "z64interface.h"
-#include "z64sfx_source.h"
-#include "z64skybox.h"
-#include "z64sram.h"
-#include "z64view.h"
#include "z64vis.h"
#include "zelda_arena.h"
#include "alignment.h"
#include "audiothread_cmd.h"
-#include "seqcmd.h"
-#include "sequence.h"
#include "sfx.h"
#include "color.h"
#include "libu64/gfxprint.h"
#include "z_lib.h"
-#include "ichain.h"
#include "regs.h"
#include "irqmgr.h"
#include "padmgr.h"
@@ -70,10 +42,8 @@
#include "gfx.h"
#include "gfx_setupdl.h"
#include "gfxalloc.h"
-#include "jpeg.h"
#include "prerender.h"
#include "rand.h"
-#include "libc64/qrand.h"
#include "sys_math.h"
#include "sys_math3d.h"
#include "widescreen.h"
@@ -103,53 +73,6 @@
#include "libc64/sprintf.h"
#include "libu64/debug.h"
-#define SCREEN_WIDTH 320
-#define SCREEN_HEIGHT 240
-
-#define THREAD_PRI_IDLE_INIT 10
-#define THREAD_PRI_MAIN_INIT 10
-#define THREAD_PRI_DMAMGR_LOW 10 // Used when decompressing files
-#define THREAD_PRI_GRAPH 11
-#define THREAD_PRI_AUDIOMGR 12
-#define THREAD_PRI_N64DD 13
-#define THREAD_PRI_DDMSG 13
-#define THREAD_PRI_PADMGR 14
-#define THREAD_PRI_MAIN 15
-#define THREAD_PRI_SCHED 15
-#define THREAD_PRI_DMAMGR 16
-#define THREAD_PRI_IRQMGR 17
-#define THREAD_PRI_FAULT_CLIENT (OS_PRIORITY_APPMAX - 1)
-#define THREAD_PRI_FAULT OS_PRIORITY_APPMAX
-
-#define THREAD_ID_IDLE 1
-#define THREAD_ID_FAULT 2
-#define THREAD_ID_MAIN 3
-#define THREAD_ID_GRAPH 4
-#define THREAD_ID_SCHED 5
-#define THREAD_ID_PADMGR 7
-
-#if ENABLE_PROFILER
-#define THREAD_ID_PIMGR 8
-#define THREAD_ID_VIMGR 9
-#else
-// Not sure why these are zero in vanilla.
-#define THREAD_ID_PIMGR 0
-#define THREAD_ID_VIMGR 0
-#endif
-
-#define THREAD_ID_N64DD 8
-#define THREAD_ID_DDMSG 9
-#define THREAD_ID_AUDIOMGR 10
-#define THREAD_ID_DMAMGR 18
-#define THREAD_ID_IRQMGR 19
-
-#define VI_CUSTOM_PAL60_LAN1 56 // Custom PAL60 VI mode
-
-typedef enum LensMode {
- /* 0 */ LENS_MODE_SHOW_ACTORS, // lens actors are invisible by default, and shown by using lens (for example, invisible enemies)
- /* 1 */ LENS_MODE_HIDE_ACTORS // lens actors are visible by default, and hidden by using lens (for example, fake walls)
-} LensMode;
-
typedef struct SetupState {
/* 0x00 */ GameState state;
} SetupState; // size = 0xA4
@@ -219,13 +142,6 @@ typedef struct SampleState {
/* 0x00A8 */ View view;
} SampleState; // size = 0x1D0
-typedef struct QuestHintCmd {
- /* 0x00 */ u8 byte0;
- /* 0x01 */ u8 byte1;
- /* 0x02 */ u8 byte2;
- /* 0x03 */ u8 byte3;
-} QuestHintCmd; // size = 0x4
-
typedef enum PauseBgPreRenderState {
/* 0 */ PAUSE_BG_PRERENDER_OFF, // Inactive, do nothing.
/* 1 */ PAUSE_BG_PRERENDER_SETUP, // The current frame is only drawn for the purpose of serving as the pause background.
diff --git a/include/z64actor.h b/include/z64actor.h
index ee82995fa..31323f1ed 100644
--- a/include/z64actor.h
+++ b/include/z64actor.h
@@ -739,6 +739,8 @@ typedef struct NpcInteractInfo {
#define TRANSITION_ACTOR_PARAMS_INDEX_SHIFT 10
#define GET_TRANSITION_ACTOR_INDEX(actor) PARAMS_GET_NOMASK((u16)(actor)->params, 10)
+extern Gfx D_80116280[];
+
void ActorShape_Init(ActorShape* shape, f32 yOffset, ActorShadowFunc shadowDraw, f32 shadowScale);
void ActorShadow_DrawCircle(Actor* actor, struct Lights* lights, struct PlayState* play);
void ActorShadow_DrawWhiteCircle(Actor* actor, struct Lights* lights, struct PlayState* play);
@@ -857,7 +859,7 @@ void Actor_DisableLens(struct PlayState* play);
void Actor_InitContext(struct PlayState* play, ActorContext* actorCtx, struct ActorEntry* playerEntry);
void Actor_UpdateAll(struct PlayState* play, ActorContext* actorCtx);
s32 Actor_CullingVolumeTest(struct PlayState* play, Actor* actor, Vec3f* projPos, f32 projW);
-void func_800315AC(struct PlayState* play, ActorContext* actorCtx);
+void Actor_DrawAll(struct PlayState* play, ActorContext* actorCtx);
void Actor_KillAllWithMissingObject(struct PlayState* play, ActorContext* actorCtx);
void func_80031B14(struct PlayState* play, ActorContext* actorCtx);
void func_80031C3C(ActorContext* actorCtx, struct PlayState* play);
diff --git a/include/z64audio.h b/include/z64audio.h
index e02ce7b84..ab3eec75e 100644
--- a/include/z64audio.h
+++ b/include/z64audio.h
@@ -68,6 +68,13 @@ typedef void (*AudioCustomUpdateFunction)(void);
#define AUDIO_RELOCATED_ADDRESS_START K0BASE
+typedef enum SoundSetting {
+ /* 0 */ SOUND_SETTING_STEREO,
+ /* 1 */ SOUND_SETTING_MONO,
+ /* 2 */ SOUND_SETTING_HEADSET,
+ /* 3 */ SOUND_SETTING_SURROUND
+} SoundSetting;
+
typedef enum SoundMode {
/* 0 */ SOUNDMODE_STEREO,
/* 1 */ SOUNDMODE_HEADSET,
@@ -1197,7 +1204,7 @@ void func_800F64E0(u8 arg0);
void Audio_ToggleMalonSinging(u8 malonSingingDisabled);
void Audio_SetEnvReverb(s8 reverb);
void Audio_SetCodeReverb(s8 reverb);
-void func_800F6700(s8 audioSetting);
+void Audio_SetSoundMode(s8 soundSetting);
void Audio_SetBaseFilter(u8);
void Audio_SetExtraFilter(u8);
void Audio_SetCutsceneFlag(s8 flag);
diff --git a/include/z64camera.h b/include/z64camera.h
index dfa6ad94d..0dc004386 100644
--- a/include/z64camera.h
+++ b/include/z64camera.h
@@ -4,7 +4,6 @@
#include "ultra64.h"
#include "z64cutscene.h"
#include "z64math.h"
-#include "z64save.h"
#include "config.h"
@@ -1709,6 +1708,8 @@ typedef enum DebugCamTextColor {
/* 7 */ DEBUG_CAM_TEXT_GREEN
} DebugCamTextColor;
+extern s32 gDebugCamEnabled; // ENABLE_CAMERA_DEBUGGER
+
void Camera_Init(Camera* camera, struct View* view, struct CollisionContext* colCtx, struct PlayState* play);
void Camera_InitDataUsingPlayer(Camera* camera, struct Player* player);
s16 Camera_ChangeStatus(Camera* camera, s16 status);
diff --git a/include/z64cutscene.h b/include/z64cutscene.h
index 270570e11..e84f16203 100644
--- a/include/z64cutscene.h
+++ b/include/z64cutscene.h
@@ -750,6 +750,14 @@ typedef enum {
/* 2 */ CS_MOTION_BLUR_DISABLE
} CsMotionBlurType;
+extern u8 gUseCutsceneCam;
+extern u16 D_8015FCCC;
+extern char D_8015FCD0[20];
+extern u8 D_8015FCE4;
+extern u16 gCamAtSplinePointsAppliedFrame;
+extern u16 gCamEyePointAppliedFrame;
+extern u16 gCamAtPointAppliedFrame;
+
void Cutscene_InitContext(struct PlayState* play, CutsceneContext* csCtx);
void Cutscene_StartManual(struct PlayState* play, CutsceneContext* csCtx);
void Cutscene_StopManual(struct PlayState* play, CutsceneContext* csCtx);
diff --git a/include/z64cutscene_flags.h b/include/z64cutscene_flags.h
new file mode 100644
index 000000000..5a3c7c2a7
--- /dev/null
+++ b/include/z64cutscene_flags.h
@@ -0,0 +1,13 @@
+#ifndef Z64CUTSCENE_FLAGS_H
+#define Z64CUTSCENE_FLAGS_H
+
+#include "ultra64.h"
+
+struct PlayState;
+
+void CutsceneFlags_UnsetAll(struct PlayState* play);
+void CutsceneFlags_Set(struct PlayState* play, s16 flag);
+void CutsceneFlags_Unset(struct PlayState* play, s16 flag);
+s32 CutsceneFlags_Get(struct PlayState* play, s16 flag);
+
+#endif
diff --git a/include/z64cutscene_spline.h b/include/z64cutscene_spline.h
new file mode 100644
index 000000000..3a7394945
--- /dev/null
+++ b/include/z64cutscene_spline.h
@@ -0,0 +1,12 @@
+#ifndef Z64CUTSCENE_SPLINE_H
+#define Z64CUTSCENE_SPLINE_H
+
+#include "ultra64.h"
+#include "z64math.h"
+
+union CutsceneCameraPoint;
+
+void func_800BB0A0(f32 u, Vec3f* pos, f32* roll, f32* viewAngle, f32* point0, f32* point1, f32* point2, f32* point3);
+s32 func_800BB2B4(Vec3f* pos, f32* roll, f32* fov, union CutsceneCameraPoint* point, s16* keyFrame, f32* curFrame);
+
+#endif
diff --git a/include/z64debug.h b/include/z64debug.h
new file mode 100644
index 000000000..0e2c7334e
--- /dev/null
+++ b/include/z64debug.h
@@ -0,0 +1,17 @@
+#ifndef Z64DEBUG_H
+#define Z64DEBUG_H
+
+#include "ultra64.h"
+
+struct GraphicsContext;
+struct Input;
+
+void Regs_Init(void);
+void DebugCamera_ScreenText(u8 x, u8 y, const char* text);
+void DebugCamera_ScreenTextColored(u8 x, u8 y, u8 colorIndex, const char* text);
+#if DEBUG_FEATURES
+void Regs_UpdateEditor(struct Input* input);
+#endif
+void Debug_DrawText(struct GraphicsContext* gfxCtx);
+
+#endif
diff --git a/include/z64environment.h b/include/z64environment.h
index 598c4655a..4c4bc770c 100644
--- a/include/z64environment.h
+++ b/include/z64environment.h
@@ -242,6 +242,19 @@ extern u8 gLightConfigAfterUnderwater;
extern u8 gInterruptSongOfStorms;
extern u16 gTimeSpeed;
+extern LightningStrike gLightningStrike;
+// TODO: These variables are here for BSS ordering but ideally they should not
+// be extern. This could be fixed by putting more stuff (e.g. struct definitions)
+// between gLightningStrike and gCustomLensFlareOn.
+extern s16 sLightningFlashAlpha;
+extern s16 sSunDepthTestX;
+extern s16 sSunDepthTestY;
+extern u8 gCustomLensFlareOn;
+extern Vec3f gCustomLensFlarePos;
+extern s16 gLensFlareScale;
+extern f32 gLensFlareColorIntensity;
+extern s16 gLensFlareGlareStrength;
+
void Environment_UpdateSkybox(u8 skyboxId, EnvironmentContext* envCtx, struct SkyboxContext* skyboxCtx);
void Environment_DrawSkyboxFilters(struct PlayState* play);
diff --git a/include/z64face_reaction.h b/include/z64face_reaction.h
new file mode 100644
index 000000000..274340ebc
--- /dev/null
+++ b/include/z64face_reaction.h
@@ -0,0 +1,74 @@
+#ifndef Z64FACE_REACTION_H
+#define Z64FACE_REACTION_H
+
+#include "ultra64.h"
+
+struct PlayState;
+
+typedef enum MaskReactionSet {
+ /* 0x00 */ MASK_REACTION_SET_CARPENTER_BOSS,
+ /* 0x01 */ MASK_REACTION_SET_CARPENTER_1,
+ /* 0x02 */ MASK_REACTION_SET_CARPENTER_2,
+ /* 0x03 */ MASK_REACTION_SET_CARPENTER_3,
+ /* 0x04 */ MASK_REACTION_SET_CARPENTER_4,
+ /* 0x05 */ MASK_REACTION_SET_HYRULIAN_GUARD,
+ /* 0x06 */ MASK_REACTION_SET_HEISHI4_1,
+ /* 0x07 */ MASK_REACTION_SET_HEISHI4_2,
+ /* 0x08 */ MASK_REACTION_SET_CUCCO_LADY,
+ /* 0x09 */ MASK_REACTION_SET_CARPENTERS_SON,
+ /* 0x0A */ MASK_REACTION_SET_KAKARIKO_ROOF_MAN,
+ /* 0x0B */ MASK_REACTION_SET_WINDMILL_MAN,
+ /* 0x0C */ MASK_REACTION_SET_12, // Unused
+ /* 0x0D */ MASK_REACTION_SET_CURSED_SKULLTULA_MAN,
+ /* 0x0E */ MASK_REACTION_SET_DAMPE,
+ /* 0x0F */ MASK_REACTION_SET_GRAVEYARD_KID,
+ /* 0x10 */ MASK_REACTION_SET_SARIA,
+ /* 0x11 */ MASK_REACTION_SET_MIDO,
+ /* 0x12 */ MASK_REACTION_SET_FADO,
+ /* 0x13 */ MASK_REACTION_SET_KOKIRI_1,
+ /* 0x14 */ MASK_REACTION_SET_KOKIRI_2,
+ /* 0x15 */ MASK_REACTION_SET_SKULL_KID,
+ /* 0x16 */ MASK_REACTION_SET_ZELDA,
+ /* 0x17 */ MASK_REACTION_SET_MALON,
+ /* 0x18 */ MASK_REACTION_SET_TALON,
+ /* 0x19 */ MASK_REACTION_SET_INGO,
+ /* 0x1A */ MASK_REACTION_SET_LAKESIDE_PROFESSOR,
+ /* 0x1B */ MASK_REACTION_SET_MAGIC_BEAN_SALESMAN,
+ /* 0x1C */ MASK_REACTION_SET_RUNNING_MAN,
+ /* 0x1D */ MASK_REACTION_SET_ZORA,
+ /* 0x1E */ MASK_REACTION_SET_KING_ZORA,
+ /* 0x1F */ MASK_REACTION_SET_RUTO,
+ /* 0x20 */ MASK_REACTION_SET_GORON,
+ /* 0x21 */ MASK_REACTION_SET_DARUNIA,
+ /* 0x22 */ MASK_REACTION_SET_GERUDO_WHITE,
+ /* 0x23 */ MASK_REACTION_SET_NABOORU,
+ /* 0x24 */ MASK_REACTION_SET_DANCING_COUPLE,
+ /* 0x25 */ MASK_REACTION_SET_DOG_LADY,
+ /* 0x26 */ MASK_REACTION_SET_WOMAN_3,
+ /* 0x27 */ MASK_REACTION_SET_MAN_1_BEARD,
+ /* 0x28 */ MASK_REACTION_SET_MAN_2_BALD,
+ /* 0x29 */ MASK_REACTION_SET_MAN_1_SHAVED_BLACK_SHIRT,
+ /* 0x2A */ MASK_REACTION_SET_BEGGAR,
+ /* 0x2B */ MASK_REACTION_SET_OLD_WOMAN,
+ /* 0x2C */ MASK_REACTION_SET_OLD_MAN,
+ /* 0x2D */ MASK_REACTION_SET_YOUNG_WOMAN_BROWN_HAIR,
+ /* 0x2E */ MASK_REACTION_SET_MAN_2_MUSTACHE_RED_SHIRT,
+ /* 0x2F */ MASK_REACTION_SET_MAN_2_MUSTACHE_BLUE_SHIRT,
+ /* 0x30 */ MASK_REACTION_SET_YOUNG_WOMAN_ORANGE_HAIR,
+ /* 0x31 */ MASK_REACTION_SET_MAN_2_ALT_MUSTACHE,
+ /* 0x32 */ MASK_REACTION_SET_MAN_1_BOWL_CUT_PURPLE_SHIRT,
+ /* 0x33 */ MASK_REACTION_SET_MAN_2_BEARD,
+ /* 0x34 */ MASK_REACTION_SET_OLD_MAN_BALD_BROWN_ROBE,
+ /* 0x35 */ MASK_REACTION_SET_MAN_2_MUSTACHE_WHITE_SHIRT,
+ /* 0x36 */ MASK_REACTION_SET_MAN_1_SHAVED_GREEN_SHIRT,
+ /* 0x37 */ MASK_REACTION_SET_WOMAN_2,
+ /* 0x38 */ MASK_REACTION_SET_OLD_MAN_BALD_PURPLE_ROBE,
+ /* 0x39 */ MASK_REACTION_SET_MAN_1_BOWL_CUT_GREEN_SHIRT,
+ /* 0x3A */ MASK_REACTION_SET_HAGGLING_TOWNSPEOPLE_1,
+ /* 0x3B */ MASK_REACTION_SET_HAGGLING_TOWNSPEOPLE_2,
+ /* 0x3C */ MASK_REACTION_SET_MAX
+} MaskReactionSet;
+
+u16 MaskReaction_GetTextId(struct PlayState* play, u32 maskReactionSet);
+
+#endif
diff --git a/include/z64font.h b/include/z64font.h
new file mode 100644
index 000000000..72f97fddd
--- /dev/null
+++ b/include/z64font.h
@@ -0,0 +1,41 @@
+#ifndef Z64FONT_H
+#define Z64FONT_H
+
+#include "ultra64.h"
+
+// TODO get these properties from the textures themselves
+#define FONT_CHAR_TEX_WIDTH 16
+#define FONT_CHAR_TEX_HEIGHT 16
+#define FONT_CHAR_TEX_SIZE ((FONT_CHAR_TEX_WIDTH * FONT_CHAR_TEX_HEIGHT) / 2) // 16x16 I4 texture
+
+typedef struct Font {
+ /* 0x0000 */ u32 msgOffset;
+ /* 0x0004 */ u32 msgLength;
+ union {
+ /* 0x0008 */ u8 charTexBuf[FONT_CHAR_TEX_SIZE * 120];
+ /* 0x0008 */ u64 force_structure_alignment_charTex;
+ };
+ union {
+ /* 0x3C08 */ u8 iconBuf[FONT_CHAR_TEX_SIZE];
+ /* 0x3C08 */ u64 force_structure_alignment_icon;
+ };
+ union {
+ /* 0x3C88 */ u8 fontBuf[FONT_CHAR_TEX_SIZE * 320];
+ /* 0x3C88 */ u64 force_structure_alignment_font;
+ };
+ union {
+ /* 0xDC88 */ u8 msgBuf[1280];
+ /* 0xDC88 */ u16 msgBufWide[640];
+ /* 0xDC88 */ u64 force_structure_alignment_msg;
+ };
+} Font; // size = 0xE188
+
+#if PLATFORM_IQUE
+void Font_LoadCharCHN(Font* font, u16 character, u16 codePointIndex);
+#endif
+void Font_LoadCharWide(Font* font, u16 character, u16 codePointIndex);
+void Font_LoadChar(Font* font, u8 character, u16 codePointIndex);
+void Font_LoadMessageBoxIcon(Font* font, u16 icon);
+void Font_LoadOrderedFont(Font* font);
+
+#endif
diff --git a/include/z64game.h b/include/z64game.h
index 1e86348f7..e2d9275fd 100644
--- a/include/z64game.h
+++ b/include/z64game.h
@@ -4,22 +4,12 @@
#include "ultra64/ultratypes.h"
#include "libu64/pad.h"
+#include "gamealloc.h"
#include "tha.h"
#include "config.h"
struct GraphicsContext;
-
-typedef struct GameAllocEntry {
- /* 0x00 */ struct GameAllocEntry* next;
- /* 0x04 */ struct GameAllocEntry* prev;
- /* 0x08 */ u32 size;
- /* 0x0C */ u32 unk_0C;
-} GameAllocEntry; // size = 0x10
-
-typedef struct GameAlloc {
- /* 0x00 */ GameAllocEntry base;
- /* 0x10 */ GameAllocEntry* head;
-} GameAlloc; // size = 0x14
+struct Gfx;
// Used in Graph_GetNextGameState in graph.c
#define DEFINE_GAMESTATE_INTERNAL(typeName, enumName) enumName,
@@ -49,4 +39,22 @@ typedef struct GameState {
/* 0xA0 */ u32 inPreNMIState;
} GameState; // size = 0xA4
+void GameState_SetFBFilter(Gfx** gfxP);
+void GameState_Draw(GameState* gameState, struct GraphicsContext* gfxCtx);
+void GameState_SetFrameBuffer(struct GraphicsContext* gfxCtx);
+void GameState_ReqPadData(GameState* gameState);
+void GameState_Update(GameState* gameState);
+void GameState_InitArena(GameState* gameState, size_t size);
+void GameState_Realloc(GameState* gameState, size_t size);
+void GameState_Init(GameState* gameState, GameStateFunc init, struct GraphicsContext* gfxCtx);
+void GameState_Destroy(GameState* gameState);
+GameStateFunc GameState_GetInit(GameState* gameState);
+u32 GameState_IsRunning(GameState* gameState);
+#if DEBUG_FEATURES
+void* GameState_Alloc(GameState* gameState, size_t size, const char* file, int line);
+#define GAME_STATE_ALLOC(gameState, size, ...) GameState_Alloc(gameState, size, __FILE__, __LINE__)
+#else
+#define GAME_STATE_ALLOC(gameState, size, ...) THA_AllocTailAlign16(&(gameState)->tha, size)
+#endif
+
#endif
diff --git a/include/z64inventory.h b/include/z64inventory.h
index 9a8133b3d..8c1a5a90d 100644
--- a/include/z64inventory.h
+++ b/include/z64inventory.h
@@ -3,7 +3,6 @@
#include "ultra64.h"
#include "z64item.h"
-#include "z64save.h"
struct PlayState;
diff --git a/include/z64lifemeter.h b/include/z64lifemeter.h
new file mode 100644
index 000000000..29b2656b8
--- /dev/null
+++ b/include/z64lifemeter.h
@@ -0,0 +1,14 @@
+#ifndef Z64LIFEMETER_H
+#define Z64LIFEMETER_H
+
+#include "ultra64/ultratypes.h"
+
+struct PlayState;
+
+void Health_InitMeter(struct PlayState* play);
+void Health_UpdateMeter(struct PlayState* play);
+void Health_DrawMeter(struct PlayState* play);
+void Health_UpdateBeatingHeart(struct PlayState* play);
+u32 Health_IsCritical(void);
+
+#endif
diff --git a/include/z64message.h b/include/z64message.h
index 415ab80ac..3758b690f 100644
--- a/include/z64message.h
+++ b/include/z64message.h
@@ -3,6 +3,7 @@
#include "z64view.h"
#include "versions.h"
+#include "z64font.h"
struct OcarinaStaff;
struct Actor;
@@ -14,11 +15,6 @@ typedef enum TextBoxIcon {
/* 2 */ TEXTBOX_ICON_ARROW
} TextBoxIcon;
-// TODO get these properties from the textures themselves
-#define FONT_CHAR_TEX_WIDTH 16
-#define FONT_CHAR_TEX_HEIGHT 16
-#define FONT_CHAR_TEX_SIZE ((FONT_CHAR_TEX_WIDTH * FONT_CHAR_TEX_HEIGHT) / 2) // 16x16 I4 texture
-
// TODO get these properties from the textures themselves
#define MESSAGE_STATIC_TEX_SIZE 0x1000
@@ -115,70 +111,6 @@ typedef enum MessageMode {
/* 0x37 */ MSGMODE_PAUSED // Causes the message system to do nothing until external code sets a new message mode or calls a public function
} MessageMode;
-typedef enum MaskReactionSet {
- /* 0x00 */ MASK_REACTION_SET_CARPENTER_BOSS,
- /* 0x01 */ MASK_REACTION_SET_CARPENTER_1,
- /* 0x02 */ MASK_REACTION_SET_CARPENTER_2,
- /* 0x03 */ MASK_REACTION_SET_CARPENTER_3,
- /* 0x04 */ MASK_REACTION_SET_CARPENTER_4,
- /* 0x05 */ MASK_REACTION_SET_HYRULIAN_GUARD,
- /* 0x06 */ MASK_REACTION_SET_HEISHI4_1,
- /* 0x07 */ MASK_REACTION_SET_HEISHI4_2,
- /* 0x08 */ MASK_REACTION_SET_CUCCO_LADY,
- /* 0x09 */ MASK_REACTION_SET_CARPENTERS_SON,
- /* 0x0A */ MASK_REACTION_SET_KAKARIKO_ROOF_MAN,
- /* 0x0B */ MASK_REACTION_SET_WINDMILL_MAN,
- /* 0x0C */ MASK_REACTION_SET_12, // Unused
- /* 0x0D */ MASK_REACTION_SET_CURSED_SKULLTULA_MAN,
- /* 0x0E */ MASK_REACTION_SET_DAMPE,
- /* 0x0F */ MASK_REACTION_SET_GRAVEYARD_KID,
- /* 0x10 */ MASK_REACTION_SET_SARIA,
- /* 0x11 */ MASK_REACTION_SET_MIDO,
- /* 0x12 */ MASK_REACTION_SET_FADO,
- /* 0x13 */ MASK_REACTION_SET_KOKIRI_1,
- /* 0x14 */ MASK_REACTION_SET_KOKIRI_2,
- /* 0x15 */ MASK_REACTION_SET_SKULL_KID,
- /* 0x16 */ MASK_REACTION_SET_ZELDA,
- /* 0x17 */ MASK_REACTION_SET_MALON,
- /* 0x18 */ MASK_REACTION_SET_TALON,
- /* 0x19 */ MASK_REACTION_SET_INGO,
- /* 0x1A */ MASK_REACTION_SET_LAKESIDE_PROFESSOR,
- /* 0x1B */ MASK_REACTION_SET_MAGIC_BEAN_SALESMAN,
- /* 0x1C */ MASK_REACTION_SET_RUNNING_MAN,
- /* 0x1D */ MASK_REACTION_SET_ZORA,
- /* 0x1E */ MASK_REACTION_SET_KING_ZORA,
- /* 0x1F */ MASK_REACTION_SET_RUTO,
- /* 0x20 */ MASK_REACTION_SET_GORON,
- /* 0x21 */ MASK_REACTION_SET_DARUNIA,
- /* 0x22 */ MASK_REACTION_SET_GERUDO_WHITE,
- /* 0x23 */ MASK_REACTION_SET_NABOORU,
- /* 0x24 */ MASK_REACTION_SET_DANCING_COUPLE,
- /* 0x25 */ MASK_REACTION_SET_DOG_LADY,
- /* 0x26 */ MASK_REACTION_SET_WOMAN_3,
- /* 0x27 */ MASK_REACTION_SET_MAN_1_BEARD,
- /* 0x28 */ MASK_REACTION_SET_MAN_2_BALD,
- /* 0x29 */ MASK_REACTION_SET_MAN_1_SHAVED_BLACK_SHIRT,
- /* 0x2A */ MASK_REACTION_SET_BEGGAR,
- /* 0x2B */ MASK_REACTION_SET_OLD_WOMAN,
- /* 0x2C */ MASK_REACTION_SET_OLD_MAN,
- /* 0x2D */ MASK_REACTION_SET_YOUNG_WOMAN_BROWN_HAIR,
- /* 0x2E */ MASK_REACTION_SET_MAN_2_MUSTACHE_RED_SHIRT,
- /* 0x2F */ MASK_REACTION_SET_MAN_2_MUSTACHE_BLUE_SHIRT,
- /* 0x30 */ MASK_REACTION_SET_YOUNG_WOMAN_ORANGE_HAIR,
- /* 0x31 */ MASK_REACTION_SET_MAN_2_ALT_MUSTACHE,
- /* 0x32 */ MASK_REACTION_SET_MAN_1_BOWL_CUT_PURPLE_SHIRT,
- /* 0x33 */ MASK_REACTION_SET_MAN_2_BEARD,
- /* 0x34 */ MASK_REACTION_SET_OLD_MAN_BALD_BROWN_ROBE,
- /* 0x35 */ MASK_REACTION_SET_MAN_2_MUSTACHE_WHITE_SHIRT,
- /* 0x36 */ MASK_REACTION_SET_MAN_1_SHAVED_GREEN_SHIRT,
- /* 0x37 */ MASK_REACTION_SET_WOMAN_2,
- /* 0x38 */ MASK_REACTION_SET_OLD_MAN_BALD_PURPLE_ROBE,
- /* 0x39 */ MASK_REACTION_SET_MAN_1_BOWL_CUT_GREEN_SHIRT,
- /* 0x3A */ MASK_REACTION_SET_HAGGLING_TOWNSPEOPLE_1,
- /* 0x3B */ MASK_REACTION_SET_HAGGLING_TOWNSPEOPLE_2,
- /* 0x3C */ MASK_REACTION_SET_MAX
-} MaskReactionSet;
-
typedef enum TextState {
/* 0 */ TEXT_STATE_NONE,
/* 1 */ TEXT_STATE_DONE_HAS_NEXT,
@@ -193,28 +125,6 @@ typedef enum TextState {
/* 10 */ TEXT_STATE_AWAITING_NEXT
} TextState;
-typedef struct Font {
- /* 0x0000 */ u32 msgOffset;
- /* 0x0004 */ u32 msgLength;
- union {
- /* 0x0008 */ u8 charTexBuf[FONT_CHAR_TEX_SIZE * 120];
- /* 0x0008 */ u64 force_structure_alignment_charTex;
- };
- union {
- /* 0x3C08 */ u8 iconBuf[FONT_CHAR_TEX_SIZE];
- /* 0x3C08 */ u64 force_structure_alignment_icon;
- };
- union {
- /* 0x3C88 */ u8 fontBuf[FONT_CHAR_TEX_SIZE * 320];
- /* 0x3C88 */ u64 force_structure_alignment_font;
- };
- union {
- /* 0xDC88 */ u8 msgBuf[1280];
- /* 0xDC88 */ u16 msgBufWide[640];
- /* 0xDC88 */ u64 force_structure_alignment_msg;
- };
-} Font; // size = 0xE188
-
#define TEXTBOX_ENDTYPE_DEFAULT 0x00
#define TEXTBOX_ENDTYPE_2_CHOICE 0x10
#define TEXTBOX_ENDTYPE_3_CHOICE 0x20
diff --git a/include/z64path.h b/include/z64path.h
new file mode 100644
index 000000000..0f9243974
--- /dev/null
+++ b/include/z64path.h
@@ -0,0 +1,19 @@
+#ifndef Z64PATH_H
+#define Z64PATH_H
+
+#include "ultra64.h"
+#include "z64math.h"
+
+struct PlayState;
+struct Actor;
+
+typedef struct Path {
+ /* 0x00 */ u8 count; // number of points in the path
+ /* 0x04 */ Vec3s* points; // Segment Address to the array of points
+} Path; // size = 0x8
+
+Path* Path_GetByIndex(struct PlayState* play, s16 index, s16 max);
+f32 Path_OrientAndGetDistSq(struct Actor* actor, Path* path, s16 waypoint, s16* yaw);
+void Path_CopyLastPoint(Path* path, Vec3f* dest);
+
+#endif
diff --git a/include/z64play.h b/include/z64play.h
index 144ff5b79..7073dbff4 100644
--- a/include/z64play.h
+++ b/include/z64play.h
@@ -4,7 +4,6 @@
#include "ultra64.h"
#include "prerender.h"
-
#include "z64actor.h"
#include "z64bgcheck.h"
#include "z64camera.h"
@@ -18,6 +17,7 @@
#include "z64message.h"
#include "z64object.h"
#include "z64pause.h"
+#include "z64room.h"
#include "z64scene.h"
#include "z64sfx_source.h"
#include "z64skybox.h"
@@ -28,6 +28,7 @@
#include "config.h"
union Color_RGBA8_u32;
+struct Path;
struct Player;
struct QuestHintCmd;
struct VisMono;
@@ -90,7 +91,7 @@ typedef struct PlayState {
/* 0x11DFC */ void* unk_11DFC;
/* 0x11E00 */ Spawn* spawnList;
/* 0x11E04 */ s16* exitList;
- /* 0x11E08 */ Path* pathList;
+ /* 0x11E08 */ struct Path* pathList;
/* 0x11E0C */ struct QuestHintCmd* naviQuestHints;
/* 0x11E10 */ void* specialEffects;
/* 0x11E14 */ u8 skyboxId;
@@ -119,6 +120,8 @@ typedef struct PlayState {
#endif
} PlayState; // size = 0x12518
+extern Mtx D_01000000; // billboardMtx
+
#define GET_ACTIVE_CAM(play) ((play)->cameraPtrs[(play)->activeCamId])
#define GET_PLAYER(play) ((Player*)(play)->actorCtx.actorLists[ACTORCAT_PLAYER].head)
diff --git a/include/z64quest_hint.h b/include/z64quest_hint.h
new file mode 100644
index 000000000..b592a07c3
--- /dev/null
+++ b/include/z64quest_hint.h
@@ -0,0 +1,11 @@
+#ifndef Z64QUEST_HINT_H
+#define Z64QUEST_HINT_H
+
+#include "ultra64.h"
+
+struct PlayState;
+
+u16 QuestHint_GetSariaTextId(struct PlayState* play);
+u16 QuestHint_GetNaviTextId(struct PlayState* play);
+
+#endif
diff --git a/include/z64quest_hint_commands.h b/include/z64quest_hint_commands.h
index 62f262f39..8b9951016 100644
--- a/include/z64quest_hint_commands.h
+++ b/include/z64quest_hint_commands.h
@@ -3,6 +3,13 @@
#include "ultra64.h"
+typedef struct QuestHintCmd {
+ /* 0x00 */ u8 byte0;
+ /* 0x01 */ u8 byte1;
+ /* 0x02 */ u8 byte2;
+ /* 0x03 */ u8 byte3;
+} QuestHintCmd; // size = 0x4
+
/*
* Hint Command Types
*/
diff --git a/include/z64room.h b/include/z64room.h
new file mode 100644
index 000000000..3d7de4f17
--- /dev/null
+++ b/include/z64room.h
@@ -0,0 +1,178 @@
+#ifndef Z64ROOM_H
+#define Z64ROOM_H
+
+#include "ultra64.h"
+#include "z64dma.h"
+#include "z64math.h"
+
+struct Input;
+struct PlayState;
+
+// Room shapes
+
+typedef enum RoomShapeType {
+ /* 0 */ ROOM_SHAPE_TYPE_NORMAL,
+ /* 1 */ ROOM_SHAPE_TYPE_IMAGE,
+ /* 2 */ ROOM_SHAPE_TYPE_CULLABLE,
+ /* 3 */ ROOM_SHAPE_TYPE_MAX
+} RoomShapeType;
+
+typedef struct RoomShapeBase {
+ /* 0x00 */ u8 type;
+} RoomShapeBase; // size = 0x01
+
+typedef struct RoomShapeDListsEntry {
+ /* 0x00 */ Gfx* opa;
+ /* 0x04 */ Gfx* xlu;
+} RoomShapeDListsEntry; // size = 0x08
+
+typedef struct RoomShapeNormal {
+ /* 0x00 */ RoomShapeBase base;
+ /* 0x01 */ u8 numEntries;
+ /* 0x04 */ RoomShapeDListsEntry* entries;
+ /* 0x08 */ RoomShapeDListsEntry* entriesEnd;
+} RoomShapeNormal; // size = 0x0C
+
+typedef enum RoomShapeImageAmountType {
+ /* 1 */ ROOM_SHAPE_IMAGE_AMOUNT_SINGLE = 1,
+ /* 2 */ ROOM_SHAPE_IMAGE_AMOUNT_MULTI
+} RoomShapeImageAmountType;
+
+typedef struct RoomShapeImageBase {
+ /* 0x00 */ RoomShapeBase base;
+ /* 0x01 */ u8 amountType; // RoomShapeImageAmountType
+ /* 0x04 */ RoomShapeDListsEntry* entry;
+} RoomShapeImageBase; // size = 0x08
+
+typedef struct RoomShapeImageSingle {
+ /* 0x00 */ RoomShapeImageBase base;
+ /* 0x08 */ void* source;
+ /* 0x0C */ u32 unk_0C;
+ /* 0x10 */ void* tlut;
+ /* 0x14 */ u16 width;
+ /* 0x16 */ u16 height;
+ /* 0x18 */ u8 fmt;
+ /* 0x19 */ u8 siz;
+ /* 0x1A */ u16 tlutMode;
+ /* 0x1C */ u16 tlutCount;
+} RoomShapeImageSingle; // size = 0x20
+
+typedef struct RoomShapeImageMultiBgEntry {
+ /* 0x00 */ u16 unk_00;
+ /* 0x02 */ u8 bgCamIndex; // for which bg cam index is this entry for
+ /* 0x04 */ void* source;
+ /* 0x08 */ u32 unk_0C;
+ /* 0x0C */ void* tlut;
+ /* 0x10 */ u16 width;
+ /* 0x12 */ u16 height;
+ /* 0x14 */ u8 fmt;
+ /* 0x15 */ u8 siz;
+ /* 0x16 */ u16 tlutMode;
+ /* 0x18 */ u16 tlutCount;
+} RoomShapeImageMultiBgEntry; // size = 0x1C
+
+typedef struct RoomShapeImageMulti {
+ /* 0x00 */ RoomShapeImageBase base;
+ /* 0x08 */ u8 numBackgrounds;
+ /* 0x0C */ RoomShapeImageMultiBgEntry* backgrounds;
+} RoomShapeImageMulti; // size = 0x10
+
+typedef struct RoomShapeCullableEntry {
+ /* 0x00 */ Vec3s boundsSphereCenter;
+ /* 0x06 */ s16 boundsSphereRadius;
+ /* 0x08 */ Gfx* opa;
+ /* 0x0C */ Gfx* xlu;
+} RoomShapeCullableEntry; // size = 0x10
+
+#define ROOM_SHAPE_CULLABLE_MAX_ENTRIES 64
+
+typedef struct RoomShapeCullable {
+ /* 0x00 */ RoomShapeBase base;
+ /* 0x01 */ u8 numEntries;
+ /* 0x04 */ RoomShapeCullableEntry* entries;
+ /* 0x08 */ RoomShapeCullableEntry* entriesEnd;
+} RoomShapeCullable; // size = 0x0C
+
+typedef union RoomShape {
+ RoomShapeBase base;
+ RoomShapeNormal normal;
+ union {
+ RoomShapeImageBase base;
+ RoomShapeImageSingle single;
+ RoomShapeImageMulti multi;
+ } image;
+ RoomShapeCullable cullable;
+} RoomShape; // "Ground Shape"
+
+typedef enum RoomType {
+ /* 0 */ ROOM_TYPE_NORMAL,
+ /* 1 */ ROOM_TYPE_DUNGEON, // Blocks Sun's Song's time advance effect. Not exclusively used by typical dungeon rooms.
+ /* 2 */ ROOM_TYPE_INDOORS, // Reduces player run speed and blocks player from attacking or jumping.
+ /* 3 */ ROOM_TYPE_3, // Unused. Color dithering is turned off when drawing the room and other things.
+ /* 4 */ ROOM_TYPE_4, // Unused. Prevents switching to CAM_SET_HORSE when mounting a horse.
+ /* 5 */ ROOM_TYPE_BOSS // Disables Environment_AdjustLights
+} RoomType;
+
+typedef enum RoomEnvironmentType {
+ /* 0 */ ROOM_ENV_DEFAULT,
+ /* 1 */ ROOM_ENV_COLD,
+ /* 2 */ ROOM_ENV_WARM,
+ /* 3 */ ROOM_ENV_HOT, // Enables hot room timer for the current room
+ /* 4 */ ROOM_ENV_UNK_STRETCH_1,
+ /* 5 */ ROOM_ENV_UNK_STRETCH_2,
+ /* 6 */ ROOM_ENV_UNK_STRETCH_3
+} RoomEnvironmentType;
+
+typedef enum LensMode {
+ /* 0 */ LENS_MODE_SHOW_ACTORS, // lens actors are invisible by default, and shown by using lens (for example, invisible enemies)
+ /* 1 */ LENS_MODE_HIDE_ACTORS // lens actors are visible by default, and hidden by using lens (for example, fake walls)
+} LensMode;
+
+typedef struct Room {
+ /* 0x00 */ s8 num; // -1 is invalid room
+ /* 0x01 */ u8 unk_01;
+ /* 0x02 */ u8 environmentType;
+ /* 0x03 */ u8 type;
+ /* 0x04 */ s8 echo;
+ /* 0x05 */ u8 lensMode;
+#if ENABLE_F3DEX3
+ u8 occPlaneCount;
+ OcclusionPlaneCandidate* occPlaneList;
+#endif
+ /* 0x08 */ RoomShape* roomShape; // original name: "ground_shape"
+ /* 0x0C */ void* segment;
+ /* 0x10 */ char unk_10[0x4];
+} Room; // size = 0x14
+
+typedef struct RoomContext {
+ /* 0x00 */ Room curRoom;
+ /* 0x14 */ Room prevRoom;
+ /* 0x28 */ void* bufPtrs[2]; // Start and end pointers for the room buffer. Can be split into two pages, where page 0 is allocated from the start pointer and page 1 is allocated from the end pointer.
+ /* 0x30 */ u8 activeBufPage; // 0 - First page in memory, 1 - Last page in memory
+ /* 0x31 */ s8 status; // 0 - Free for new room request, 1 - DmaRequest for a new room is in progress
+ /* 0x34 */ void* roomRequestAddr; // Pointer to where the requested room segment will be stored
+ /* 0x38 */ DmaRequest dmaRequest;
+ /* 0x58 */ OSMesgQueue loadQueue;
+ /* 0x70 */ OSMesg loadMsg;
+ /* 0x74 */ s16 drawParams[2]; // context-specific data used by the current scene draw config
+} RoomContext; // size = 0x78
+
+typedef struct RoomList {
+ /* 0x00 */ u8 count;
+ /* 0x04 */ RomFile* romFiles; // Array of rom addresses for each room in a scene
+} RoomList;
+
+#define ROOM_DRAW_OPA (1 << 0)
+#define ROOM_DRAW_XLU (1 << 1)
+
+void func_80095AA0(struct PlayState* play, Room* room, struct Input* input, s32 arg3);
+void Room_DrawBackground2D(Gfx** gfxP, void* tex, void* tlut, u16 width, u16 height, u8 fmt, u8 siz, u16 tlutMode,
+ u16 tlutCount, f32 offsetX, f32 offsetY);
+void Room_Init(struct PlayState* play, Room* room);
+u32 Room_SetupFirstRoom(struct PlayState* play, RoomContext* roomCtx);
+s32 Room_RequestNewRoom(struct PlayState* play, RoomContext* roomCtx, s32 roomNum);
+s32 Room_ProcessRoomRequest(struct PlayState* play, RoomContext* roomCtx);
+void Room_Draw(struct PlayState* play, Room* room, u32 flags);
+void Room_FinishRoomChange(struct PlayState* play, RoomContext* roomCtx);
+
+#endif
diff --git a/include/z64save.h b/include/z64save.h
index 666630ead..6214c5c5c 100644
--- a/include/z64save.h
+++ b/include/z64save.h
@@ -6,6 +6,11 @@
#include "z64inventory.h"
#include "z64math.h"
+typedef enum ZTargetSetting {
+ /* 0 */ Z_TARGET_SETTING_SWITCH,
+ /* 1 */ Z_TARGET_SETTING_HOLD
+} ZTargetSetting;
+
typedef enum Language {
#if OOT_NTSC
/* 0 */ LANGUAGE_JPN,
@@ -326,10 +331,10 @@ typedef struct SaveContext {
/* 0x1404 */ u16 minigameState;
/* 0x1406 */ u16 minigameScore; // "yabusame_total"
/* 0x1408 */ char unk_1408[0x0001];
- /* 0x1409 */ u8 language; // NTSC 0: Japanese; 1: English | PAL 0: English; 1: German; 2: French
- /* 0x140A */ u8 audioSetting;
+ /* 0x1409 */ u8 language; // NTSC 0: Japanese; 1: English | PAL 0: English; 1: German; 2: French (see enum `Language`)
+ /* 0x140A */ u8 soundSetting; // 0: Stereo; 1: Mono; 2: Headset; 3: Surround (see enum `SoundSetting`)
/* 0x140B */ char unk_140B[0x0001];
- /* 0x140C */ u8 zTargetSetting; // 0: Switch; 1: Hold
+ /* 0x140C */ u8 zTargetSetting; // 0: Switch; 1: Hold (see enum `ZTargetSetting`)
/* 0x140E */ u16 forcedSeqId; // immediately start playing the sequence if set
/* 0x1410 */ u8 cutsceneTransitionControl; // context dependent usage: can either trigger a delayed fade or control fill alpha
/* 0x1411 */ char unk_1411[0x0001];
diff --git a/include/z64scene.h b/include/z64scene.h
index 4f25eea60..427394281 100644
--- a/include/z64scene.h
+++ b/include/z64scene.h
@@ -4,16 +4,17 @@
#include "macros.h"
#include "ultra64.h"
#include "z64bgcheck.h"
-#include "z64dma.h"
#include "z64environment.h"
#include "z64light.h"
#include "z64math.h"
+#include "z64path.h"
#include "config.h"
#include "command_macros_base.h"
struct GameState;
struct PlayState;
+struct RoomShapeBase;
typedef struct SceneTableEntry {
/* 0x00 */ RomFile sceneFile;
@@ -52,163 +53,6 @@ typedef struct Spawn {
/* 0x01 */ u8 room;
} Spawn;
-typedef struct Path {
- /* 0x00 */ u8 count; // number of points in the path
- /* 0x04 */ Vec3s* points; // Segment Address to the array of points
-} Path; // size = 0x8
-
-// Room shapes
-
-typedef enum RoomShapeType {
- /* 0 */ ROOM_SHAPE_TYPE_NORMAL,
- /* 1 */ ROOM_SHAPE_TYPE_IMAGE,
- /* 2 */ ROOM_SHAPE_TYPE_CULLABLE,
- /* 3 */ ROOM_SHAPE_TYPE_MAX
-} RoomShapeType;
-
-typedef struct RoomShapeBase {
- /* 0x00 */ u8 type;
-} RoomShapeBase; // size = 0x01
-
-typedef struct RoomShapeDListsEntry {
- /* 0x00 */ Gfx* opa;
- /* 0x04 */ Gfx* xlu;
-} RoomShapeDListsEntry; // size = 0x08
-
-typedef struct RoomShapeNormal {
- /* 0x00 */ RoomShapeBase base;
- /* 0x01 */ u8 numEntries;
- /* 0x04 */ RoomShapeDListsEntry* entries;
- /* 0x08 */ RoomShapeDListsEntry* entriesEnd;
-} RoomShapeNormal; // size = 0x0C
-
-typedef enum RoomShapeImageAmountType {
- /* 1 */ ROOM_SHAPE_IMAGE_AMOUNT_SINGLE = 1,
- /* 2 */ ROOM_SHAPE_IMAGE_AMOUNT_MULTI
-} RoomShapeImageAmountType;
-
-typedef struct RoomShapeImageBase {
- /* 0x00 */ RoomShapeBase base;
- /* 0x01 */ u8 amountType; // RoomShapeImageAmountType
- /* 0x04 */ RoomShapeDListsEntry* entry;
-} RoomShapeImageBase; // size = 0x08
-
-typedef struct RoomShapeImageSingle {
- /* 0x00 */ RoomShapeImageBase base;
- /* 0x08 */ void* source;
- /* 0x0C */ u32 unk_0C;
- /* 0x10 */ void* tlut;
- /* 0x14 */ u16 width;
- /* 0x16 */ u16 height;
- /* 0x18 */ u8 fmt;
- /* 0x19 */ u8 siz;
- /* 0x1A */ u16 tlutMode;
- /* 0x1C */ u16 tlutCount;
-} RoomShapeImageSingle; // size = 0x20
-
-typedef struct RoomShapeImageMultiBgEntry {
- /* 0x00 */ u16 unk_00;
- /* 0x02 */ u8 bgCamIndex; // for which bg cam index is this entry for
- /* 0x04 */ void* source;
- /* 0x08 */ u32 unk_0C;
- /* 0x0C */ void* tlut;
- /* 0x10 */ u16 width;
- /* 0x12 */ u16 height;
- /* 0x14 */ u8 fmt;
- /* 0x15 */ u8 siz;
- /* 0x16 */ u16 tlutMode;
- /* 0x18 */ u16 tlutCount;
-} RoomShapeImageMultiBgEntry; // size = 0x1C
-
-typedef struct RoomShapeImageMulti {
- /* 0x00 */ RoomShapeImageBase base;
- /* 0x08 */ u8 numBackgrounds;
- /* 0x0C */ RoomShapeImageMultiBgEntry* backgrounds;
-} RoomShapeImageMulti; // size = 0x10
-
-typedef struct RoomShapeCullableEntry {
- /* 0x00 */ Vec3s boundsSphereCenter;
- /* 0x06 */ s16 boundsSphereRadius;
- /* 0x08 */ Gfx* opa;
- /* 0x0C */ Gfx* xlu;
-} RoomShapeCullableEntry; // size = 0x10
-
-#define ROOM_SHAPE_CULLABLE_MAX_ENTRIES 64
-
-typedef struct RoomShapeCullable {
- /* 0x00 */ RoomShapeBase base;
- /* 0x01 */ u8 numEntries;
- /* 0x04 */ RoomShapeCullableEntry* entries;
- /* 0x08 */ RoomShapeCullableEntry* entriesEnd;
-} RoomShapeCullable; // size = 0x0C
-
-typedef union RoomShape {
- RoomShapeBase base;
- RoomShapeNormal normal;
- union {
- RoomShapeImageBase base;
- RoomShapeImageSingle single;
- RoomShapeImageMulti multi;
- } image;
- RoomShapeCullable cullable;
-} RoomShape; // "Ground Shape"
-
-typedef enum RoomType {
- /* 0 */ ROOM_TYPE_NORMAL,
- /* 1 */ ROOM_TYPE_DUNGEON, // Blocks Sun's Song's time advance effect. Not exclusively used by typical dungeon rooms.
- /* 2 */ ROOM_TYPE_INDOORS, // Reduces player run speed and blocks player from attacking or jumping.
- /* 3 */ ROOM_TYPE_3, // Unused. Color dithering is turned off when drawing the room and other things.
- /* 4 */ ROOM_TYPE_4, // Unused. Prevents switching to CAM_SET_HORSE when mounting a horse.
- /* 5 */ ROOM_TYPE_BOSS // Disables Environment_AdjustLights
-} RoomType;
-
-typedef enum RoomEnvironmentType {
- /* 0 */ ROOM_ENV_DEFAULT,
- /* 1 */ ROOM_ENV_COLD,
- /* 2 */ ROOM_ENV_WARM,
- /* 3 */ ROOM_ENV_HOT, // Enables hot room timer for the current room
- /* 4 */ ROOM_ENV_UNK_STRETCH_1,
- /* 5 */ ROOM_ENV_UNK_STRETCH_2,
- /* 6 */ ROOM_ENV_UNK_STRETCH_3
-} RoomEnvironmentType;
-
-typedef struct Room {
- /* 0x00 */ s8 num; // -1 is invalid room
- /* 0x01 */ u8 unk_01;
- /* 0x02 */ u8 environmentType;
- /* 0x03 */ u8 type;
- /* 0x04 */ s8 echo;
- /* 0x05 */ u8 lensMode;
-#if ENABLE_F3DEX3
- u8 occPlaneCount;
- OcclusionPlaneCandidate* occPlaneList;
-#endif
- /* 0x08 */ RoomShape* roomShape; // original name: "ground_shape"
- /* 0x0C */ void* segment;
- /* 0x10 */ char unk_10[0x4];
-} Room; // size = 0x14
-
-typedef struct RoomContext {
- /* 0x00 */ Room curRoom;
- /* 0x14 */ Room prevRoom;
- /* 0x28 */ void* bufPtrs[2]; // Start and end pointers for the room buffer. Can be split into two pages, where page 0 is allocated from the start pointer and page 1 is allocated from the end pointer.
- /* 0x30 */ u8 activeBufPage; // 0 - First page in memory, 1 - Last page in memory
- /* 0x31 */ s8 status; // 0 - Free for new room request, 1 - DmaRequest for a new room is in progress
- /* 0x34 */ void* roomRequestAddr; // Pointer to where the requested room segment will be stored
- /* 0x38 */ DmaRequest dmaRequest;
- /* 0x58 */ OSMesgQueue loadQueue;
- /* 0x70 */ OSMesg loadMsg;
- /* 0x74 */ s16 drawParams[2]; // context-specific data used by the current scene draw config
-} RoomContext; // size = 0x78
-
-typedef struct RoomList {
- /* 0x00 */ u8 count;
- /* 0x04 */ RomFile* romFiles; // Array of rom addresses for each room in a scene
-} RoomList;
-
-#define ROOM_DRAW_OPA (1 << 0)
-#define ROOM_DRAW_XLU (1 << 1)
-
// Scene commands
typedef struct SCmdBase {
@@ -278,7 +122,7 @@ typedef struct SCmdRoomBehavior {
typedef struct SCmdMesh {
/* 0x00 */ u8 code;
/* 0x01 */ u8 data1;
- /* 0x04 */ RoomShapeBase* data;
+ /* 0x04 */ struct RoomShapeBase* data;
} SCmdMesh;
typedef struct SCmdObjectList {
diff --git a/include/z64skin.h b/include/z64skin.h
index d29c7c748..641a98092 100644
--- a/include/z64skin.h
+++ b/include/z64skin.h
@@ -3,6 +3,10 @@
#include "z64animation.h"
+struct Actor;
+struct GraphicsContext;
+struct PlayState;
+
/**
* Holds a compact version of a vertex used in the Skin system
* It is used to initialise the Vtx used by an animated limb
@@ -75,4 +79,19 @@ typedef s32 (*SkinOverrideLimbDraw)(struct Actor*, struct PlayState*, s32, Skin*
#define SKIN_TRANSFORM_IS_FHG 0x23
+void Skin_UpdateVertices(MtxF* mtx, SkinVertex* skinVertices, SkinLimbModif* modifEntry, Vtx* vtxBuf, Vec3f* pos);
+void Skin_DrawAnimatedLimb(struct GraphicsContext* gfxCtx, Skin* skin, s32 limbIndex, s32 arg3, s32 drawFlags);
+void Skin_DrawLimb(struct GraphicsContext* gfxCtx, Skin* skin, s32 limbIndex, Gfx* dlistOverride, s32 drawFlags);
+void func_800A6330(struct Actor* actor, struct PlayState* play, Skin* skin, SkinPostDraw postDraw, s32 setTranslation);
+void func_800A6360(struct Actor* actor, struct PlayState* play, Skin* skin, SkinPostDraw postDraw,
+ SkinOverrideLimbDraw overrideLimbDraw, s32 setTranslation);
+void func_800A6394(struct Actor* actor, struct PlayState* play, Skin* skin, SkinPostDraw postDraw,
+ SkinOverrideLimbDraw overrideLimbDraw, s32 setTranslation, s32 arg6);
+void func_800A63CC(struct Actor* actor, struct PlayState* play, Skin* skin, SkinPostDraw postDraw,
+ SkinOverrideLimbDraw overrideLimbDraw, s32 setTranslation, s32 arg6, s32 drawFlags);
+void Skin_GetLimbPos(Skin* skin, s32 limbIndex, Vec3f* offset, Vec3f* dst);
+void Skin_Init(struct PlayState* play, Skin* skin, SkeletonHeader* skeletonHeader, AnimationHeader* animationHeader);
+void Skin_Free(struct PlayState* play, Skin* skin);
+s32 Skin_ApplyAnimTransformations(Skin* skin, MtxF* limbMatrices, struct Actor* actor, s32 setTranslation);
+
#endif
diff --git a/include/z64sram.h b/include/z64sram.h
index 3769f4419..9fcaf83b0 100644
--- a/include/z64sram.h
+++ b/include/z64sram.h
@@ -3,6 +3,10 @@
#include "ultra64/ultratypes.h"
+struct FileSelectState;
+struct GameState;
+struct PlayState;
+
typedef struct SramContext {
/* 0x00 */ u8* readBuff;
} SramContext; // size = 0x4
@@ -12,9 +16,22 @@ typedef struct SramContext {
typedef enum SramHeaderField {
/* 0x00 */ SRAM_HEADER_SOUND,
- /* 0x01 */ SRAM_HEADER_ZTARGET,
+ /* 0x01 */ SRAM_HEADER_Z_TARGET,
/* 0x02 */ SRAM_HEADER_LANGUAGE,
/* 0x03 */ SRAM_HEADER_MAGIC // must be the value in `sSramDefaultHeader` for save to be considered valid
} SramHeaderField;
+void Sram_InitNewSave(void);
+void Sram_InitDebugSave(void);
+void Sram_OpenSave(SramContext* sramCtx);
+void Sram_WriteSave(SramContext* sramCtx);
+void Sram_VerifyAndLoadAllSaves(struct FileSelectState* fileSelect, SramContext* sramCtx);
+void Sram_InitSave(struct FileSelectState* fileSelect, SramContext* sramCtx);
+void Sram_EraseSave(struct FileSelectState* fileSelect, SramContext* sramCtx);
+void Sram_CopySave(struct FileSelectState* fileSelect, SramContext* sramCtx);
+void Sram_WriteSramHeader(SramContext* sramCtx);
+void Sram_InitSram(struct GameState* gameState, SramContext* sramCtx);
+void Sram_Alloc(struct GameState* gameState, SramContext* sramCtx);
+void Sram_Init(struct PlayState* play, SramContext* sramCtx);
+
#endif
diff --git a/include/z64ss_sram.h b/include/z64ss_sram.h
new file mode 100644
index 000000000..ffd628239
--- /dev/null
+++ b/include/z64ss_sram.h
@@ -0,0 +1,12 @@
+#ifndef Z64SS_SRAM_H
+#define Z64SS_SRAM_H
+
+#include "libc/stddef.h"
+#include "ultra64/ultratypes.h"
+
+void SsSram_Init(s32 addr, u8 handleType, u8 handleDomain, u8 handleLatency, u8 handlePageSize, u8 handleRelDuration,
+ u8 handlePulse, u32 handleSpeed);
+void SsSram_Dma(void* dramAddr, size_t size, s32 direction);
+void SsSram_ReadWrite(s32 addr, void* dramAddr, size_t size, s32 direction);
+
+#endif
diff --git a/include/z64thread.h b/include/z64thread.h
new file mode 100644
index 000000000..17ea8a016
--- /dev/null
+++ b/include/z64thread.h
@@ -0,0 +1,43 @@
+#ifndef Z64THREAD_H
+#define Z64THREAD_H
+
+#include "ultra64.h"
+
+#define THREAD_ID_IDLE 1
+#define THREAD_ID_FAULT 2
+#define THREAD_ID_MAIN 3
+#define THREAD_ID_GRAPH 4
+#define THREAD_ID_SCHED 5
+#define THREAD_ID_PADMGR 7
+
+#if ENABLE_PROFILER
+#define THREAD_ID_PIMGR 8
+#define THREAD_ID_VIMGR 9
+#else
+// Not sure why these are zero in vanilla.
+#define THREAD_ID_PIMGR 0
+#define THREAD_ID_VIMGR 0
+#endif
+
+#define THREAD_ID_N64DD 8
+#define THREAD_ID_DDMSG 9
+#define THREAD_ID_AUDIOMGR 10
+#define THREAD_ID_DMAMGR 18
+#define THREAD_ID_IRQMGR 19
+
+#define THREAD_PRI_IDLE_INIT 10
+#define THREAD_PRI_MAIN_INIT 10
+#define THREAD_PRI_DMAMGR_LOW 10 // Used when decompressing files
+#define THREAD_PRI_GRAPH 11
+#define THREAD_PRI_AUDIOMGR 12
+#define THREAD_PRI_N64DD 13
+#define THREAD_PRI_DDMSG 13
+#define THREAD_PRI_PADMGR 14
+#define THREAD_PRI_MAIN 15
+#define THREAD_PRI_SCHED 15
+#define THREAD_PRI_DMAMGR 16
+#define THREAD_PRI_IRQMGR 17
+#define THREAD_PRI_FAULT_CLIENT (OS_PRIORITY_APPMAX - 1)
+#define THREAD_PRI_FAULT OS_PRIORITY_APPMAX
+
+#endif
diff --git a/src/audio/debug.inc.c b/src/audio/debug.inc.c
index 29fbd50a3..a41254001 100644
--- a/src/audio/debug.inc.c
+++ b/src/audio/debug.inc.c
@@ -847,7 +847,7 @@ void AudioDebug_ProcessInput_SndCont(void) {
&gSfxDefaultReverb);
break;
case 4:
- func_800F6700(sAudioSndContWork[sAudioSndContSel]);
+ Audio_SetSoundMode(sAudioSndContWork[sAudioSndContSel]);
break;
case 5:
SEQCMD_DISABLE_PLAY_SEQUENCES(sAudioSndContWork[sAudioSndContSel]);
diff --git a/src/audio/general.c b/src/audio/general.c
index f308eedc3..e4d985d1f 100644
--- a/src/audio/general.c
+++ b/src/audio/general.c
@@ -1,5 +1,7 @@
#include "ultra64.h"
#include "global.h"
+#include "seqcmd.h"
+#include "sequence.h"
#include "versions.h"
#if !PLATFORM_N64
@@ -3767,26 +3769,26 @@ void Audio_SetCodeReverb(s8 reverb) {
}
}
-void func_800F6700(s8 audioSetting) {
+void Audio_SetSoundMode(s8 soundSetting) {
s8 soundModeIndex;
- switch (audioSetting) {
- case 0:
+ switch (soundSetting) {
+ case SOUND_SETTING_STEREO:
soundModeIndex = SOUNDMODE_STEREO;
sSoundMode = SOUNDMODE_STEREO;
break;
- case 1:
+ case SOUND_SETTING_MONO:
soundModeIndex = SOUNDMODE_MONO;
sSoundMode = SOUNDMODE_MONO;
break;
- case 2:
+ case SOUND_SETTING_HEADSET:
soundModeIndex = SOUNDMODE_HEADSET;
sSoundMode = SOUNDMODE_HEADSET;
break;
- case 3:
+ case SOUND_SETTING_SURROUND:
soundModeIndex = SOUNDMODE_STEREO;
sSoundMode = SOUNDMODE_SURROUND;
break;
diff --git a/src/audio/lib/load.c b/src/audio/lib/load.c
index 0aa3324d7..8ecf7f888 100644
--- a/src/audio/lib/load.c
+++ b/src/audio/lib/load.c
@@ -1,7 +1,9 @@
#include "ultra64.h"
-#include "global.h"
+#include "buffers.h"
#include "versions.h"
+#include "global.h"
+
#define MK_ASYNC_MSG(retData, tableType, id, loadStatus) \
(((retData) << 24) | ((tableType) << 16) | ((id) << 8) | (loadStatus))
#define ASYNC_TBLTYPE(v) ((u8)(v >> 16))
diff --git a/src/audio/sequence.c b/src/audio/sequence.c
index 54e768f77..a5180223c 100644
--- a/src/audio/sequence.c
+++ b/src/audio/sequence.c
@@ -20,6 +20,7 @@
#include "ultra64.h"
#include "global.h"
#include "ultra64/abi.h"
+#include "seqcmd.h"
// Direct audio command (skips the queueing system)
#define SEQCMD_SET_SEQPLAYER_VOLUME_NOW(seqPlayerIndex, duration, volume) \
diff --git a/src/audio/session_init.c b/src/audio/session_init.c
index a6e67f40d..d04a955bc 100644
--- a/src/audio/session_init.c
+++ b/src/audio/session_init.c
@@ -1,4 +1,8 @@
+#include "buffers.h"
+#include "z64audio.h"
+
#include "global.h"
+
#include "assets/audio/sequence_sizes.h"
#include "assets/audio/soundfont_sizes.h"
diff --git a/src/boot/boot_main.c b/src/boot/boot_main.c
index 0c1eeea49..4bd5b5bd0 100644
--- a/src/boot/boot_main.c
+++ b/src/boot/boot_main.c
@@ -4,9 +4,9 @@
#if PLATFORM_N64
#include "cic6105.h"
#endif
+#include "z64thread.h"
-#pragma increment_block_number "gc-eu:128 gc-eu-mq:128 gc-jp:128 gc-jp-ce:128 gc-jp-mq:128 gc-us:128 gc-us-mq:128" \
- "ntsc-1.2:128"
+#pragma increment_block_number "gc-eu:0 gc-eu-mq:0 gc-jp:0 gc-jp-ce:0 gc-jp-mq:0 gc-us:0 gc-us-mq:0 ntsc-1.2:128"
StackEntry sBootThreadInfo;
OSThread sIdleThread;
diff --git a/src/boot/cic6105.c b/src/boot/cic6105.c
index 2bb6f474a..6af30844f 100644
--- a/src/boot/cic6105.c
+++ b/src/boot/cic6105.c
@@ -1,4 +1,4 @@
-#pragma increment_block_number "ntsc-1.2:128"
+#pragma increment_block_number "ntsc-1.2:0"
#include "global.h"
#include "cic6105.h"
diff --git a/src/boot/idle.c b/src/boot/idle.c
index c708f4d8c..73e68ab44 100644
--- a/src/boot/idle.c
+++ b/src/boot/idle.c
@@ -1,9 +1,15 @@
-#include "global.h"
+#include "buffers.h"
+#include "segment_symbols.h"
#include "stack.h"
+#include "stackcheck.h"
#include "terminal.h"
#include "versions.h"
+#include "z64thread.h"
-#pragma increment_block_number "gc-eu:64 gc-eu-mq:64 gc-jp:64 gc-jp-ce:64 gc-jp-mq:64 gc-us:64 gc-us-mq:64 ntsc-1.2:64"
+#include "global.h"
+
+#pragma increment_block_number "gc-eu:128 gc-eu-mq:128 gc-jp:128 gc-jp-ce:128 gc-jp-mq:128 gc-us:128 gc-us-mq:128" \
+ "ntsc-1.0:138 ntsc-1.1:138 ntsc-1.2:138 pal-1.0:136 pal-1.1:136"
OSThread sMainThread;
#if OOT_VERSION < PAL_1_0
diff --git a/src/boot/z_std_dma.c b/src/boot/z_std_dma.c
index 30edf7d83..813b4e415 100644
--- a/src/boot/z_std_dma.c
+++ b/src/boot/z_std_dma.c
@@ -18,18 +18,23 @@
* There are some additional provisions to ensure that audio DMA is particularly high-speed, the audio data is assumed
* to be uncompressed and the request queue and address translation is skipped.
*/
-#include "global.h"
+#include "libc64/sleep.h"
#include "fault.h"
-#include "stack.h"
-#include "terminal.h"
#include "compression.h"
#include "line_numbers.h"
#if PLATFORM_N64
#include "n64dd.h"
#endif
+#include "segment_symbols.h"
+#include "stack.h"
+#include "stackcheck.h"
+#include "terminal.h"
+#include "z64thread.h"
+
+#include "global.h"
#pragma increment_block_number "gc-eu:128 gc-eu-mq:128 gc-jp:128 gc-jp-ce:128 gc-jp-mq:128 gc-us:128 gc-us-mq:128" \
- "ntsc-1.2:76 pal-1.0:74 pal-1.1:74"
+ "ntsc-1.2:20 pal-1.0:18 pal-1.1:18"
StackEntry sDmaMgrStackInfo;
OSMesgQueue sDmaMgrMsgQueue;
diff --git a/src/buffers/audio_heap.c b/src/buffers/audio_heap.c
index d0f17ad7a..1a38187df 100644
--- a/src/buffers/audio_heap.c
+++ b/src/buffers/audio_heap.c
@@ -1,4 +1,6 @@
-#include "z64.h"
#include "config.h"
+#include "ultra64/ultratypes.h"
+#include "alignment.h"
+#include "buffers.h"
ALIGNED(16) u8 gAudioHeap[AUDIO_HEAP_SIZE];
diff --git a/src/buffers/gfxbuffers.c b/src/buffers/gfxbuffers.c
index fa466bc82..1806570ae 100644
--- a/src/buffers/gfxbuffers.c
+++ b/src/buffers/gfxbuffers.c
@@ -1,4 +1,7 @@
-#include "z64.h"
+#include "alignment.h"
+#include "buffers.h"
+#include "gfx.h"
+#include "ultra64.h"
ALIGNED(16) u64 gGfxSPTaskOutputBuffer[0x3000];
diff --git a/src/buffers/zbuffer.c b/src/buffers/zbuffer.c
index d9e5d2784..0eda88921 100644
--- a/src/buffers/zbuffer.c
+++ b/src/buffers/zbuffer.c
@@ -1,3 +1,6 @@
-#include "z64.h"
+#include "alignment.h"
+#include "buffers.h"
+#include "macros.h"
+#include "ultra64/ultratypes.h"
ALIGNED(64) u16 gZBuffer[SCREEN_HEIGHT][SCREEN_WIDTH];
diff --git a/src/code/code_n64dd_800AD4C0.c b/src/code/code_n64dd_800AD4C0.c
index 3f1488c66..34dcdb3bb 100644
--- a/src/code/code_n64dd_800AD4C0.c
+++ b/src/code/code_n64dd_800AD4C0.c
@@ -1,6 +1,8 @@
-#include "global.h"
#include "fault.h"
#include "n64dd.h"
+#include "z64save.h"
+
+#include "global.h"
n64ddStruct_800FEE70_pointers D_800FEE70 = {
func_801C7C1C,
diff --git a/src/code/db_camera.c b/src/code/db_camera.c
index a025767d4..afbb82fae 100644
--- a/src/code/db_camera.c
+++ b/src/code/db_camera.c
@@ -1,9 +1,23 @@
-#include "global.h"
-
#include "config.h"
#if IS_CAMERA_DEBUG_ENABLED
+#include "libu64/gfxprint.h"
+#include "attributes.h"
+#include "controller.h"
+#include "debug_arena.h"
+#include "letterbox.h"
+#include "mempak.h"
+#include "regs.h"
+#include "sfx.h"
+#include "z_lib.h"
+#include "z64camera.h"
+#include "z64cutscene.h"
+#include "z64cutscene_spline.h"
+#include "z64debug.h"
#include "z64debug_display.h"
+#include "z64olib.h"
+#include "z64play.h"
+#include "z64save.h"
#define DEBUG_CAM_CONTROLLER_PORT 2
@@ -2371,3 +2385,5 @@ void func_800BB060(void) {
int func_800BB06C(void) {
return sDebugCamPtr->unk_00 == 2 && sDebugCamAnim.unk_0A != 0;
}
+
+#endif
diff --git a/src/code/debug_malloc.c b/src/code/debug_malloc.c
index 8397b28c4..07e078bc7 100644
--- a/src/code/debug_malloc.c
+++ b/src/code/debug_malloc.c
@@ -1,5 +1,7 @@
-#include "global.h"
#include "libc64/os_malloc.h"
+#include "debug_arena.h"
+
+#include "macros.h"
#define LOG_SEVERITY_NOLOG 0
#define LOG_SEVERITY_ERROR 2
diff --git a/src/code/fault_gc.c b/src/code/fault_gc.c
index cb1df9143..6f43a7c4e 100644
--- a/src/code/fault_gc.c
+++ b/src/code/fault_gc.c
@@ -40,14 +40,21 @@
* DPad-Up may be pressed to enable sending fault pages over osSyncPrintf as well as displaying them on-screen.
* DPad-Down disables sending fault pages over osSyncPrintf.
*/
-#pragma increment_block_number "gc-eu:160 gc-eu-mq:160 gc-eu-mq-dbg:144 gc-jp:160 gc-jp-ce:160 gc-jp-mq:160 gc-us:160" \
- "gc-us-mq:160 ique-cn:160"
+#pragma increment_block_number "gc-eu:96 gc-eu-mq:96 gc-eu-mq-dbg:96 gc-jp:112 gc-jp-ce:112 gc-jp-mq:112 gc-us:112" \
+ "gc-us-mq:112 ique-cn:112"
#include "global.h"
+#include "libc64/sleep.h"
+#include "libc64/sprintf.h"
#include "alloca.h"
+#include "controller.h"
#include "fault.h"
#include "stack.h"
+#include "stackcheck.h"
#include "terminal.h"
+#include "z64thread.h"
+
+#include "macros.h"
void Fault_Init(void);
void Fault_SetOsSyncPrintfEnabled(u32 enabled);
diff --git a/src/code/fault_n64.c b/src/code/fault_n64.c
index 720307c0a..ecfc87f10 100644
--- a/src/code/fault_n64.c
+++ b/src/code/fault_n64.c
@@ -1,12 +1,19 @@
-#pragma increment_block_number "ntsc-1.0:0 ntsc-1.1:0 ntsc-1.2:0 pal-1.0:0 pal-1.1:0"
-
-#include "global.h"
-#include "fault.h"
#include "libc64/os_malloc.h"
+#include "libc64/sleep.h"
+#include "libc64/sprintf.h"
+#include "controller.h"
+#include "fault.h"
+#include "padmgr.h"
+#include "segmented_address.h"
#include "stack.h"
+#include "stackcheck.h"
#include "terminal.h"
+#include "z64thread.h"
-#pragma increment_block_number "ntsc-1.0:192 ntsc-1.1:192 ntsc-1.2:192 pal-1.0:192 pal-1.1:192"
+#include "macros.h"
+#include "global.h"
+
+#pragma increment_block_number "ntsc-1.0:128 ntsc-1.1:128 ntsc-1.2:128 pal-1.0:128 pal-1.1:128"
typedef struct FaultMgr {
OSThread thread;
diff --git a/src/code/flg_set.c b/src/code/flg_set.c
index 27c234341..a53ecde74 100644
--- a/src/code/flg_set.c
+++ b/src/code/flg_set.c
@@ -1,4 +1,10 @@
-#include "global.h"
+#include "libu64/gfxprint.h"
+#include "libu64/pad.h"
+#include "gfx.h"
+#include "gfxalloc.h"
+#include "controller.h"
+#include "z64play.h"
+#include "z64save.h"
typedef struct FlagSetEntry {
/* 0x00 */ u16* value;
diff --git a/src/code/game.c b/src/code/game.c
index 175bcf5df..10d21f42d 100644
--- a/src/code/game.c
+++ b/src/code/game.c
@@ -1,12 +1,29 @@
-#include "global.h"
+#include "libu64/debug.h"
+#include "libu64/gfxprint.h"
+#include "audiomgr.h"
+#include "buffers.h"
+#include "controller.h"
+#include "debug_arena.h"
+#include "gfx.h"
+#include "gfxalloc.h"
#include "fault.h"
#include "libc64/os_malloc.h"
-#include "terminal.h"
-#include "versions.h"
#include "line_numbers.h"
#if PLATFORM_N64
#include "n64dd.h"
#endif
+#include "padmgr.h"
+#include "regs.h"
+#include "rumble.h"
+#include "speed_meter.h"
+#include "terminal.h"
+#include "versions.h"
+#include "z64debug.h"
+#include "z64game.h"
+#include "z64vis.h"
+
+#include "macros.h"
+#include "global.h"
VisCvg sVisCvg;
VisZBuf sVisZBuf;
diff --git a/src/code/gamealloc.c b/src/code/gamealloc.c
index d625bc65f..47591fd00 100644
--- a/src/code/gamealloc.c
+++ b/src/code/gamealloc.c
@@ -1,4 +1,8 @@
-#include "global.h"
+#include "libc64/malloc.h"
+#include "libu64/debug.h"
+#include "gamealloc.h"
+
+#include "macros.h"
void GameAlloc_Log(GameAlloc* this) {
GameAllocEntry* iter;
diff --git a/src/code/graph.c b/src/code/graph.c
index 2b4672c06..35357ffb5 100644
--- a/src/code/graph.c
+++ b/src/code/graph.c
@@ -1,15 +1,25 @@
-#include "global.h"
+#include "libc64/malloc.h"
+#include "libc64/sprintf.h"
+#include "libu64/debug.h"
+#include "buffers.h"
+#include "gfx.h"
#include "fault.h"
+#include "line_numbers.h"
+#include "regs.h"
+#include "sys_ucode.h"
#include "terminal.h"
#include "ucode_disas.h"
#include "versions.h"
-#include "line_numbers.h"
+#include "z64save.h"
+
+#include "macros.h"
+#include "global.h"
#define GFXPOOL_HEAD_MAGIC 0x1234
#define GFXPOOL_TAIL_MAGIC 0x5678
-#pragma increment_block_number "gc-eu:0 gc-eu-mq:0 gc-jp:0 gc-jp-ce:0 gc-jp-mq:0 gc-us:0 gc-us-mq:0 ntsc-1.0:160" \
- "ntsc-1.1:160 ntsc-1.2:160 pal-1.0:160 pal-1.1:160"
+#pragma increment_block_number "gc-eu:0 gc-eu-mq:0 gc-jp:0 gc-jp-ce:0 gc-jp-mq:0 gc-us:0 gc-us-mq:0 ntsc-1.0:192" \
+ "ntsc-1.1:192 ntsc-1.2:192 pal-1.0:192 pal-1.1:192"
/**
* The time at which the previous `Graph_Update` ended.
diff --git a/src/code/irqmgr.c b/src/code/irqmgr.c
index 59d7a41cf..b90d5df7b 100644
--- a/src/code/irqmgr.c
+++ b/src/code/irqmgr.c
@@ -35,6 +35,7 @@
#include "global.h"
#include "terminal.h"
#include "versions.h"
+#include "z64thread.h"
vu32 gIrqMgrResetStatus = IRQ_RESET_STATUS_IDLE;
volatile OSTime sIrqMgrResetTime = 0;
diff --git a/src/code/jpegdecoder.c b/src/code/jpegdecoder.c
index a29752511..338c6b15d 100644
--- a/src/code/jpegdecoder.c
+++ b/src/code/jpegdecoder.c
@@ -1,4 +1,4 @@
-#include "global.h"
+#include "jpeg.h"
s32 JpegDecoder_ProcessMcu(JpegHuffmanTable* hTable0, JpegHuffmanTable* hTable1, u16* mcu, s16* unk);
s32 JpegDecoder_ParseNextSymbol(JpegHuffmanTable* hTable, s16* outCoeff, s8* outZeroCount);
diff --git a/src/code/jpegutils.c b/src/code/jpegutils.c
index 00c040609..7f5442fd9 100644
--- a/src/code/jpegutils.c
+++ b/src/code/jpegutils.c
@@ -1,4 +1,4 @@
-#include "global.h"
+#include "jpeg.h"
void JpegUtils_ProcessQuantizationTable(u8* dqt, JpegQuantizationTable* qt, u8 count) {
u8 i;
diff --git a/src/code/main.c b/src/code/main.c
index 2120c16f7..d2feaf499 100644
--- a/src/code/main.c
+++ b/src/code/main.c
@@ -12,7 +12,7 @@ extern struct Scheduler gScheduler;
extern struct PadMgr gPadMgr;
extern struct IrqMgr gIrqMgr;
-#include "global.h"
+#include "debug_arena.h"
#include "fault.h"
#include "segmented_address.h"
#include "stack.h"
@@ -22,9 +22,13 @@ extern struct IrqMgr gIrqMgr;
#include "cic6105.h"
#include "n64dd.h"
#endif
+#include "z64debug.h"
+#include "z64thread.h"
-#pragma increment_block_number "gc-eu:144 gc-eu-mq:144 gc-jp:144 gc-jp-ce:144 gc-jp-mq:144 gc-us:144 gc-us-mq:144" \
- "ique-cn:160 ntsc-1.0:136 ntsc-1.1:136 ntsc-1.2:136 pal-1.0:134 pal-1.1:134"
+#include "global.h"
+
+#pragma increment_block_number "gc-eu:96 gc-eu-mq:96 gc-jp:96 gc-jp-ce:96 gc-jp-mq:96 gc-us:96 gc-us-mq:96 ique-cn:96" \
+ "ntsc-1.0:79 ntsc-1.1:79 ntsc-1.2:79 pal-1.0:77 pal-1.1:77"
extern u8 _buffersSegmentEnd[];
diff --git a/src/code/padmgr.c b/src/code/padmgr.c
index 740f15b29..9e6d1ae14 100644
--- a/src/code/padmgr.c
+++ b/src/code/padmgr.c
@@ -31,6 +31,7 @@
#include "libu64/debug.h"
#include "libu64/padsetup.h"
#include "macros.h"
+#include "padmgr.h"
#include "fault.h"
#include "terminal.h"
#include "line_numbers.h"
diff --git a/src/code/sched.c b/src/code/sched.c
index fd82aa3d3..284e13df1 100644
--- a/src/code/sched.c
+++ b/src/code/sched.c
@@ -39,9 +39,15 @@
*
* @see irqmgr.c
*/
-#include "global.h"
+#include "libu64/debug.h"
#include "fault.h"
+#include "irqmgr.h"
+#include "regs.h"
+#include "sched.h"
#include "versions.h"
+#include "z64thread.h"
+
+#include "global.h"
#define RSP_DONE_MSG 667
#define RDP_DONE_MSG 668
diff --git a/src/code/sys_math3d_draw.c b/src/code/sys_math3d_draw.c
index bc2197fa1..5fc9ac7b3 100644
--- a/src/code/sys_math3d_draw.c
+++ b/src/code/sys_math3d_draw.c
@@ -1,5 +1,7 @@
-#include "z64.h"
-#include "functions.h"
+#include "sys_math3d.h"
+#include "z64play.h"
+#include "gfx.h"
+#include "sys_matrix.h"
#if DEBUG_FEATURES
void Math3D_VtxF2L(Vtx* r, Vec3f* v) {
diff --git a/src/code/sys_matrix.c b/src/code/sys_matrix.c
index 9e56d4088..081a29276 100644
--- a/src/code/sys_matrix.c
+++ b/src/code/sys_matrix.c
@@ -1,7 +1,14 @@
-#include "global.h"
+#include "libc64/math64.h"
+#include "gfx.h"
#if DEBUG_FEATURES
#include "fault.h"
#endif
+#include "macros.h"
+#include "sys_matrix.h"
+#include "ultra64.h"
+#include "z_lib.h"
+#include "z64game.h"
+#include "z64skin_matrix.h"
// clang-format off
Mtx gIdentityMtx = gdSPDefMtx(
@@ -19,9 +26,6 @@ MtxF gIdentityMtxF = {
};
// clang-format on
-#pragma increment_block_number "gc-eu:128 gc-eu-mq:128 gc-jp:128 gc-jp-ce:128 gc-jp-mq:128 gc-us:128 gc-us-mq:128" \
- "pal-1.1:128"
-
MtxF* sMatrixStack; // "Matrix_stack"
MtxF* sCurrentMatrix; // "Matrix_now"
diff --git a/src/code/sys_ucode.c b/src/code/sys_ucode.c
index 5ced4d38d..3e2291393 100644
--- a/src/code/sys_ucode.c
+++ b/src/code/sys_ucode.c
@@ -1,5 +1,6 @@
-#include "global.h"
#include "fault.h"
+#include "ultra64.h"
+#include "segment_symbols.h"
#if !ENABLE_F3DEX3
u64* sDefaultGSPUCodeText = gspF3DZEX2_NoN_PosLight_fifoTextStart;
diff --git a/src/code/ucode_disas.c b/src/code/ucode_disas.c
index 9cba821c8..64c602ece 100644
--- a/src/code/ucode_disas.c
+++ b/src/code/ucode_disas.c
@@ -1,5 +1,10 @@
-#include "global.h"
#include "ucode_disas.h"
+#include "ultra64.h"
+#include "ultra64/gs2dex.h"
+#include "libu64/mtxuty-cvt.h"
+#include "segmented_address.h"
+
+#include "macros.h"
#if DEBUG_FEATURES
diff --git a/src/code/z_actor.c b/src/code/z_actor.c
index 572d7a73f..42efb8787 100644
--- a/src/code/z_actor.c
+++ b/src/code/z_actor.c
@@ -1,14 +1,32 @@
-#include "global.h"
+#include "libc64/math64.h"
#include "fault.h"
+#include "gfx.h"
+#include "gfx_setupdl.h"
#include "quake.h"
#include "rand.h"
+#include "regs.h"
+#include "rumble.h"
+#include "segmented_address.h"
+#include "sfx.h"
+#include "sys_math.h"
+#include "sys_matrix.h"
#include "terminal.h"
#include "versions.h"
+#include "z_lib.h"
+#include "zelda_arena.h"
+#include "z64effect.h"
+#include "z64light.h"
#include "z64horse.h"
+#include "z64play.h"
+#include "z64save.h"
+#include "z64skin_matrix.h"
#include "config.h"
+#include "global.h"
+
#include "overlays/actors/ovl_Arms_Hook/z_arms_hook.h"
#include "overlays/actors/ovl_En_Part/z_en_part.h"
+
#include "assets/objects/gameplay_keep/gameplay_keep.h"
#include "assets/objects/gameplay_dangeon_keep/gameplay_dangeon_keep.h"
#include "assets/objects/object_bdoor/object_bdoor.h"
@@ -2853,7 +2871,20 @@ s32 Actor_CullingVolumeTest(PlayState* play, Actor* actor, Vec3f* projPos, f32 p
return false;
}
-void func_800315AC(PlayState* play, ActorContext* actorCtx) {
+/**
+ * Iterates through all category lists to draw every actor.
+ *
+ * In addition to actors, this function also draws:
+ * - Effects
+ * - EffectSs
+ * - Title Cards
+ * - Farores Wind Pointer
+ * - Light glow
+ * - Actor Collision (debug only)
+ *
+ * Note: If an actor is made visible by Lens of Truth, it will be drawn by `Actor_DrawLensActors` instead.
+ */
+void Actor_DrawAll(PlayState* play, ActorContext* actorCtx) {
s32 invisibleActorCounter;
Actor* invisibleActors[INVISIBLE_ACTOR_MAX];
ActorListEntry* actorListEntry;
diff --git a/src/code/z_bgcheck.c b/src/code/z_bgcheck.c
index 6620d9ddf..b0a5abf48 100644
--- a/src/code/z_bgcheck.c
+++ b/src/code/z_bgcheck.c
@@ -1,8 +1,17 @@
-#include "global.h"
-#include "terminal.h"
+#include "libu64/debug.h"
+#include "attributes.h"
#include "line_numbers.h"
+#include "regs.h"
+#include "segmented_address.h"
+#include "sys_math3d.h"
+#include "terminal.h"
+#include "z_lib.h"
+#include "z64bgcheck.h"
+#include "z64play.h"
+#include "z64player.h"
+#include "z64skin_matrix.h"
-#pragma increment_block_number "ntsc-1.0:120 ntsc-1.1:120 ntsc-1.2:120"
+#pragma increment_block_number "ntsc-1.0:184 ntsc-1.1:184 ntsc-1.2:184"
u16 DynaSSNodeList_GetNextNodeIdx(DynaSSNodeList* nodeList);
void BgCheck_GetStaticLookupIndicesFromPos(CollisionContext* colCtx, Vec3f* pos, Vec3i* sector);
diff --git a/src/code/z_camera.c b/src/code/z_camera.c
index 9a8dd89ac..4546f59d9 100644
--- a/src/code/z_camera.c
+++ b/src/code/z_camera.c
@@ -1,12 +1,15 @@
#include "ultra64.h"
-#include "global.h"
#include "quake.h"
#include "terminal.h"
+#include "z64cutscene_spline.h"
+#include "z64debug.h"
+#include "z64olib.h"
+#include "z64save.h"
#include "overlays/actors/ovl_En_Horse/z_en_horse.h"
#include "config.h"
#pragma increment_block_number "gc-eu:192 gc-eu-mq:192 gc-jp:192 gc-jp-ce:192 gc-jp-mq:192 gc-us:192 gc-us-mq:192" \
- "ique-cn:192 ntsc-1.0:128 ntsc-1.1:128 ntsc-1.2:128 pal-1.0:128 pal-1.1:128"
+ "ique-cn:192 ntsc-1.0:192 ntsc-1.1:192 ntsc-1.2:192 pal-1.0:192 pal-1.1:192"
s16 Camera_RequestSettingImpl(Camera* camera, s16 requestedSetting, s16 flags);
s32 Camera_RequestModeImpl(Camera* camera, s16 requestedMode, u8 forceModeChange);
@@ -3637,7 +3640,7 @@ s32 Camera_KeepOn3(Camera* camera) {
}
#pragma increment_block_number "gc-eu:128 gc-eu-mq:128 gc-jp:128 gc-jp-ce:128 gc-jp-mq:128 gc-us:128 gc-us-mq:128" \
- "ique-cn:128 ntsc-1.0:138 ntsc-1.1:138 ntsc-1.2:138 pal-1.0:136 pal-1.1:136"
+ "ique-cn:128 ntsc-1.0:118 ntsc-1.1:118 ntsc-1.2:118 pal-1.0:116 pal-1.1:116"
s32 Camera_KeepOn4(Camera* camera) {
static Vec3f D_8015BD50;
@@ -7552,7 +7555,7 @@ void Camera_Init(Camera* camera, View* view, CollisionContext* colCtx, PlayState
sDbgModeIdx = -1;
#endif
- D_8011D3F0 = 3;
+ sSceneInitLetterboxTimer = 3; // show letterbox for 3 frames at the start of a new scene
PRINTF(VT_FGCOL(BLUE) "camera: initialize --- " VT_RST " UID %d\n", camera->uid);
}
@@ -8166,15 +8169,15 @@ Vec3s Camera_Update(Camera* camera) {
Camera_CalcAtDefault(camera, &eyeAtAngle, 0.0f, false);
}
- if (D_8011D3F0 != 0) {
- D_8011D3F0--;
+ if (sSceneInitLetterboxTimer != 0) {
+ sSceneInitLetterboxTimer--;
}
if (camera->status == CAM_STAT_ACTIVE) {
if ((gSaveContext.gameMode != GAMEMODE_NORMAL) && (gSaveContext.gameMode != GAMEMODE_END_CREDITS)) {
sCameraInterfaceField = CAM_INTERFACE_FIELD(CAM_LETTERBOX_NONE, CAM_HUD_VISIBILITY_ALL, 0);
Camera_UpdateInterface(sCameraInterfaceField);
- } else if ((D_8011D3F0 != 0) && (camera->camId == CAM_ID_MAIN)) {
+ } else if ((sSceneInitLetterboxTimer != 0) && (camera->camId == CAM_ID_MAIN)) {
sCameraInterfaceField = CAM_INTERFACE_FIELD(CAM_LETTERBOX_LARGE, CAM_HUD_VISIBILITY_NOTHING_ALT, 0);
Camera_UpdateInterface(sCameraInterfaceField);
} else if ((camera->play->transitionMode != TRANS_MODE_OFF) && (camera->camId != CAM_ID_MAIN)) {
diff --git a/src/code/z_camera_data.inc.c b/src/code/z_camera_data.inc.c
index 2c796631e..ff550572d 100644
--- a/src/code/z_camera_data.inc.c
+++ b/src/code/z_camera_data.inc.c
@@ -2609,7 +2609,7 @@ s16 D_8011D3CC[] = {
s32 sUpdateCameraDirection = 0;
s32 D_8011D3EC = 0;
-s32 D_8011D3F0 = 0;
+s32 sSceneInitLetterboxTimer = 0;
s32 sDemo5PrevAction12Frame = -16;
diff --git a/src/code/z_collision_check.c b/src/code/z_collision_check.c
index f284964ae..154d83af1 100644
--- a/src/code/z_collision_check.c
+++ b/src/code/z_collision_check.c
@@ -15,8 +15,7 @@
#include "overlays/effects/ovl_Effect_Ss_HitMark/z_eff_ss_hitmark.h"
#include "z_lib.h"
-#pragma increment_block_number "gc-eu:128 gc-eu-mq:128 gc-jp:128 gc-jp-ce:128 gc-jp-mq:128 gc-us:128 gc-us-mq:128" \
- "ique-cn:128 ntsc-1.0:104 ntsc-1.1:104 ntsc-1.2:104 pal-1.0:104 pal-1.1:104"
+#pragma increment_block_number "ique-cn:0 ntsc-1.0:232 ntsc-1.1:232 ntsc-1.2:232 pal-1.0:232 pal-1.1:232"
typedef s32 (*ColChkResetFunc)(PlayState*, Collider*);
typedef void (*ColChkApplyFunc)(PlayState*, CollisionCheckContext*, Collider*);
diff --git a/src/code/z_common_data.c b/src/code/z_common_data.c
index 74d570e29..d9077faef 100644
--- a/src/code/z_common_data.c
+++ b/src/code/z_common_data.c
@@ -1,9 +1,14 @@
-#include "global.h"
#include "region.h"
+#include "sequence.h"
#include "versions.h"
+#include "z64environment.h"
+#include "z64save.h"
+#include "z64transition.h"
-#pragma increment_block_number "gc-eu:128 gc-eu-mq:128 gc-jp:128 gc-jp-ce:128 gc-jp-mq:128 gc-us:128 gc-us-mq:128" \
- "ntsc-1.0:176 ntsc-1.1:176 ntsc-1.2:176 pal-1.0:192 pal-1.1:192"
+#include "global.h"
+
+#pragma increment_block_number "gc-eu:0 gc-eu-mq:0 gc-jp:0 gc-jp-ce:0 gc-jp-mq:0 gc-us:0 gc-us-mq:0 ntsc-1.0:176" \
+ "ntsc-1.1:176 ntsc-1.2:176 pal-1.0:192 pal-1.1:192"
ALIGNED(16) SaveContext gSaveContext;
#if PLATFORM_IQUE
diff --git a/src/code/z_construct.c b/src/code/z_construct.c
index fa0f4a38d..4696cb76e 100644
--- a/src/code/z_construct.c
+++ b/src/code/z_construct.c
@@ -1,5 +1,12 @@
-#include "global.h"
+#include "map.h"
+#include "regs.h"
+#include "segment_symbols.h"
#include "versions.h"
+#include "z64lifemeter.h"
+#include "z64interface.h"
+#include "z64ocarina.h"
+#include "z64play.h"
+#include "z64save.h"
void Interface_Destroy(PlayState* play) {
Map_Destroy(play);
diff --git a/src/code/z_cutscene_spline.c b/src/code/z_cutscene_spline.c
index 421f9a280..d95b2ca7f 100644
--- a/src/code/z_cutscene_spline.c
+++ b/src/code/z_cutscene_spline.c
@@ -1,4 +1,8 @@
-#include "global.h"
+#include "ultra64.h"
+#include "z64math.h"
+#include "z64camera.h"
+#include "z64cutscene_spline.h"
+#include "macros.h"
// The code in this file is very similar to a spline system used in Super Mario 64 for cutscene camera movement
diff --git a/src/code/z_debug.c b/src/code/z_debug.c
index affc761f3..544b931ae 100644
--- a/src/code/z_debug.c
+++ b/src/code/z_debug.c
@@ -1,5 +1,17 @@
-#include "global.h"
#include "config.h"
+#include "libc64/malloc.h"
+#include "libu64/gfxprint.h"
+#include "libu64/pad.h"
+#include "color.h"
+#include "controller.h"
+#include "gfx.h"
+#include "gfxalloc.h"
+#include "regs.h"
+#include "rumble.h"
+#include "ultra64.h"
+#include "z64debug.h"
+
+#include "macros.h"
// ENABLE_CAMERA_DEBUGGER
typedef struct DebugCamTextBufferEntry {
@@ -16,7 +28,7 @@ typedef struct InputCombo {
} InputCombo; // size = 0x4
#pragma increment_block_number "gc-eu:160 gc-eu-mq:160 gc-jp:160 gc-jp-ce:160 gc-jp-mq:160 gc-us:160 gc-us-mq:160" \
- "ique-cn:128 ntsc-1.0:160 ntsc-1.1:160 ntsc-1.2:160 pal-1.0:160 pal-1.1:160"
+ "ique-cn:160 ntsc-1.0:160 ntsc-1.1:160 ntsc-1.2:160 pal-1.0:160 pal-1.1:160"
RegEditor* gRegEditor; // ``gRegEditor->data`` is used by non-debug features in normal gameplay
diff --git a/src/code/z_demo.c b/src/code/z_demo.c
index dc1eb49bd..1a569bed9 100644
--- a/src/code/z_demo.c
+++ b/src/code/z_demo.c
@@ -1,12 +1,31 @@
-#pragma increment_block_number "gc-eu:128 gc-eu-mq:128 gc-jp:128 gc-jp-ce:128 gc-jp-mq:128 gc-us:128 gc-us-mq:128" \
- "ntsc-1.0:128 ntsc-1.1:128 ntsc-1.2:128 pal-1.0:128 pal-1.1:128"
+#pragma increment_block_number "gc-eu:0 gc-eu-mq:0 gc-jp:0 gc-jp-ce:0 gc-jp-mq:0 gc-us:0 gc-us-mq:0 ique-cn:0" \
+ "ntsc-1.0:0 ntsc-1.1:0 ntsc-1.2:0 pal-1.0:0 pal-1.1:0"
#include "global.h"
-#include "quake.h"
-#include "z64camera.h"
+
#include "config.h"
+#include "libu64/gfxprint.h"
+#include "controller.h"
+#include "gfx.h"
+#include "gfxalloc.h"
+#include "letterbox.h"
#if PLATFORM_N64
#include "n64dd.h"
#endif
+#include "regs.h"
+#include "rumble.h"
+#include "quake.h"
+#include "segmented_address.h"
+#include "seqcmd.h"
+#include "sequence.h"
+#include "sfx.h"
+#include "z_lib.h"
+#include "z64audio.h"
+#include "z64camera.h"
+#include "z64cutscene.h"
+#include "z64cutscene_flags.h"
+#include "z64play.h"
+#include "z64player.h"
+#include "z64save.h"
#include "assets/scenes/indoors/tokinoma/tokinoma_scene.h"
@@ -131,8 +150,8 @@ u16 gCamAtSplinePointsAppliedFrame;
u16 gCamEyePointAppliedFrame;
u16 gCamAtPointAppliedFrame;
-#pragma increment_block_number "gc-eu:0 gc-eu-mq:0 gc-jp:188 gc-jp-ce:188 gc-jp-mq:0 gc-us:188 gc-us-mq:0" \
- "ntsc-1.0:128 ntsc-1.1:80 ntsc-1.2:80 pal-1.0:80 pal-1.1:80"
+#pragma increment_block_number "gc-eu:128 gc-eu-mq:128 gc-jp:128 gc-jp-ce:128 gc-jp-mq:128 gc-us:128 gc-us-mq:128" \
+ "ique-cn:128 ntsc-1.0:0 ntsc-1.1:0 ntsc-1.2:0 pal-1.0:0 pal-1.1:0"
// Cam ID to return to when a scripted cutscene is finished
s16 sReturnToCamId;
diff --git a/src/code/z_elf_message.c b/src/code/z_elf_message.c
index c90b4ee6f..7b3cf1c55 100644
--- a/src/code/z_elf_message.c
+++ b/src/code/z_elf_message.c
@@ -1,5 +1,9 @@
-#include "global.h"
+#include "libu64/debug.h"
+#include "rand.h"
+#include "z64play.h"
+#include "z64player.h"
#include "z64quest_hint_commands.h"
+#include "z64save.h"
QuestHintCmd sChildSariaQuestHints[] = {
QUEST_HINT_STRENGTH_UPG(SKIP, 0, false, 3),
diff --git a/src/code/z_en_item00.c b/src/code/z_en_item00.c
index a81804a5b..e7c25063d 100644
--- a/src/code/z_en_item00.c
+++ b/src/code/z_en_item00.c
@@ -17,6 +17,7 @@
#include "z64item.h"
#include "z64play.h"
#include "z64player.h"
+#include "z64save.h"
#include "assets/objects/gameplay_keep/gameplay_keep.h"
diff --git a/src/code/z_env_flags.c b/src/code/z_env_flags.c
index d277a5f75..9ad7e7a02 100644
--- a/src/code/z_env_flags.c
+++ b/src/code/z_env_flags.c
@@ -1,4 +1,5 @@
#include "ultra64.h"
+#include "z64cutscene_flags.h"
#include "z64play.h"
void CutsceneFlags_UnsetAll(PlayState* play) {
diff --git a/src/code/z_face_reaction.c b/src/code/z_face_reaction.c
index 9864944b1..ea6313a76 100644
--- a/src/code/z_face_reaction.c
+++ b/src/code/z_face_reaction.c
@@ -1,4 +1,6 @@
-#include "global.h"
+#include "ultra64.h"
+#include "z64face_reaction.h"
+#include "z64player.h"
u16 sMaskReactionSetTextIds[MASK_REACTION_SET_MAX][PLAYER_MASK_MAX] = {
// MASK_REACTION_SET_CARPENTER_BOSS
@@ -182,7 +184,7 @@ u16 sMaskReactionSetTextIds[MASK_REACTION_SET_MAX][PLAYER_MASK_MAX] = {
{ 0x0000, 0x7104, 0x7105, 0x7107, 0x7105, 0x710C, 0x7105, 0x7107, 0x7107 },
};
-u16 MaskReaction_GetTextId(PlayState* play, u32 maskReactionSet) {
+u16 MaskReaction_GetTextId(struct PlayState* play, u32 maskReactionSet) {
u8 currentMask = Player_GetMask(play);
return sMaskReactionSetTextIds[maskReactionSet][currentMask];
diff --git a/src/code/z_fbdemo_fade.c b/src/code/z_fbdemo_fade.c
index d2cb382f0..3375628cb 100644
--- a/src/code/z_fbdemo_fade.c
+++ b/src/code/z_fbdemo_fade.c
@@ -1,5 +1,12 @@
-#include "global.h"
+#include "ultra64.h"
+#include "main.h"
+#include "regs.h"
#include "terminal.h"
+#include "z_lib.h"
+#include "z64save.h"
+#include "z64transition_instances.h"
+
+#include "macros.h"
typedef enum TransitionFadeDirection {
/* 0 */ TRANS_FADE_DIR_IN,
diff --git a/src/code/z_fbdemo_wipe1.c b/src/code/z_fbdemo_wipe1.c
index 7b92249b7..b8ee9883f 100644
--- a/src/code/z_fbdemo_wipe1.c
+++ b/src/code/z_fbdemo_wipe1.c
@@ -1,4 +1,6 @@
-#include "global.h"
+#include "gfx.h"
+#include "z64save.h"
+#include "z64transition_instances.h"
typedef enum TransitionWipeDirection {
/* 0 */ TRANS_WIPE_DIR_IN,
diff --git a/src/code/z_frame_advance.c b/src/code/z_frame_advance.c
index 0e593ff6f..d6c0801b8 100644
--- a/src/code/z_frame_advance.c
+++ b/src/code/z_frame_advance.c
@@ -3,7 +3,7 @@
#include "stdbool.h"
#include "controller.h"
-#include "padmgr.h"
+#include "libu64/pad.h"
#include "macros.h"
void FrameAdvance_Init(FrameAdvanceContext* frameAdvCtx) {
diff --git a/src/code/z_game_over.c b/src/code/z_game_over.c
index f0390a961..20814a4c7 100644
--- a/src/code/z_game_over.c
+++ b/src/code/z_game_over.c
@@ -1,7 +1,14 @@
-#include "z64game_over.h"
-
-#include "global.h"
+#include "letterbox.h"
+#include "regs.h"
+#include "rumble.h"
+#include "sequence.h"
#include "versions.h"
+#include "z64game_over.h"
+#include "z64play.h"
+#include "z64save.h"
+
+#include "macros.h"
+#include "global.h"
void GameOver_Init(PlayState* play) {
play->gameOverCtx.state = GAMEOVER_INACTIVE;
diff --git a/src/code/z_horse.c b/src/code/z_horse.c
index f6f55c9d0..800f72c73 100644
--- a/src/code/z_horse.c
+++ b/src/code/z_horse.c
@@ -4,7 +4,8 @@
#include "z64horse.h"
#include "z64play.h"
#include "z64player.h"
-#include "src/overlays/actors/ovl_En_Horse/z_en_horse.h"
+#include "z64save.h"
+#include "overlays/actors/ovl_En_Horse/z_en_horse.h"
/**
* Tests if the player horse can be spawned
diff --git a/src/code/z_inventory.c b/src/code/z_inventory.c
index 2f89c0565..bb4bb5f85 100644
--- a/src/code/z_inventory.c
+++ b/src/code/z_inventory.c
@@ -1,4 +1,8 @@
-#include "global.h"
+#include "ultra64.h"
+#include "z64play.h"
+#include "z64player.h"
+#include "z64save.h"
+
#include "assets/textures/icon_item_static/icon_item_static.h"
#include "assets/textures/icon_item_24_static/icon_item_24_static.h"
#include "assets/textures/parameter_static/parameter_static.h"
diff --git a/src/code/z_jpeg.c b/src/code/z_jpeg.c
index 86a97183a..81e299946 100644
--- a/src/code/z_jpeg.c
+++ b/src/code/z_jpeg.c
@@ -1,6 +1,12 @@
#include "global.h"
+#include "ultra64.h"
+#include "attributes.h"
+#include "jpeg.h"
+#include "sys_ucode.h"
#include "terminal.h"
+#include "macros.h"
+
#define MARKER_ESCAPE 0x00
#define MARKER_SOI 0xD8
#define MARKER_SOF 0xC0
diff --git a/src/code/z_kaleido_scope_call.c b/src/code/z_kaleido_scope_call.c
index 9983b9b32..f1017342a 100644
--- a/src/code/z_kaleido_scope_call.c
+++ b/src/code/z_kaleido_scope_call.c
@@ -1,8 +1,14 @@
-#pragma increment_block_number "gc-eu:192 gc-eu-mq:192 gc-jp:192 gc-jp-ce:192 gc-jp-mq:192 gc-us:192 gc-us-mq:192" \
- "ique-cn:192 ntsc-1.0:224 ntsc-1.1:224 ntsc-1.2:224 pal-1.0:224 pal-1.1:224"
+#pragma increment_block_number "gc-eu:160 gc-eu-mq:160 gc-jp:160 gc-jp-ce:160 gc-jp-mq:160 gc-us:160 gc-us-mq:160" \
+ "ique-cn:160 ntsc-1.0:160 ntsc-1.1:160 ntsc-1.2:160 pal-1.0:160 pal-1.1:160"
+
+#include "libu64/debug.h"
+#include "kaleido_manager.h"
+#include "letterbox.h"
+#include "regs.h"
+#include "terminal.h"
+#include "z64play.h"
#include "global.h"
-#include "terminal.h"
void (*sKaleidoScopeUpdateFunc)(PlayState* play);
void (*sKaleidoScopeDrawFunc)(PlayState* play);
diff --git a/src/code/z_kaleido_setup.c b/src/code/z_kaleido_setup.c
index 86d725642..68f6f5251 100644
--- a/src/code/z_kaleido_setup.c
+++ b/src/code/z_kaleido_setup.c
@@ -1,7 +1,12 @@
-#include "global.h"
+#include "controller.h"
+#include "letterbox.h"
#if PLATFORM_N64
#include "n64dd.h"
#endif
+#include "regs.h"
+#include "z64audio.h"
+#include "z64play.h"
+#include "z64save.h"
/*
* The following three arrays are effectively unused.
diff --git a/src/code/z_kanfont.c b/src/code/z_kanfont.c
index fa038276f..21ba416b3 100644
--- a/src/code/z_kanfont.c
+++ b/src/code/z_kanfont.c
@@ -1,6 +1,12 @@
-#include "global.h"
+#include "kanread.h"
#include "message_data_static.h"
+#include "segment_symbols.h"
#include "versions.h"
+#include "z64dma.h"
+#include "z64font.h"
+#include "z64message.h"
+
+#include "macros.h"
/**
* Loads a texture from kanji for the requested `character` into the character texture buffer
diff --git a/src/code/z_kankyo.c b/src/code/z_kankyo.c
index 290aaf54a..fd864e8fd 100644
--- a/src/code/z_kankyo.c
+++ b/src/code/z_kankyo.c
@@ -1,12 +1,33 @@
-#pragma increment_block_number "gc-eu:224 gc-eu-mq:224 gc-jp:208 gc-jp-ce:208 gc-jp-mq:208 gc-us:208 gc-us-mq:208" \
- "ique-cn:208 ntsc-1.0:208 ntsc-1.1:208 ntsc-1.2:208 pal-1.0:232 pal-1.1:232"
+#pragma increment_block_number "gc-eu:64 gc-eu-mq:64 gc-jp:0 gc-jp-ce:0 gc-jp-mq:0 gc-us:0 gc-us-mq:0 ique-cn:0" \
+ "ntsc-1.0:0 ntsc-1.1:0 ntsc-1.2:0 pal-1.0:64 pal-1.1:64"
-#include "global.h"
+#include "libc64/qrand.h"
+#include "libu64/gfxprint.h"
+#include "buffers.h"
+#include "gfx.h"
+#include "gfx_setupdl.h"
+#include "gfxalloc.h"
#include "ultra64.h"
+#include "regs.h"
+#include "rumble.h"
+#include "segment_symbols.h"
+#include "segmented_address.h"
+#include "seqcmd.h"
+#include "sequence.h"
+#include "sfx.h"
+#include "sys_math.h"
+#include "sys_math3d.h"
+#include "sys_matrix.h"
#include "terminal.h"
#include "versions.h"
-
+#include "z_lib.h"
+#include "z64audio.h"
+#include "z64cutscene.h"
#include "z64frame_advance.h"
+#include "z64environment.h"
+#include "z64play.h"
+#include "z64player.h"
+#include "z64save.h"
#include "assets/objects/gameplay_keep/gameplay_keep.h"
#include "assets/objects/gameplay_field_keep/gameplay_field_keep.h"
@@ -214,8 +235,8 @@ s16 sLightningFlashAlpha;
s16 sSunDepthTestX;
s16 sSunDepthTestY;
-#pragma increment_block_number "gc-eu:240 gc-eu-mq:240 gc-jp:224 gc-jp-ce:224 gc-jp-mq:224 gc-us:224 gc-us-mq:224" \
- "ique-cn:224 ntsc-1.0:224 ntsc-1.1:224 ntsc-1.2:224 pal-1.0:240 pal-1.1:240"
+#pragma increment_block_number "gc-eu:160 gc-eu-mq:160 gc-jp:128 gc-jp-ce:128 gc-jp-mq:128 gc-us:128 gc-us-mq:128" \
+ "ique-cn:128 ntsc-1.0:128 ntsc-1.1:128 ntsc-1.2:128 pal-1.0:192 pal-1.1:192"
LightNode* sNGameOverLightNode;
LightInfo sNGameOverLightInfo;
diff --git a/src/code/z_lifemeter.c b/src/code/z_lifemeter.c
index 950bcad80..970e18982 100644
--- a/src/code/z_lifemeter.c
+++ b/src/code/z_lifemeter.c
@@ -1,4 +1,13 @@
-#include "global.h"
+#include "gfx.h"
+#include "gfx_setupdl.h"
+#include "sfx.h"
+#include "sys_matrix.h"
+#include "z_lib.h"
+#include "z64lifemeter.h"
+#include "z64play.h"
+#include "z64player.h"
+#include "z64save.h"
+
#include "assets/textures/parameter_static/parameter_static.h"
static s16 sHeartsPrimColors[3][3] = {
diff --git a/src/code/z_lights.c b/src/code/z_lights.c
index 5ca9855b0..136ec27dc 100644
--- a/src/code/z_lights.c
+++ b/src/code/z_lights.c
@@ -1,4 +1,10 @@
-#include "global.h"
+#include "buffers.h"
+#include "gfx.h"
+#include "gfx_setupdl.h"
+#include "sys_matrix.h"
+#include "z64light.h"
+#include "z64play.h"
+
#include "assets/objects/gameplay_keep/gameplay_keep.h"
#define LIGHTS_BUFFER_SIZE 32
diff --git a/src/code/z_map_data.c b/src/code/z_map_data.c
index 0a9c9e637..ada54ba02 100644
--- a/src/code/z_map_data.c
+++ b/src/code/z_map_data.c
@@ -1,4 +1,5 @@
-#include "global.h"
+#include "map.h"
+#include "z64save.h"
static s16 sFloorTexIndexOffset[10][8] = {
{ 0, 0, 0, 0, 2, 4, 6, 8 }, { 0, 0, 0, 0, 0, 0, 0, 2 },
diff --git a/src/code/z_map_exp.c b/src/code/z_map_exp.c
index 487922366..59040a521 100644
--- a/src/code/z_map_exp.c
+++ b/src/code/z_map_exp.c
@@ -1,10 +1,22 @@
-#include "global.h"
-#include "terminal.h"
-#include "assets/objects/gameplay_keep/gameplay_keep.h"
-#include "assets/textures/parameter_static/parameter_static.h"
+#include "gfx.h"
+#include "gfx_setupdl.h"
+#include "controller.h"
+#include "map.h"
#if PLATFORM_N64
#include "n64dd.h"
#endif
+#include "regs.h"
+#include "sfx.h"
+#include "sys_matrix.h"
+#include "terminal.h"
+#include "z64play.h"
+#include "z64player.h"
+#include "z64save.h"
+
+#include "global.h"
+
+#include "assets/objects/gameplay_keep/gameplay_keep.h"
+#include "assets/textures/parameter_static/parameter_static.h"
MapData* gMapData;
diff --git a/src/code/z_map_mark.c b/src/code/z_map_mark.c
index fe7c9f75c..72b2f1081 100644
--- a/src/code/z_map_mark.c
+++ b/src/code/z_map_mark.c
@@ -1,9 +1,17 @@
-#include "global.h"
+#include "libu64/debug.h"
+#include "regs.h"
+#include "romfile.h"
+#include "segment_symbols.h"
#include "terminal.h"
#include "assets/textures/parameter_static/parameter_static.h"
#if PLATFORM_N64
#include "n64dd.h"
#endif
+#include "z64map_mark.h"
+#include "z64play.h"
+#include "z64save.h"
+
+#include "global.h"
typedef struct MapMarkInfo {
/* 0x00 */ void* texture;
diff --git a/src/code/z_message.c b/src/code/z_message.c
index e83c2728d..63e1fd796 100644
--- a/src/code/z_message.c
+++ b/src/code/z_message.c
@@ -1,14 +1,30 @@
-#include "global.h"
+#include "libu64/gfxprint.h"
+#include "attributes.h"
+#include "controller.h"
+#include "gfx.h"
+#include "gfx_setupdl.h"
+#include "gfxalloc.h"
#include "message_data_static.h"
-#include "terminal.h"
-#include "versions.h"
-#include "assets/textures/parameter_static/parameter_static.h"
#if PLATFORM_N64
#include "n64dd.h"
#endif
+#include "segment_symbols.h"
+#include "sequence.h"
+#include "regs.h"
+#include "terminal.h"
+#include "versions.h"
+#include "z64audio.h"
+#include "z64ocarina.h"
+#include "z64play.h"
+#include "z64player.h"
+#include "z64save.h"
+
+#include "global.h"
+
+#include "assets/textures/parameter_static/parameter_static.h"
#pragma increment_block_number "gc-eu:0 gc-eu-mq:0 gc-jp:128 gc-jp-ce:128 gc-jp-mq:128 gc-us:128 gc-us-mq:128" \
- "ntsc-1.0:80 ntsc-1.1:80 ntsc-1.2:80 pal-1.0:128 pal-1.1:128"
+ "ntsc-1.0:144 ntsc-1.1:144 ntsc-1.2:144 pal-1.0:128 pal-1.1:128"
#if !PLATFORM_IQUE
#define MSG_BUF_DECODED (msgCtx->msgBufDecoded)
diff --git a/src/code/z_nulltask.c b/src/code/z_nulltask.c
index 1f7dae689..42ba3d86f 100644
--- a/src/code/z_nulltask.c
+++ b/src/code/z_nulltask.c
@@ -1,4 +1,5 @@
-#include "global.h"
+#include "ultra64.h"
+#include "sched.h"
/**
* Blocks the current thread until all queued scheduler tasks have completed.
diff --git a/src/code/z_onepointdemo.c b/src/code/z_onepointdemo.c
index 04ffc2f46..6a4c896ac 100644
--- a/src/code/z_onepointdemo.c
+++ b/src/code/z_onepointdemo.c
@@ -1,7 +1,15 @@
-#include "global.h"
+#include "libc64/math64.h"
+#include "libc64/qrand.h"
+#include "one_point_cutscene.h"
#include "quake.h"
+#include "sfx.h"
#include "terminal.h"
#include "versions.h"
+#include "z_lib.h"
+#include "z64olib.h"
+#include "z64play.h"
+#include "z64player.h"
+#include "z64save.h"
#include "overlays/actors/ovl_En_Sw/z_en_sw.h"
static s16 sDisableAttention = false;
diff --git a/src/code/z_parameter.c b/src/code/z_parameter.c
index 6f7b6c8c2..5054790d8 100644
--- a/src/code/z_parameter.c
+++ b/src/code/z_parameter.c
@@ -1,7 +1,27 @@
-#include "global.h"
+#include "attributes.h"
+#include "controller.h"
+#include "gfx.h"
+#include "gfx_setupdl.h"
+#include "main.h"
+#include "map.h"
+#include "regs.h"
+#include "segment_symbols.h"
+#include "segmented_address.h"
+#include "sequence.h"
+#include "sfx.h"
+#include "sys_matrix.h"
#include "terminal.h"
#include "versions.h"
+#include "z64audio.h"
+#include "z64lifemeter.h"
#include "z64horse.h"
+#include "z64ocarina.h"
+#include "z64play.h"
+#include "z64player.h"
+#include "z64save.h"
+
+#include "global.h"
+
#include "assets/textures/parameter_static/parameter_static.h"
#include "assets/textures/do_action_static/do_action_static.h"
#include "assets/textures/icon_item_static/icon_item_static.h"
diff --git a/src/code/z_path.c b/src/code/z_path.c
index d27530eb3..29b51a8f1 100644
--- a/src/code/z_path.c
+++ b/src/code/z_path.c
@@ -1,4 +1,9 @@
-#include "global.h"
+#include "ultra64.h"
+#include "libc64/math64.h"
+#include "segmented_address.h"
+#include "z64actor.h"
+#include "z64path.h"
+#include "z64play.h"
Path* Path_GetByIndex(PlayState* play, s16 index, s16 max) {
Path* path;
diff --git a/src/code/z_play.c b/src/code/z_play.c
index da9775711..65bd20226 100644
--- a/src/code/z_play.c
+++ b/src/code/z_play.c
@@ -1,24 +1,46 @@
-
-#include "global.h"
+#include "libu64/debug.h"
+#include "buffers.h"
+#include "controller.h"
#include "fault.h"
-#include "quake.h"
-#include "terminal.h"
#include "config.h"
-#include "versions.h"
+#include "gfx.h"
+#include "gfxalloc.h"
+#include "kaleido_manager.h"
+#include "letterbox.h"
#include "line_numbers.h"
#if PLATFORM_N64
#include "n64dd.h"
#endif
-
+#include "one_point_cutscene.h"
+#include "quake.h"
+#include "regs.h"
+#include "rumble.h"
+#include "segmented_address.h"
+#include "sequence.h"
+#include "sfx.h"
+#include "sys_math3d.h"
+#include "sys_matrix.h"
+#include "terminal.h"
+#include "versions.h"
+#include "zelda_arena.h"
+#include "z64cutscene_flags.h"
#include "z64debug_display.h"
+#include "z64effect.h"
#include "z64frame_advance.h"
#include "z64camera.h"
+#include "z64light.h"
+#include "z64play.h"
+#include "z64player.h"
+#include "z64save.h"
#if CAN_INCLUDE_EXAMPLE_SCENE
#include "assets/scenes/example/example_scene.h"
#endif
-#pragma increment_block_number "gc-eu:128 gc-eu-mq:128 gc-jp:128 gc-jp-ce:128 gc-jp-mq:128 gc-us:128 gc-us-mq:128"
+#include "global.h"
+
+#pragma increment_block_number "gc-eu:128 gc-eu-mq:128 gc-jp:128 gc-jp-ce:128 gc-jp-mq:128 gc-us:128 gc-us-mq:128" \
+ "ique-cn:192 ntsc-1.0:96 ntsc-1.1:96 ntsc-1.2:96 pal-1.0:96 pal-1.1:96"
TransitionTile gTransitionTile;
s32 gTransitionTileState;
@@ -1549,7 +1571,7 @@ void Play_Draw(PlayState* this) {
}
if (!DEBUG_FEATURES || (R_HREG_MODE != HREG_MODE_PLAY) || R_PLAY_DRAW_ACTORS) {
- func_800315AC(this, &this->actorCtx);
+ Actor_DrawAll(this, &this->actorCtx);
}
if (!DEBUG_FEATURES || (R_HREG_MODE != HREG_MODE_PLAY) || R_PLAY_DRAW_LENS_FLARES) {
diff --git a/src/code/z_player_call.c b/src/code/z_player_call.c
index b922f5663..2874522df 100644
--- a/src/code/z_player_call.c
+++ b/src/code/z_player_call.c
@@ -4,7 +4,7 @@
(ACTOR_FLAG_ATTENTION_ENABLED | ACTOR_FLAG_HOSTILE | ACTOR_FLAG_UPDATE_CULLING_DISABLED | \
ACTOR_FLAG_DRAW_CULLING_DISABLED | ACTOR_FLAG_UPDATE_DURING_OCARINA | ACTOR_FLAG_CAN_PRESS_SWITCHES)
-#pragma increment_block_number "gc-eu:128 gc-eu-mq:128 gc-jp:128 gc-jp-ce:128 gc-jp-mq:128 gc-us:128 gc-us-mq:128" \
+#pragma increment_block_number "gc-eu:0 gc-eu-mq:0 gc-jp:128 gc-jp-ce:128 gc-jp-mq:128 gc-us:128 gc-us-mq:128" \
"ntsc-1.2:128 pal-1.1:128"
void (*sPlayerCallInitFunc)(Actor* thisx, PlayState* play);
diff --git a/src/code/z_player_lib.c b/src/code/z_player_lib.c
index 86b97c750..705f1bbcb 100644
--- a/src/code/z_player_lib.c
+++ b/src/code/z_player_lib.c
@@ -1,13 +1,25 @@
-#include "global.h"
+#include "libc64/math64.h"
+#include "gfx.h"
+#include "gfx_setupdl.h"
+#include "regs.h"
+#include "segmented_address.h"
+#include "sys_matrix.h"
#include "versions.h"
+#include "z_lib.h"
#include "z64draw.h"
+#include "z64effect.h"
+#include "z64play.h"
+#include "z64player.h"
+#include "z64save.h"
+#include "z64skin_matrix.h"
#include "assets/objects/gameplay_keep/gameplay_keep.h"
#include "assets/objects/object_link_boy/object_link_boy.h"
#include "assets/objects/object_link_child/object_link_child.h"
#include "config.h"
-#pragma increment_block_number "gc-eu:0 gc-eu-mq:0 gc-jp:128 gc-jp-ce:128 gc-jp-mq:128 gc-us:128 gc-us-mq:128"
+#pragma increment_block_number "gc-eu:0 gc-eu-mq:0 gc-jp:128 gc-jp-ce:128 gc-jp-mq:128 gc-us:128 gc-us-mq:128" \
+ "pal-1.0:0 pal-1.1:0"
typedef struct BowSlingshotStringData {
/* 0x00 */ Gfx* dList;
diff --git a/src/code/z_quake.c b/src/code/z_quake.c
index 4c318b938..2e83a7c10 100644
--- a/src/code/z_quake.c
+++ b/src/code/z_quake.c
@@ -1,6 +1,10 @@
-#include "global.h"
+#include "libc64/qrand.h"
+#include "macros.h"
#include "quake.h"
#include "terminal.h"
+#include "z_lib.h"
+#include "z64olib.h"
+#include "z64play.h"
typedef struct QuakeRequest {
/* 0x00 */ s16 index;
diff --git a/src/code/z_rcp.c b/src/code/z_rcp.c
index 0b4217eac..d84b84f95 100644
--- a/src/code/z_rcp.c
+++ b/src/code/z_rcp.c
@@ -1,3 +1,11 @@
+#include "buffers.h"
+#include "gfx.h"
+#include "gfx_setupdl.h"
+#include "gfxalloc.h"
+#include "letterbox.h"
+#include "regs.h"
+#include "z64play.h"
+
#include "global.h"
#if ENABLE_F3DEX3
diff --git a/src/code/z_room.c b/src/code/z_room.c
index e2202248e..09f9a18b0 100644
--- a/src/code/z_room.c
+++ b/src/code/z_room.c
@@ -1,11 +1,27 @@
-#include "global.h"
+#include "libu64/debug.h"
+#include "ultra64/gs2dex.h"
+#include "buffers.h"
#include "fault.h"
-#include "terminal.h"
-#include "versions.h"
+#include "gfx.h"
+#include "gfx_setupdl.h"
+#include "jpeg.h"
#include "line_numbers.h"
+#include "map.h"
#if PLATFORM_N64
#include "n64dd.h"
#endif
+#include "regs.h"
+#include "segmented_address.h"
+#include "sys_matrix.h"
+#include "sys_ucode.h"
+#include "terminal.h"
+#include "versions.h"
+#include "z64audio.h"
+#include "z64play.h"
+#include "z64player.h"
+#include "z64room.h"
+#include "z64save.h"
+#include "z64skin_matrix.h"
Vec3f D_801270A0 = { 0.0f, 0.0f, 0.0f };
diff --git a/src/code/z_scene.c b/src/code/z_scene.c
index b124cde67..382b51c96 100644
--- a/src/code/z_scene.c
+++ b/src/code/z_scene.c
@@ -1,6 +1,8 @@
#include "global.h"
+#include "seqcmd.h"
#include "terminal.h"
#include "versions.h"
+#include "z64save.h"
SceneCmdHandlerFunc sSceneCmdHandlers[SCENE_CMD_ID_MAX];
RomFile sNaviQuestHintFiles[];
diff --git a/src/code/z_scene_table.c b/src/code/z_scene_table.c
index bcdffb2f2..35fe7e59e 100644
--- a/src/code/z_scene_table.c
+++ b/src/code/z_scene_table.c
@@ -1,12 +1,22 @@
-#include "global.h"
-#include "quake.h"
-#include "versions.h"
-#include "z64frame_advance.h"
-#include "animated_materials.h"
#include "config.h"
+#include "libc64/qrand.h"
+#include "gfx.h"
#if PLATFORM_N64
#include "n64dd.h"
#endif
+#include "quake.h"
+#include "regs.h"
+#include "segment_symbols.h"
+#include "segmented_address.h"
+#include "sfx.h"
+#include "sys_matrix.h"
+#include "versions.h"
+#include "z_lib.h"
+#include "z64frame_advance.h"
+#include "z64play.h"
+#include "z64player.h"
+#include "z64save.h"
+#include "animated_materials.h"
#include "assets/scenes/indoors/miharigoya/miharigoya_scene.h"
#include "assets/scenes/indoors/souko/souko_scene.h"
diff --git a/src/code/z_skin.c b/src/code/z_skin.c
index 4ba0f6cb4..508943cdd 100644
--- a/src/code/z_skin.c
+++ b/src/code/z_skin.c
@@ -1,4 +1,10 @@
-#include "global.h"
+#include "gfx.h"
+#include "segmented_address.h"
+#include "sys_matrix.h"
+#include "z64math.h"
+#include "z64play.h"
+#include "z64skin.h"
+#include "z64skin_matrix.h"
#pragma increment_block_number "gc-eu:128 gc-eu-mq:128 gc-jp:128 gc-jp-ce:128 gc-jp-mq:128 gc-us:128 gc-us-mq:128" \
"pal-1.1:128"
diff --git a/src/code/z_skin_awb.c b/src/code/z_skin_awb.c
index 55633bc87..8a175ed15 100644
--- a/src/code/z_skin_awb.c
+++ b/src/code/z_skin_awb.c
@@ -1,5 +1,10 @@
-#include "global.h"
#include "overlays/actors/ovl_En_fHG/z_en_fhg.h"
+#include "segmented_address.h"
+#include "zelda_arena.h"
+#include "z64actor.h"
+#include "z64play.h"
+#include "z64skin.h"
+#include "z64skin_matrix.h"
/**
* Initialises the Vtx buffers used for limb at index `limbIndex`
diff --git a/src/code/z_sram.c b/src/code/z_sram.c
index 3292bd849..ee7743b5e 100644
--- a/src/code/z_sram.c
+++ b/src/code/z_sram.c
@@ -1,6 +1,8 @@
#include "global.h"
#include "terminal.h"
#include "versions.h"
+#include "z64save.h"
+#include "z64ss_sram.h"
#define SLOT_SIZE (sizeof(SaveContext) + 0x28)
#define CHECKSUM_SIZE (sizeof(Save) / 2)
@@ -52,10 +54,13 @@ u16 gSramSlotOffsets[] = {
};
static u8 sSramDefaultHeader[] = {
- // TODO: use enums for these
- 0, // SRAM_HEADER_SOUND
- 0, // SRAM_HEADER_ZTARGET
- 0, // SRAM_HEADER_LANGUAGE
+ SOUND_SETTING_STEREO, // SRAM_HEADER_SOUND
+ Z_TARGET_SETTING_SWITCH, // SRAM_HEADER_Z_TARGET
+#if OOT_NTSC
+ LANGUAGE_JPN, // SRAM_HEADER_LANGUAGE
+#else
+ LANGUAGE_ENG, // SRAM_HEADER_LANGUAGE
+#endif
// SRAM_HEADER_MAGIC
0x98,
@@ -1016,8 +1021,8 @@ void Sram_InitSram(GameState* gameState, SramContext* sramCtx) {
}
}
- gSaveContext.audioSetting = sramCtx->readBuff[SRAM_HEADER_SOUND] & 3;
- gSaveContext.zTargetSetting = sramCtx->readBuff[SRAM_HEADER_ZTARGET] & 1;
+ gSaveContext.soundSetting = sramCtx->readBuff[SRAM_HEADER_SOUND] & 3;
+ gSaveContext.zTargetSetting = sramCtx->readBuff[SRAM_HEADER_Z_TARGET] & 1;
#if OOT_PAL
gSaveContext.language = sramCtx->readBuff[SRAM_HEADER_LANGUAGE];
@@ -1042,11 +1047,11 @@ void Sram_InitSram(GameState* gameState, SramContext* sramCtx) {
PRINTF(T("GOOD!GOOD! サイズ=%d + %d = %d\n", "GOOD! GOOD! Size = %d + %d = %d\n"), sizeof(SaveInfo), 4,
sizeof(SaveInfo) + 4);
PRINTF_COLOR_BLUE();
- PRINTF("Na_SetSoundOutputMode = %d\n", gSaveContext.audioSetting);
- PRINTF("Na_SetSoundOutputMode = %d\n", gSaveContext.audioSetting);
- PRINTF("Na_SetSoundOutputMode = %d\n", gSaveContext.audioSetting);
+ PRINTF("Na_SetSoundOutputMode = %d\n", gSaveContext.soundSetting);
+ PRINTF("Na_SetSoundOutputMode = %d\n", gSaveContext.soundSetting);
+ PRINTF("Na_SetSoundOutputMode = %d\n", gSaveContext.soundSetting);
PRINTF_RST();
- func_800F6700(gSaveContext.audioSetting);
+ Audio_SetSoundMode(gSaveContext.soundSetting);
}
void Sram_Alloc(GameState* gameState, SramContext* sramCtx) {
diff --git a/src/code/z_ss_sram.c b/src/code/z_ss_sram.c
index dd26d695c..c2b7e2d34 100644
--- a/src/code/z_ss_sram.c
+++ b/src/code/z_ss_sram.c
@@ -1,4 +1,6 @@
#include "ultra64.h"
+
+#include "macros.h"
#include "global.h"
typedef struct SsSramContext {
diff --git a/src/code/z_vr_box.c b/src/code/z_vr_box.c
index 224674af9..b04fe86a5 100644
--- a/src/code/z_vr_box.c
+++ b/src/code/z_vr_box.c
@@ -1,6 +1,7 @@
#include "global.h"
#include "terminal.h"
#include "z64environment.h"
+#include "z64save.h"
typedef struct SkyboxFaceParams {
/* 0x000 */ s32 xStart;
diff --git a/src/compression/yaz0.c b/src/compression/yaz0.c
index 8d9517081..cc4d6a17a 100644
--- a/src/compression/yaz0.c
+++ b/src/compression/yaz0.c
@@ -1,8 +1,8 @@
#include "global.h"
#include "compression.h"
-#pragma increment_block_number "gc-eu:128 gc-eu-mq:128 gc-jp:128 gc-jp-ce:128 gc-jp-mq:128 gc-us:128 gc-us-mq:128" \
- "ntsc-1.2:128 pal-1.1:128"
+#pragma increment_block_number "gc-eu:0 gc-eu-mq:0 gc-jp:0 gc-jp-ce:0 gc-jp-mq:0 gc-us:0 gc-us-mq:0 ntsc-1.2:128" \
+ "pal-1.1:128"
ALIGNED(16) u8 sYaz0DataBuffer[0x400];
u8* sYaz0DataBufferEnd;
diff --git a/src/elf_message/elf_message_field.c b/src/elf_message/elf_message_field.c
index 505649afd..8c672ad50 100644
--- a/src/elf_message/elf_message_field.c
+++ b/src/elf_message/elf_message_field.c
@@ -1,5 +1,5 @@
-#include "global.h"
#include "z64quest_hint_commands.h"
+#include "z64save.h"
QuestHintCmd gOverworldNaviQuestHints[] = {
QUEST_HINT_FLAG(CHECK, EVENTCHKINF_05, false, 0x40),
diff --git a/src/elf_message/elf_message_ydan.c b/src/elf_message/elf_message_ydan.c
index 21b5fe89f..cde6410b2 100644
--- a/src/elf_message/elf_message_ydan.c
+++ b/src/elf_message/elf_message_ydan.c
@@ -1,4 +1,3 @@
-#include "global.h"
#include "z64quest_hint_commands.h"
QuestHintCmd gDungeonNaviQuestHints[] = {
diff --git a/src/libu64/mtxuty-cvt.c b/src/libu64/mtxuty-cvt.c
index 10f88f782..759c686d9 100644
--- a/src/libu64/mtxuty-cvt.c
+++ b/src/libu64/mtxuty-cvt.c
@@ -1,4 +1,6 @@
-#include "global.h"
+#include "ultra64.h"
+#include "libu64/debug.h"
+#include "libu64/mtxuty-cvt.h"
void MtxConv_F2L(Mtx* m1, MtxF* m2) {
s32 i;
diff --git a/src/libultra/mgu/normalize.s b/src/libultra/mgu/normalize.s
index 8174527f2..d94748bce 100644
--- a/src/libultra/mgu/normalize.s
+++ b/src/libultra/mgu/normalize.s
@@ -8,20 +8,24 @@ LEAF(guNormalize)
lwc1 ft0, (a0)
lwc1 ft1, (a1)
lwc1 ft2, (a2)
+.set noreorder
mul.s ft3, ft0, ft0
li.s t0, 1.0
mul.s ft4, ft1, ft1
add.s ft5, ft3, ft4
mul.s ft4, ft2, ft2
+.set reorder
add.s ft3, ft4, ft5
mtc1 t0, ft5
sqrt.s ft4, ft3
div.s ft3, ft5, ft4
+.set noreorder
mul.s ft4, ft0, ft3
nop
mul.s ft5, ft1, ft3
nop
mul.s ft0, ft2, ft3
+.set reorder
swc1 ft4, (a0)
swc1 ft5, (a1)
swc1 ft0, (a2)
diff --git a/src/n64dd/z_n64dd.c b/src/n64dd/z_n64dd.c
index 3524cd348..864b67d82 100644
--- a/src/n64dd/z_n64dd.c
+++ b/src/n64dd/z_n64dd.c
@@ -6,8 +6,9 @@
#include "stack.h"
#include "versions.h"
#include "line_numbers.h"
+#include "z64thread.h"
-#pragma increment_block_number "ntsc-1.0:128 ntsc-1.1:128 ntsc-1.2:128 pal-1.0:128 pal-1.1:128"
+#pragma increment_block_number "ntsc-1.0:64 ntsc-1.1:64 ntsc-1.2:64 pal-1.0:64 pal-1.1:64"
typedef struct struct_801D9C30 {
/* 0x000 */ s32 unk_000; // disk start
diff --git a/src/overlays/actors/ovl_Arrow_Fire/z_arrow_fire.c b/src/overlays/actors/ovl_Arrow_Fire/z_arrow_fire.c
index 67268e9e8..a92c22611 100644
--- a/src/overlays/actors/ovl_Arrow_Fire/z_arrow_fire.c
+++ b/src/overlays/actors/ovl_Arrow_Fire/z_arrow_fire.c
@@ -16,8 +16,6 @@
#include "z_lib.h"
#include "z64play.h"
-#include "z64.h"
-
#define FLAGS (ACTOR_FLAG_UPDATE_CULLING_DISABLED | ACTOR_FLAG_UPDATE_DURING_OCARINA)
void ArrowFire_Init(Actor* thisx, PlayState* play);
diff --git a/src/overlays/actors/ovl_Arrow_Ice/z_arrow_ice.c b/src/overlays/actors/ovl_Arrow_Ice/z_arrow_ice.c
index e84af1d7b..953e0a333 100644
--- a/src/overlays/actors/ovl_Arrow_Ice/z_arrow_ice.c
+++ b/src/overlays/actors/ovl_Arrow_Ice/z_arrow_ice.c
@@ -16,8 +16,6 @@
#include "z_lib.h"
#include "z64play.h"
-#include "z64.h"
-
#define FLAGS (ACTOR_FLAG_UPDATE_CULLING_DISABLED | ACTOR_FLAG_UPDATE_DURING_OCARINA)
void ArrowIce_Init(Actor* thisx, PlayState* play);
diff --git a/src/overlays/actors/ovl_Arrow_Light/z_arrow_light.c b/src/overlays/actors/ovl_Arrow_Light/z_arrow_light.c
index 4f3f5572e..100b8c20c 100644
--- a/src/overlays/actors/ovl_Arrow_Light/z_arrow_light.c
+++ b/src/overlays/actors/ovl_Arrow_Light/z_arrow_light.c
@@ -16,8 +16,6 @@
#include "z_lib.h"
#include "z64play.h"
-#include "z64.h"
-
#define FLAGS (ACTOR_FLAG_UPDATE_CULLING_DISABLED | ACTOR_FLAG_UPDATE_DURING_OCARINA)
void ArrowLight_Init(Actor* thisx, PlayState* play);
diff --git a/src/overlays/actors/ovl_Bg_Bdan_Objects/z_bg_bdan_objects.c b/src/overlays/actors/ovl_Bg_Bdan_Objects/z_bg_bdan_objects.c
index 2548f33e1..c92746556 100644
--- a/src/overlays/actors/ovl_Bg_Bdan_Objects/z_bg_bdan_objects.c
+++ b/src/overlays/actors/ovl_Bg_Bdan_Objects/z_bg_bdan_objects.c
@@ -16,6 +16,7 @@
#include "z64audio.h"
#include "z64play.h"
#include "z64player.h"
+#include "z64save.h"
#include "assets/objects/object_bdan_objects/object_bdan_objects.h"
diff --git a/src/overlays/actors/ovl_Bg_Breakwall/z_bg_breakwall.c b/src/overlays/actors/ovl_Bg_Breakwall/z_bg_breakwall.c
index e03e1f629..f36d251f4 100644
--- a/src/overlays/actors/ovl_Bg_Breakwall/z_bg_breakwall.c
+++ b/src/overlays/actors/ovl_Bg_Breakwall/z_bg_breakwall.c
@@ -17,6 +17,7 @@
#include "z_lib.h"
#include "z64play.h"
#include "z64player.h"
+#include "z64save.h"
#include "assets/scenes/dungeons/ddan/ddan_scene.h"
#include "assets/objects/object_bwall/object_bwall.h"
diff --git a/src/overlays/actors/ovl_Bg_Dodoago/z_bg_dodoago.c b/src/overlays/actors/ovl_Bg_Dodoago/z_bg_dodoago.c
index d202bd9ab..bf421ecd9 100644
--- a/src/overlays/actors/ovl_Bg_Dodoago/z_bg_dodoago.c
+++ b/src/overlays/actors/ovl_Bg_Dodoago/z_bg_dodoago.c
@@ -20,6 +20,7 @@
#include "z_lib.h"
#include "z64effect.h"
#include "z64play.h"
+#include "z64save.h"
#include "assets/objects/object_ddan_objects/object_ddan_objects.h"
@@ -140,12 +141,12 @@ void BgDodoago_Init(Actor* thisx, PlayState* play) {
return;
}
- Collider_InitCylinder(play, &this->colliderMain);
- Collider_InitCylinder(play, &this->colliderLeft);
- Collider_InitCylinder(play, &this->colliderRight);
- Collider_SetCylinder(play, &this->colliderMain, &this->dyna.actor, &sColCylinderInitMain);
- Collider_SetCylinder(play, &this->colliderLeft, &this->dyna.actor, &sColCylinderInitLeftRight);
- Collider_SetCylinder(play, &this->colliderRight, &this->dyna.actor, &sColCylinderInitLeftRight);
+ Collider_InitCylinder(play, &this->mainCollider);
+ Collider_InitCylinder(play, &this->leftCollider);
+ Collider_InitCylinder(play, &this->rightCollider);
+ Collider_SetCylinder(play, &this->mainCollider, &this->dyna.actor, &sColCylinderInitMain);
+ Collider_SetCylinder(play, &this->leftCollider, &this->dyna.actor, &sColCylinderInitLeftRight);
+ Collider_SetCylinder(play, &this->rightCollider, &this->dyna.actor, &sColCylinderInitLeftRight);
BgDodoago_SetupAction(this, BgDodoago_WaitExplosives);
sDisableBombCatcher = false;
@@ -155,13 +156,13 @@ void BgDodoago_Destroy(Actor* thisx, PlayState* play) {
BgDodoago* this = (BgDodoago*)thisx;
DynaPoly_DeleteBgActor(play, &play->colCtx.dyna, this->dyna.bgId);
- Collider_DestroyCylinder(play, &this->colliderMain);
- Collider_DestroyCylinder(play, &this->colliderLeft);
- Collider_DestroyCylinder(play, &this->colliderRight);
+ Collider_DestroyCylinder(play, &this->mainCollider);
+ Collider_DestroyCylinder(play, &this->leftCollider);
+ Collider_DestroyCylinder(play, &this->rightCollider);
}
void BgDodoago_WaitExplosives(BgDodoago* this, PlayState* play) {
- Actor* explosive = Actor_GetCollidedExplosive(play, &this->colliderMain.base);
+ Actor* explosive = Actor_GetCollidedExplosive(play, &this->mainCollider.base);
if (explosive != NULL) {
this->state =
@@ -198,21 +199,21 @@ void BgDodoago_WaitExplosives(BgDodoago* this, PlayState* play) {
sTimer = 50;
}
} else if (Flags_GetEventChkInf(EVENTCHKINF_B0)) {
- Collider_UpdateCylinder(&this->dyna.actor, &this->colliderMain);
- Collider_UpdateCylinder(&this->dyna.actor, &this->colliderLeft);
- Collider_UpdateCylinder(&this->dyna.actor, &this->colliderRight);
+ Collider_UpdateCylinder(&this->dyna.actor, &this->mainCollider);
+ Collider_UpdateCylinder(&this->dyna.actor, &this->leftCollider);
+ Collider_UpdateCylinder(&this->dyna.actor, &this->rightCollider);
- this->colliderMain.dim.pos.z += 200;
+ this->mainCollider.dim.pos.z += 200;
- this->colliderLeft.dim.pos.z += 215;
- this->colliderLeft.dim.pos.x += 90;
+ this->leftCollider.dim.pos.z += 215;
+ this->leftCollider.dim.pos.x += 90;
- this->colliderRight.dim.pos.z += 215;
- this->colliderRight.dim.pos.x -= 90;
+ this->rightCollider.dim.pos.z += 215;
+ this->rightCollider.dim.pos.x -= 90;
- CollisionCheck_SetAC(play, &play->colChkCtx, &this->colliderMain.base);
- CollisionCheck_SetOC(play, &play->colChkCtx, &this->colliderLeft.base);
- CollisionCheck_SetOC(play, &play->colChkCtx, &this->colliderRight.base);
+ CollisionCheck_SetAC(play, &play->colChkCtx, &this->mainCollider.base);
+ CollisionCheck_SetOC(play, &play->colChkCtx, &this->leftCollider.base);
+ CollisionCheck_SetOC(play, &play->colChkCtx, &this->rightCollider.base);
}
}
@@ -290,15 +291,15 @@ void BgDodoago_Update(Actor* thisx, PlayState* play) {
if (this->dyna.actor.parent == NULL) {
// this is a "bomb catcher", it kills the XZ speed and sets the timer for bombs that are dropped through the
// holes in the bridge above the skull
- if ((this->colliderLeft.base.ocFlags1 & OC1_HIT) || (this->colliderRight.base.ocFlags1 & OC1_HIT)) {
+ if ((this->leftCollider.base.ocFlags1 & OC1_HIT) || (this->rightCollider.base.ocFlags1 & OC1_HIT)) {
- if (this->colliderLeft.base.ocFlags1 & OC1_HIT) {
- actor = this->colliderLeft.base.oc;
+ if (this->leftCollider.base.ocFlags1 & OC1_HIT) {
+ actor = this->leftCollider.base.oc;
} else {
- actor = this->colliderRight.base.oc;
+ actor = this->rightCollider.base.oc;
}
- this->colliderLeft.base.ocFlags1 &= ~OC1_HIT;
- this->colliderRight.base.ocFlags1 &= ~OC1_HIT;
+ this->leftCollider.base.ocFlags1 &= ~OC1_HIT;
+ this->rightCollider.base.ocFlags1 &= ~OC1_HIT;
if (actor->category == ACTORCAT_EXPLOSIVE && actor->id == ACTOR_EN_BOM && actor->params == 0) {
bomb = (EnBom*)actor;
diff --git a/src/overlays/actors/ovl_Bg_Dodoago/z_bg_dodoago.h b/src/overlays/actors/ovl_Bg_Dodoago/z_bg_dodoago.h
index c767ed500..9f361a3cc 100644
--- a/src/overlays/actors/ovl_Bg_Dodoago/z_bg_dodoago.h
+++ b/src/overlays/actors/ovl_Bg_Dodoago/z_bg_dodoago.h
@@ -16,9 +16,9 @@ typedef void (*BgDodoagoActionFunc)(struct BgDodoago*, struct PlayState*);
typedef struct BgDodoago {
/* 0x0000 */ DynaPolyActor dyna;
/* 0x0164 */ s16 state; // BgDodoagoEye or a timer-like value
- /* 0x0168 */ ColliderCylinder colliderMain; // Used to detect explosions for lighting the eyes
- /* 0x01B4 */ ColliderCylinder colliderLeft; // OC-colliding bombs have their xz speed cleared and timer set
- /* 0x0200 */ ColliderCylinder colliderRight; // same as colliderLeft
+ /* 0x0168 */ ColliderCylinder mainCollider; // Used to detect explosions for lighting the eyes
+ /* 0x01B4 */ ColliderCylinder leftCollider; // OC-colliding bombs have their xz speed cleared and timer set
+ /* 0x0200 */ ColliderCylinder rightCollider; // same as colliderLeft
/* 0x024C */ BgDodoagoActionFunc actionFunc;
} BgDodoago; // size = 0x0250
diff --git a/src/overlays/actors/ovl_Bg_Dy_Yoseizo/z_bg_dy_yoseizo.c b/src/overlays/actors/ovl_Bg_Dy_Yoseizo/z_bg_dy_yoseizo.c
index b20e6fc16..eb35f5249 100644
--- a/src/overlays/actors/ovl_Bg_Dy_Yoseizo/z_bg_dy_yoseizo.c
+++ b/src/overlays/actors/ovl_Bg_Dy_Yoseizo/z_bg_dy_yoseizo.c
@@ -22,6 +22,7 @@
#include "z64ocarina.h"
#include "z64play.h"
#include "z64player.h"
+#include "z64save.h"
#include "assets/objects/object_dy_obj/object_dy_obj.h"
#include "assets/scenes/indoors/yousei_izumi_yoko/yousei_izumi_yoko_scene.h"
diff --git a/src/overlays/actors/ovl_Bg_Gate_Shutter/z_bg_gate_shutter.c b/src/overlays/actors/ovl_Bg_Gate_Shutter/z_bg_gate_shutter.c
index c4811a1d5..9385ed95b 100644
--- a/src/overlays/actors/ovl_Bg_Gate_Shutter/z_bg_gate_shutter.c
+++ b/src/overlays/actors/ovl_Bg_Gate_Shutter/z_bg_gate_shutter.c
@@ -13,6 +13,7 @@
#include "terminal.h"
#include "z_lib.h"
#include "z64play.h"
+#include "z64save.h"
#include "assets/objects/object_spot01_matoyab/object_spot01_matoyab.h"
diff --git a/src/overlays/actors/ovl_Bg_Gjyo_Bridge/z_bg_gjyo_bridge.c b/src/overlays/actors/ovl_Bg_Gjyo_Bridge/z_bg_gjyo_bridge.c
index a4a64c201..6c0f01b32 100644
--- a/src/overlays/actors/ovl_Bg_Gjyo_Bridge/z_bg_gjyo_bridge.c
+++ b/src/overlays/actors/ovl_Bg_Gjyo_Bridge/z_bg_gjyo_bridge.c
@@ -13,6 +13,7 @@
#include "sys_matrix.h"
#include "z64play.h"
#include "z64player.h"
+#include "z64save.h"
#include "assets/objects/object_gjyo_objects/object_gjyo_objects.h"
#include "assets/scenes/overworld/ganon_tou/ganon_tou_scene.h"
diff --git a/src/overlays/actors/ovl_Bg_Haka/z_bg_haka.c b/src/overlays/actors/ovl_Bg_Haka/z_bg_haka.c
index 6e0b045a8..f20af0b9f 100644
--- a/src/overlays/actors/ovl_Bg_Haka/z_bg_haka.c
+++ b/src/overlays/actors/ovl_Bg_Haka/z_bg_haka.c
@@ -14,6 +14,7 @@
#include "z_lib.h"
#include "z64play.h"
#include "z64player.h"
+#include "z64save.h"
#include "assets/objects/object_haka/object_haka.h"
diff --git a/src/overlays/actors/ovl_Bg_Haka_Megane/z_bg_haka_megane.c b/src/overlays/actors/ovl_Bg_Haka_Megane/z_bg_haka_megane.c
index c83de3001..3d67136b7 100644
--- a/src/overlays/actors/ovl_Bg_Haka_Megane/z_bg_haka_megane.c
+++ b/src/overlays/actors/ovl_Bg_Haka_Megane/z_bg_haka_megane.c
@@ -9,8 +9,6 @@
#include "ichain.h"
#include "z64play.h"
-#include "z64.h"
-
#include "assets/objects/object_hakach_objects/object_hakach_objects.h"
#include "assets/objects/object_haka_objects/object_haka_objects.h"
diff --git a/src/overlays/actors/ovl_Bg_Haka_Sgami/z_bg_haka_sgami.c b/src/overlays/actors/ovl_Bg_Haka_Sgami/z_bg_haka_sgami.c
index ce4da2a2e..f11973a86 100644
--- a/src/overlays/actors/ovl_Bg_Haka_Sgami/z_bg_haka_sgami.c
+++ b/src/overlays/actors/ovl_Bg_Haka_Sgami/z_bg_haka_sgami.c
@@ -155,12 +155,12 @@ void BgHakaSgami_Init(Actor* thisx, PlayState* play) {
Collider_InitTris(play, colliderScythe);
Collider_SetTris(play, colliderScythe, thisx, &sTrisInit, this->colliderScytheItems);
- Collider_InitCylinder(play, &this->colliderScytheCenter);
- Collider_SetCylinder(play, &this->colliderScytheCenter, thisx, &sCylinderInit);
+ Collider_InitCylinder(play, &this->scytheCenterCollider);
+ Collider_SetCylinder(play, &this->scytheCenterCollider, thisx, &sCylinderInit);
- this->colliderScytheCenter.dim.pos.x = thisx->world.pos.x;
- this->colliderScytheCenter.dim.pos.y = thisx->world.pos.y;
- this->colliderScytheCenter.dim.pos.z = thisx->world.pos.z;
+ this->scytheCenterCollider.dim.pos.x = thisx->world.pos.x;
+ this->scytheCenterCollider.dim.pos.y = thisx->world.pos.y;
+ this->scytheCenterCollider.dim.pos.z = thisx->world.pos.z;
CollisionCheck_SetInfo(&thisx->colChkInfo, NULL, &sColChkInfoInit);
@@ -181,8 +181,8 @@ void BgHakaSgami_Init(Actor* thisx, PlayState* play) {
thisx->flags &= ~ACTOR_FLAG_ATTENTION_ENABLED;
} else {
this->requiredObjectSlot = Object_GetSlot(&play->objectCtx, OBJECT_ICE_OBJECTS);
- this->colliderScytheCenter.dim.radius = 30;
- this->colliderScytheCenter.dim.height = 70;
+ this->scytheCenterCollider.dim.radius = 30;
+ this->scytheCenterCollider.dim.height = 70;
Actor_SetFocus(thisx, 40.0f);
}
@@ -200,7 +200,7 @@ void BgHakaSgami_Destroy(Actor* thisx, PlayState* play) {
Effect_Delete(play, this->blureEffectIndex[0]);
Effect_Delete(play, this->blureEffectIndex[1]);
Collider_DestroyTris(play, &this->colliderScythe);
- Collider_DestroyCylinder(play, &this->colliderScytheCenter);
+ Collider_DestroyCylinder(play, &this->scytheCenterCollider);
}
void BgHakaSgami_SetupSpin(BgHakaSgami* this, PlayState* play) {
@@ -289,7 +289,7 @@ void BgHakaSgami_Spin(BgHakaSgami* this, PlayState* play) {
}
CollisionCheck_SetAT(play, &play->colChkCtx, &this->colliderScythe.base);
- CollisionCheck_SetOC(play, &play->colChkCtx, &this->colliderScytheCenter.base);
+ CollisionCheck_SetOC(play, &play->colChkCtx, &this->scytheCenterCollider.base);
Actor_PlaySfx_Flagged(&this->actor, NA_SE_EV_ROLLCUTTER_MOTOR - SFX_FLAG);
}
diff --git a/src/overlays/actors/ovl_Bg_Haka_Sgami/z_bg_haka_sgami.h b/src/overlays/actors/ovl_Bg_Haka_Sgami/z_bg_haka_sgami.h
index 2bbcd2dc0..53c0b6340 100644
--- a/src/overlays/actors/ovl_Bg_Haka_Sgami/z_bg_haka_sgami.h
+++ b/src/overlays/actors/ovl_Bg_Haka_Sgami/z_bg_haka_sgami.h
@@ -15,7 +15,7 @@ typedef struct BgHakaSgami {
/* 0x0151 */ s8 unk_151;
/* 0x0152 */ s16 timer;
/* 0x0154 */ s32 blureEffectIndex[2];
- /* 0x015C */ ColliderCylinder colliderScytheCenter;
+ /* 0x015C */ ColliderCylinder scytheCenterCollider;
/* 0x01A8 */ ColliderTris colliderScythe;
/* 0x01C8 */ ColliderTrisElement colliderScytheItems[4];
} BgHakaSgami; // size = 0x0338
diff --git a/src/overlays/actors/ovl_Bg_Hidan_Curtain/z_bg_hidan_curtain.c b/src/overlays/actors/ovl_Bg_Hidan_Curtain/z_bg_hidan_curtain.c
index dfaca6232..a20a0a042 100644
--- a/src/overlays/actors/ovl_Bg_Hidan_Curtain/z_bg_hidan_curtain.c
+++ b/src/overlays/actors/ovl_Bg_Hidan_Curtain/z_bg_hidan_curtain.c
@@ -14,6 +14,7 @@
#include "sys_matrix.h"
#include "z_lib.h"
#include "z64play.h"
+#include "z64save.h"
#include "assets/objects/gameplay_keep/gameplay_keep.h"
diff --git a/src/overlays/actors/ovl_Bg_Hidan_Fwbig/z_bg_hidan_fwbig.c b/src/overlays/actors/ovl_Bg_Hidan_Fwbig/z_bg_hidan_fwbig.c
index 26201b24c..47849aa85 100644
--- a/src/overlays/actors/ovl_Bg_Hidan_Fwbig/z_bg_hidan_fwbig.c
+++ b/src/overlays/actors/ovl_Bg_Hidan_Fwbig/z_bg_hidan_fwbig.c
@@ -17,6 +17,7 @@
#include "z_lib.h"
#include "z64play.h"
#include "z64player.h"
+#include "z64save.h"
#include "assets/objects/gameplay_keep/gameplay_keep.h"
#include "assets/objects/object_hidan_objects/object_hidan_objects.h"
diff --git a/src/overlays/actors/ovl_Bg_Ingate/z_bg_ingate.c b/src/overlays/actors/ovl_Bg_Ingate/z_bg_ingate.c
index 40eaf99d1..e46139117 100644
--- a/src/overlays/actors/ovl_Bg_Ingate/z_bg_ingate.c
+++ b/src/overlays/actors/ovl_Bg_Ingate/z_bg_ingate.c
@@ -11,6 +11,7 @@
#include "sys_matrix.h"
#include "z_lib.h"
#include "z64play.h"
+#include "z64save.h"
#include "assets/objects/object_ingate/object_ingate.h"
diff --git a/src/overlays/actors/ovl_Bg_Jya_1flift/z_bg_jya_1flift.c b/src/overlays/actors/ovl_Bg_Jya_1flift/z_bg_jya_1flift.c
index 8dbf588a1..94fd0883d 100644
--- a/src/overlays/actors/ovl_Bg_Jya_1flift/z_bg_jya_1flift.c
+++ b/src/overlays/actors/ovl_Bg_Jya_1flift/z_bg_jya_1flift.c
@@ -10,6 +10,7 @@
#include "sfx.h"
#include "z_lib.h"
#include "z64play.h"
+#include "z64save.h"
#include "assets/objects/object_jya_obj/object_jya_obj.h"
diff --git a/src/overlays/actors/ovl_Bg_Jya_Block/z_bg_jya_block.c b/src/overlays/actors/ovl_Bg_Jya_Block/z_bg_jya_block.c
index bcd06ce59..946db1b05 100644
--- a/src/overlays/actors/ovl_Bg_Jya_Block/z_bg_jya_block.c
+++ b/src/overlays/actors/ovl_Bg_Jya_Block/z_bg_jya_block.c
@@ -13,6 +13,7 @@
#include "sys_matrix.h"
#include "z64play.h"
#include "z64player.h"
+#include "z64save.h"
#include "assets/objects/gameplay_dangeon_keep/gameplay_dangeon_keep.h"
diff --git a/src/overlays/actors/ovl_Bg_Jya_Bombchuiwa/z_bg_jya_bombchuiwa.c b/src/overlays/actors/ovl_Bg_Jya_Bombchuiwa/z_bg_jya_bombchuiwa.c
index cd7d83e0f..5b1c869ea 100644
--- a/src/overlays/actors/ovl_Bg_Jya_Bombchuiwa/z_bg_jya_bombchuiwa.c
+++ b/src/overlays/actors/ovl_Bg_Jya_Bombchuiwa/z_bg_jya_bombchuiwa.c
@@ -77,7 +77,7 @@ void BgJyaBombchuiwa_SetupCollider(BgJyaBombchuiwa* this, PlayState* play) {
s32 pad;
Collider_InitJntSph(play, &this->collider);
- Collider_SetJntSph(play, &this->collider, &this->actor, &sJntSphInit, &this->colliderItems);
+ Collider_SetJntSph(play, &this->collider, &this->actor, &sJntSphInit, this->colliderElements);
}
void BgJyaBombchuiwa_SetDrawFlags(BgJyaBombchuiwa* this, u8 drawFlags) {
diff --git a/src/overlays/actors/ovl_Bg_Jya_Bombchuiwa/z_bg_jya_bombchuiwa.h b/src/overlays/actors/ovl_Bg_Jya_Bombchuiwa/z_bg_jya_bombchuiwa.h
index 650a95ce7..ad9b9c33d 100644
--- a/src/overlays/actors/ovl_Bg_Jya_Bombchuiwa/z_bg_jya_bombchuiwa.h
+++ b/src/overlays/actors/ovl_Bg_Jya_Bombchuiwa/z_bg_jya_bombchuiwa.h
@@ -12,7 +12,7 @@ typedef struct BgJyaBombchuiwa {
/* 0x0000 */ Actor actor;
/* 0x014C */ BgJyaBombchuiwaActionFunc actionFunc;
/* 0x0150 */ ColliderJntSph collider;
- /* 0x0170 */ ColliderJntSphElement colliderItems;
+ /* 0x0170 */ ColliderJntSphElement colliderElements[1];
/* 0x01B0 */ f32 lightRayIntensity;
/* 0x01B4 */ s16 timer;
/* 0x01B6 */ u8 drawFlags; // Used to determine how the actor is drawn.
diff --git a/src/overlays/actors/ovl_Bg_Jya_Bombiwa/z_bg_jya_bombiwa.h b/src/overlays/actors/ovl_Bg_Jya_Bombiwa/z_bg_jya_bombiwa.h
index 6593e4903..9f06d9a1d 100644
--- a/src/overlays/actors/ovl_Bg_Jya_Bombiwa/z_bg_jya_bombiwa.h
+++ b/src/overlays/actors/ovl_Bg_Jya_Bombiwa/z_bg_jya_bombiwa.h
@@ -4,7 +4,6 @@
#include "ultra64.h"
#include "z64actor.h"
-
struct BgJyaBombiwa;
typedef struct BgJyaBombiwa {
diff --git a/src/overlays/actors/ovl_Bg_Jya_Goroiwa/z_bg_jya_goroiwa.c b/src/overlays/actors/ovl_Bg_Jya_Goroiwa/z_bg_jya_goroiwa.c
index e46dbfa34..6d6b13efb 100644
--- a/src/overlays/actors/ovl_Bg_Jya_Goroiwa/z_bg_jya_goroiwa.c
+++ b/src/overlays/actors/ovl_Bg_Jya_Goroiwa/z_bg_jya_goroiwa.c
@@ -90,7 +90,7 @@ void BgJyaGoroiwa_InitCollider(BgJyaGoroiwa* this, PlayState* play) {
s32 pad;
Collider_InitJntSph(play, &this->collider);
- Collider_SetJntSph(play, &this->collider, &this->actor, &sJntSphInit, &this->colliderItem);
+ Collider_SetJntSph(play, &this->collider, &this->actor, &sJntSphInit, this->colliderElements);
BgJyaGoroiwa_UpdateCollider(this);
this->collider.elements[0].dim.worldSphere.radius = 58;
}
diff --git a/src/overlays/actors/ovl_Bg_Jya_Goroiwa/z_bg_jya_goroiwa.h b/src/overlays/actors/ovl_Bg_Jya_Goroiwa/z_bg_jya_goroiwa.h
index 299f9a65f..35f4c971c 100644
--- a/src/overlays/actors/ovl_Bg_Jya_Goroiwa/z_bg_jya_goroiwa.h
+++ b/src/overlays/actors/ovl_Bg_Jya_Goroiwa/z_bg_jya_goroiwa.h
@@ -12,7 +12,7 @@ typedef struct BgJyaGoroiwa {
/* 0x0000 */ Actor actor;
/* 0x014C */ BgJyaGoroiwaFunc actionFunc;
/* 0x0150 */ ColliderJntSph collider;
- /* 0x0170 */ ColliderJntSphElement colliderItem;
+ /* 0x0170 */ ColliderJntSphElement colliderElements[1];
/* 0x01B0 */ f32 speedFactor;
/* 0x01B4 */ s16 hasHit;
/* 0x01B6 */ s16 waitTimer;
diff --git a/src/overlays/actors/ovl_Bg_Jya_Ironobj/z_bg_jya_ironobj.c b/src/overlays/actors/ovl_Bg_Jya_Ironobj/z_bg_jya_ironobj.c
index e953b653c..3ecb0cb2f 100644
--- a/src/overlays/actors/ovl_Bg_Jya_Ironobj/z_bg_jya_ironobj.c
+++ b/src/overlays/actors/ovl_Bg_Jya_Ironobj/z_bg_jya_ironobj.c
@@ -89,13 +89,13 @@ static InitChainEntry sInitChain[] = {
static CollisionHeader* sCollisionHeaders[] = { &gPillarCol, &gThroneCol };
void BgJyaIronobj_InitCylinder(BgJyaIronobj* this, PlayState* play) {
- ColliderCylinder* colCylinder = &this->colCylinder;
+ ColliderCylinder* colCylinder = &this->colliderCylinder;
Collider_InitCylinder(play, colCylinder);
Collider_SetCylinder(play, colCylinder, &this->dyna.actor, &sCylinderInit);
if (PARAMS_GET_U(this->dyna.actor.params, 0, 1) == 1) {
- this->colCylinder.dim.radius = 40;
- this->colCylinder.dim.height = 100;
+ this->colliderCylinder.dim.radius = 40;
+ this->colliderCylinder.dim.height = 100;
}
Collider_UpdateCylinder(&this->dyna.actor, colCylinder);
}
@@ -244,7 +244,7 @@ void BgJyaIronobj_Init(Actor* thisx, PlayState* play) {
void BgJyaIronobj_Destroy(Actor* thisx, PlayState* play) {
BgJyaIronobj* this = (BgJyaIronobj*)thisx;
- Collider_DestroyCylinder(play, &this->colCylinder);
+ Collider_DestroyCylinder(play, &this->colliderCylinder);
DynaPoly_DeleteBgActor(play, &play->colCtx.dyna, this->dyna.bgId);
}
@@ -258,9 +258,9 @@ void func_808992E8(BgJyaIronobj* this, PlayState* play) {
Vec3f dropPos;
s32 i;
- if (this->colCylinder.base.acFlags & AC_HIT) {
- actor = this->colCylinder.base.ac;
- this->colCylinder.base.acFlags &= ~AC_HIT;
+ if (this->colliderCylinder.base.acFlags & AC_HIT) {
+ actor = this->colliderCylinder.base.ac;
+ this->colliderCylinder.base.acFlags &= ~AC_HIT;
if (actor != NULL && actor->id == ACTOR_EN_IK) {
particleFunc[PARAMS_GET_U(this->dyna.actor.params, 0, 1)](this, play, (EnIk*)actor);
SfxSource_PlaySfxAtFixedWorldPos(play, &this->dyna.actor.world.pos, 80, NA_SE_EN_IRONNACK_BREAK_PILLAR);
@@ -275,7 +275,7 @@ void func_808992E8(BgJyaIronobj* this, PlayState* play) {
return;
}
} else {
- CollisionCheck_SetAC(play, &play->colChkCtx, &this->colCylinder.base);
+ CollisionCheck_SetAC(play, &play->colChkCtx, &this->colliderCylinder.base);
}
}
diff --git a/src/overlays/actors/ovl_Bg_Jya_Ironobj/z_bg_jya_ironobj.h b/src/overlays/actors/ovl_Bg_Jya_Ironobj/z_bg_jya_ironobj.h
index e31894172..9768aec2a 100644
--- a/src/overlays/actors/ovl_Bg_Jya_Ironobj/z_bg_jya_ironobj.h
+++ b/src/overlays/actors/ovl_Bg_Jya_Ironobj/z_bg_jya_ironobj.h
@@ -11,7 +11,7 @@ typedef void (*BgJyaIronobjActionFunc)(struct BgJyaIronobj*, struct PlayState*);
typedef struct BgJyaIronobj {
/* 0x0000 */ DynaPolyActor dyna;
/* 0x0164 */ BgJyaIronobjActionFunc actionFunc;
- /* 0x0168 */ ColliderCylinder colCylinder;
+ /* 0x0168 */ ColliderCylinder colliderCylinder;
} BgJyaIronobj; // size = 0x01B4
#endif
diff --git a/src/overlays/actors/ovl_Bg_Jya_Megami/z_bg_jya_megami.c b/src/overlays/actors/ovl_Bg_Jya_Megami/z_bg_jya_megami.c
index 364e09596..4e9d88d7c 100644
--- a/src/overlays/actors/ovl_Bg_Jya_Megami/z_bg_jya_megami.c
+++ b/src/overlays/actors/ovl_Bg_Jya_Megami/z_bg_jya_megami.c
@@ -136,7 +136,7 @@ void BgJyaMegami_InitCollider(BgJyaMegami* this, PlayState* play) {
s32 pad;
Collider_InitJntSph(play, &this->collider);
- Collider_SetJntSph(play, &this->collider, &this->dyna.actor, &sJntSphInit, &this->colliderItem);
+ Collider_SetJntSph(play, &this->collider, &this->dyna.actor, &sJntSphInit, this->colliderElements);
}
void BgJyaMegami_SpawnEffect(PlayState* play, Vec3f* pos, Vec3f* velocity, s32 num, s32 arg4) {
diff --git a/src/overlays/actors/ovl_Bg_Jya_Megami/z_bg_jya_megami.h b/src/overlays/actors/ovl_Bg_Jya_Megami/z_bg_jya_megami.h
index df3451f9d..e297ebb63 100644
--- a/src/overlays/actors/ovl_Bg_Jya_Megami/z_bg_jya_megami.h
+++ b/src/overlays/actors/ovl_Bg_Jya_Megami/z_bg_jya_megami.h
@@ -19,7 +19,7 @@ typedef struct BgJyaMegami {
/* 0x0000 */ DynaPolyActor dyna;
/* 0x0164 */ BgJyaMegamiActionFunc actionFunc;
/* 0x0168 */ ColliderJntSph collider;
- /* 0x0188 */ ColliderJntSphElement colliderItem;
+ /* 0x0188 */ ColliderJntSphElement colliderElements[1];
/* 0x01C8 */ s16 lightTimer;
/* 0x01CA */ s16 explosionTimer;
/* 0x01CC */ s16 crumbleIndex;
diff --git a/src/overlays/actors/ovl_Bg_Mori_Hashigo/z_bg_mori_hashigo.c b/src/overlays/actors/ovl_Bg_Mori_Hashigo/z_bg_mori_hashigo.c
index 211f06d3b..b75117adc 100644
--- a/src/overlays/actors/ovl_Bg_Mori_Hashigo/z_bg_mori_hashigo.c
+++ b/src/overlays/actors/ovl_Bg_Mori_Hashigo/z_bg_mori_hashigo.c
@@ -5,6 +5,14 @@
*/
#include "z_bg_mori_hashigo.h"
+
+#include "gfx.h"
+#include "gfx_setupdl.h"
+#include "ichain.h"
+#include "sys_matrix.h"
+#include "z_lib.h"
+#include "z64play.h"
+
#include "assets/objects/object_mori_objects/object_mori_objects.h"
#define FLAGS 0
diff --git a/src/overlays/actors/ovl_Bg_Mori_Hashigo/z_bg_mori_hashigo.h b/src/overlays/actors/ovl_Bg_Mori_Hashigo/z_bg_mori_hashigo.h
index d667f933e..e14aec45e 100644
--- a/src/overlays/actors/ovl_Bg_Mori_Hashigo/z_bg_mori_hashigo.h
+++ b/src/overlays/actors/ovl_Bg_Mori_Hashigo/z_bg_mori_hashigo.h
@@ -2,11 +2,11 @@
#define Z_BG_MORI_HASHIGO_H
#include "ultra64.h"
-#include "global.h"
+#include "z64actor.h"
struct BgMoriHashigo;
-typedef void (*BgMoriHashigoActionFunc)(struct BgMoriHashigo*, PlayState*);
+typedef void (*BgMoriHashigoActionFunc)(struct BgMoriHashigo*, struct PlayState*);
typedef struct BgMoriHashigo {
/* 0x0000 */ DynaPolyActor dyna;
diff --git a/src/overlays/actors/ovl_Bg_Mori_Hashira4/z_bg_mori_hashira4.c b/src/overlays/actors/ovl_Bg_Mori_Hashira4/z_bg_mori_hashira4.c
index c5f634640..9f3b50dad 100644
--- a/src/overlays/actors/ovl_Bg_Mori_Hashira4/z_bg_mori_hashira4.c
+++ b/src/overlays/actors/ovl_Bg_Mori_Hashira4/z_bg_mori_hashira4.c
@@ -5,6 +5,16 @@
*/
#include "z_bg_mori_hashira4.h"
+
+#include "gfx.h"
+#include "gfx_setupdl.h"
+#include "ichain.h"
+#include "one_point_cutscene.h"
+#include "sfx.h"
+#include "sys_matrix.h"
+#include "z_lib.h"
+#include "z64play.h"
+
#include "assets/objects/object_mori_objects/object_mori_objects.h"
#define FLAGS ACTOR_FLAG_UPDATE_CULLING_DISABLED
diff --git a/src/overlays/actors/ovl_Bg_Mori_Hashira4/z_bg_mori_hashira4.h b/src/overlays/actors/ovl_Bg_Mori_Hashira4/z_bg_mori_hashira4.h
index a36a6ef36..e4ab5a2d8 100644
--- a/src/overlays/actors/ovl_Bg_Mori_Hashira4/z_bg_mori_hashira4.h
+++ b/src/overlays/actors/ovl_Bg_Mori_Hashira4/z_bg_mori_hashira4.h
@@ -2,11 +2,11 @@
#define Z_BG_MORI_HASHIRA4_H
#include "ultra64.h"
-#include "global.h"
+#include "z64actor.h"
struct BgMoriHashira4;
-typedef void (*BgMoriHashira4ActionFunc)(struct BgMoriHashira4*, PlayState*);
+typedef void (*BgMoriHashira4ActionFunc)(struct BgMoriHashira4*, struct PlayState*);
typedef struct BgMoriHashira4 {
/* 0x0000 */ DynaPolyActor dyna;
diff --git a/src/overlays/actors/ovl_Bg_Mori_Hineri/z_bg_mori_hineri.c b/src/overlays/actors/ovl_Bg_Mori_Hineri/z_bg_mori_hineri.c
index 70e60eacf..92fc3c57a 100644
--- a/src/overlays/actors/ovl_Bg_Mori_Hineri/z_bg_mori_hineri.c
+++ b/src/overlays/actors/ovl_Bg_Mori_Hineri/z_bg_mori_hineri.c
@@ -5,7 +5,19 @@
*/
#include "z_bg_mori_hineri.h"
+
+#include "gfx.h"
+#include "gfx_setupdl.h"
+#include "ichain.h"
+#include "one_point_cutscene.h"
+#include "sfx.h"
+#include "sys_matrix.h"
#include "versions.h"
+#include "z_lib.h"
+#include "z64curve.h"
+#include "z64play.h"
+#include "z64player.h"
+
#include "assets/objects/gameplay_keep/gameplay_keep.h"
#include "assets/objects/object_box/object_box.h"
#include "assets/objects/object_mori_hineri1/object_mori_hineri1.h"
diff --git a/src/overlays/actors/ovl_Bg_Mori_Hineri/z_bg_mori_hineri.h b/src/overlays/actors/ovl_Bg_Mori_Hineri/z_bg_mori_hineri.h
index 468bb2965..b9a29df50 100644
--- a/src/overlays/actors/ovl_Bg_Mori_Hineri/z_bg_mori_hineri.h
+++ b/src/overlays/actors/ovl_Bg_Mori_Hineri/z_bg_mori_hineri.h
@@ -2,14 +2,14 @@
#define Z_BG_MORI_HINERI_H
#include "ultra64.h"
-#include "global.h"
+#include "z64actor.h"
struct BgMoriHineri;
// Due to a unique access pattern, this param cannot use the generic "PARAMS_GET_U" macros
#define TWISTED_HALLWAY_GET_PARAM_15(thisx) (((thisx)->params & (NBITS_TO_MASK(1) << (15))) >> ((15) - (1)))
-typedef void (*BgMoriHineriActionFunc)(struct BgMoriHineri*, PlayState*);
+typedef void (*BgMoriHineriActionFunc)(struct BgMoriHineri*, struct PlayState*);
typedef struct BgMoriHineri {
/* 0x0000 */ DynaPolyActor dyna;
diff --git a/src/overlays/actors/ovl_Bg_Mori_Idomizu/z_bg_mori_idomizu.c b/src/overlays/actors/ovl_Bg_Mori_Idomizu/z_bg_mori_idomizu.c
index 9af9f14f2..051e7c687 100644
--- a/src/overlays/actors/ovl_Bg_Mori_Idomizu/z_bg_mori_idomizu.c
+++ b/src/overlays/actors/ovl_Bg_Mori_Idomizu/z_bg_mori_idomizu.c
@@ -5,6 +5,15 @@
*/
#include "z_bg_mori_idomizu.h"
+
+#include "gfx.h"
+#include "gfx_setupdl.h"
+#include "one_point_cutscene.h"
+#include "sfx.h"
+#include "sys_matrix.h"
+#include "z_lib.h"
+#include "z64play.h"
+
#include "assets/objects/object_mori_objects/object_mori_objects.h"
#define FLAGS (ACTOR_FLAG_UPDATE_CULLING_DISABLED | ACTOR_FLAG_DRAW_CULLING_DISABLED)
diff --git a/src/overlays/actors/ovl_Bg_Mori_Idomizu/z_bg_mori_idomizu.h b/src/overlays/actors/ovl_Bg_Mori_Idomizu/z_bg_mori_idomizu.h
index 3e7036ec4..434862242 100644
--- a/src/overlays/actors/ovl_Bg_Mori_Idomizu/z_bg_mori_idomizu.h
+++ b/src/overlays/actors/ovl_Bg_Mori_Idomizu/z_bg_mori_idomizu.h
@@ -2,11 +2,11 @@
#define Z_BG_MORI_IDOMIZU_H
#include "ultra64.h"
-#include "global.h"
+#include "z64actor.h"
struct BgMoriIdomizu;
-typedef void (*BgMoriIdomizuActionFunc)(struct BgMoriIdomizu*, PlayState*);
+typedef void (*BgMoriIdomizuActionFunc)(struct BgMoriIdomizu*, struct PlayState*);
typedef struct BgMoriIdomizu {
/* 0x0000 */ Actor actor;
diff --git a/src/overlays/actors/ovl_Bg_Mori_Kaitenkabe/z_bg_mori_kaitenkabe.c b/src/overlays/actors/ovl_Bg_Mori_Kaitenkabe/z_bg_mori_kaitenkabe.c
index e9fc984f9..0b22e202b 100644
--- a/src/overlays/actors/ovl_Bg_Mori_Kaitenkabe/z_bg_mori_kaitenkabe.c
+++ b/src/overlays/actors/ovl_Bg_Mori_Kaitenkabe/z_bg_mori_kaitenkabe.c
@@ -5,6 +5,16 @@
*/
#include "z_bg_mori_kaitenkabe.h"
+
+#include "gfx.h"
+#include "gfx_setupdl.h"
+#include "ichain.h"
+#include "sfx.h"
+#include "sys_matrix.h"
+#include "z_lib.h"
+#include "z64play.h"
+#include "z64player.h"
+
#include "assets/objects/object_mori_objects/object_mori_objects.h"
#define FLAGS 0
diff --git a/src/overlays/actors/ovl_Bg_Mori_Kaitenkabe/z_bg_mori_kaitenkabe.h b/src/overlays/actors/ovl_Bg_Mori_Kaitenkabe/z_bg_mori_kaitenkabe.h
index 7bd6939d3..91c0d65a8 100644
--- a/src/overlays/actors/ovl_Bg_Mori_Kaitenkabe/z_bg_mori_kaitenkabe.h
+++ b/src/overlays/actors/ovl_Bg_Mori_Kaitenkabe/z_bg_mori_kaitenkabe.h
@@ -2,11 +2,11 @@
#define Z_BG_MORI_KAITENKABE_H
#include "ultra64.h"
-#include "global.h"
+#include "z64actor.h"
struct BgMoriKaitenkabe;
-typedef void (*BgMoriKaitenkabeActionFunc)(struct BgMoriKaitenkabe*, PlayState*);
+typedef void (*BgMoriKaitenkabeActionFunc)(struct BgMoriKaitenkabe*, struct PlayState*);
typedef struct BgMoriKaitenkabe {
/* 0x0000 */ DynaPolyActor dyna;
diff --git a/src/overlays/actors/ovl_Bg_Mori_Rakkatenjo/z_bg_mori_rakkatenjo.c b/src/overlays/actors/ovl_Bg_Mori_Rakkatenjo/z_bg_mori_rakkatenjo.c
index 61bbf6b9e..b331b15b2 100644
--- a/src/overlays/actors/ovl_Bg_Mori_Rakkatenjo/z_bg_mori_rakkatenjo.c
+++ b/src/overlays/actors/ovl_Bg_Mori_Rakkatenjo/z_bg_mori_rakkatenjo.c
@@ -5,8 +5,19 @@
*/
#include "z_bg_mori_rakkatenjo.h"
-#include "assets/objects/object_mori_objects/object_mori_objects.h"
+
+#include "gfx.h"
+#include "gfx_setupdl.h"
+#include "ichain.h"
#include "quake.h"
+#include "rumble.h"
+#include "sfx.h"
+#include "sys_matrix.h"
+#include "z_lib.h"
+#include "z64play.h"
+#include "z64player.h"
+
+#include "assets/objects/object_mori_objects/object_mori_objects.h"
#define FLAGS (ACTOR_FLAG_UPDATE_CULLING_DISABLED | ACTOR_FLAG_DRAW_CULLING_DISABLED)
diff --git a/src/overlays/actors/ovl_Bg_Mori_Rakkatenjo/z_bg_mori_rakkatenjo.h b/src/overlays/actors/ovl_Bg_Mori_Rakkatenjo/z_bg_mori_rakkatenjo.h
index 97bdbc0bf..657baefc5 100644
--- a/src/overlays/actors/ovl_Bg_Mori_Rakkatenjo/z_bg_mori_rakkatenjo.h
+++ b/src/overlays/actors/ovl_Bg_Mori_Rakkatenjo/z_bg_mori_rakkatenjo.h
@@ -2,11 +2,11 @@
#define Z_BG_MORI_RAKKATENJO_H
#include "ultra64.h"
-#include "global.h"
+#include "z64actor.h"
struct BgMoriRakkatenjo;
-typedef void (*BgMoriRakkatenjoActionFunction)(struct BgMoriRakkatenjo*, PlayState*);
+typedef void (*BgMoriRakkatenjoActionFunction)(struct BgMoriRakkatenjo*, struct PlayState*);
typedef struct BgMoriRakkatenjo {
/* 0x0000 */ DynaPolyActor dyna;
diff --git a/src/overlays/actors/ovl_Bg_Po_Event/z_bg_po_event.c b/src/overlays/actors/ovl_Bg_Po_Event/z_bg_po_event.c
index 1c5ce99ec..eda5a530e 100644
--- a/src/overlays/actors/ovl_Bg_Po_Event/z_bg_po_event.c
+++ b/src/overlays/actors/ovl_Bg_Po_Event/z_bg_po_event.c
@@ -18,6 +18,7 @@
#include "z64effect.h"
#include "z64play.h"
#include "z64player.h"
+#include "z64save.h"
#include "assets/objects/object_po_sisters/object_po_sisters.h"
diff --git a/src/overlays/actors/ovl_Bg_Po_Syokudai/z_bg_po_syokudai.c b/src/overlays/actors/ovl_Bg_Po_Syokudai/z_bg_po_syokudai.c
index 9dae9b2a5..e5b8edea9 100644
--- a/src/overlays/actors/ovl_Bg_Po_Syokudai/z_bg_po_syokudai.c
+++ b/src/overlays/actors/ovl_Bg_Po_Syokudai/z_bg_po_syokudai.c
@@ -5,6 +5,16 @@
*/
#include "z_bg_po_syokudai.h"
+
+#include "libc64/qrand.h"
+#include "gfx.h"
+#include "gfx_setupdl.h"
+#include "ichain.h"
+#include "sfx.h"
+#include "sys_matrix.h"
+#include "z64light.h"
+#include "z64play.h"
+
#include "assets/objects/gameplay_keep/gameplay_keep.h"
#include "assets/objects/object_syokudai/object_syokudai.h"
diff --git a/src/overlays/actors/ovl_Bg_Po_Syokudai/z_bg_po_syokudai.h b/src/overlays/actors/ovl_Bg_Po_Syokudai/z_bg_po_syokudai.h
index 8bb84f0fe..a6186dcbe 100644
--- a/src/overlays/actors/ovl_Bg_Po_Syokudai/z_bg_po_syokudai.h
+++ b/src/overlays/actors/ovl_Bg_Po_Syokudai/z_bg_po_syokudai.h
@@ -2,7 +2,8 @@
#define Z_BG_PO_SYOKUDAI_H
#include "ultra64.h"
-#include "global.h"
+#include "z64actor.h"
+#include "z64light.h"
struct BgPoSyokudai;
diff --git a/src/overlays/actors/ovl_Bg_Pushbox/z_bg_pushbox.c b/src/overlays/actors/ovl_Bg_Pushbox/z_bg_pushbox.c
index 7d9ef63e6..3392a15f6 100644
--- a/src/overlays/actors/ovl_Bg_Pushbox/z_bg_pushbox.c
+++ b/src/overlays/actors/ovl_Bg_Pushbox/z_bg_pushbox.c
@@ -5,6 +5,14 @@
*/
#include "z_bg_pushbox.h"
+
+#include "gfx.h"
+#include "gfx_setupdl.h"
+#include "ichain.h"
+#include "sys_matrix.h"
+#include "z_lib.h"
+#include "z64play.h"
+
#include "assets/objects/object_pu_box/object_pu_box.h"
#define FLAGS 0
diff --git a/src/overlays/actors/ovl_Bg_Pushbox/z_bg_pushbox.h b/src/overlays/actors/ovl_Bg_Pushbox/z_bg_pushbox.h
index 577ebaabb..38cd6857d 100644
--- a/src/overlays/actors/ovl_Bg_Pushbox/z_bg_pushbox.h
+++ b/src/overlays/actors/ovl_Bg_Pushbox/z_bg_pushbox.h
@@ -2,11 +2,11 @@
#define Z_BG_PUSHBOX_H
#include "ultra64.h"
-#include "global.h"
+#include "z64actor.h"
struct BgPushbox;
-typedef void (*BgPushboxActionFunc)(struct BgPushbox*, PlayState*);
+typedef void (*BgPushboxActionFunc)(struct BgPushbox*, struct PlayState*);
typedef struct BgPushbox {
/* 0x0000 */ DynaPolyActor dyna;
diff --git a/src/overlays/actors/ovl_Bg_Relay_Objects/z_bg_relay_objects.c b/src/overlays/actors/ovl_Bg_Relay_Objects/z_bg_relay_objects.c
index f6dfcc3d3..37591ae02 100644
--- a/src/overlays/actors/ovl_Bg_Relay_Objects/z_bg_relay_objects.c
+++ b/src/overlays/actors/ovl_Bg_Relay_Objects/z_bg_relay_objects.c
@@ -5,6 +5,17 @@
*/
#include "z_bg_relay_objects.h"
+
+#include "ichain.h"
+#include "rumble.h"
+#include "sfx.h"
+#include "z_lib.h"
+#include "z64audio.h"
+#include "z64cutscene_flags.h"
+#include "z64play.h"
+#include "z64player.h"
+#include "z64save.h"
+
#include "assets/objects/object_relay_objects/object_relay_objects.h"
#define FLAGS ACTOR_FLAG_UPDATE_CULLING_DISABLED
diff --git a/src/overlays/actors/ovl_Bg_Relay_Objects/z_bg_relay_objects.h b/src/overlays/actors/ovl_Bg_Relay_Objects/z_bg_relay_objects.h
index 802d84064..25db5cc5f 100644
--- a/src/overlays/actors/ovl_Bg_Relay_Objects/z_bg_relay_objects.h
+++ b/src/overlays/actors/ovl_Bg_Relay_Objects/z_bg_relay_objects.h
@@ -2,11 +2,11 @@
#define Z_BG_RELAY_OBJECTS_H
#include "ultra64.h"
-#include "global.h"
+#include "z64actor.h"
struct BgRelayObjects;
-typedef void (*BgRelayObjectsActionFunc)(struct BgRelayObjects*, PlayState*);
+typedef void (*BgRelayObjectsActionFunc)(struct BgRelayObjects*, struct PlayState*);
typedef struct BgRelayObjects {
/* 0x0000 */ DynaPolyActor dyna;
diff --git a/src/overlays/actors/ovl_Bg_Spot00_Break/z_bg_spot00_break.c b/src/overlays/actors/ovl_Bg_Spot00_Break/z_bg_spot00_break.c
index 3eb461a52..4a3a760d9 100644
--- a/src/overlays/actors/ovl_Bg_Spot00_Break/z_bg_spot00_break.c
+++ b/src/overlays/actors/ovl_Bg_Spot00_Break/z_bg_spot00_break.c
@@ -5,6 +5,11 @@
*/
#include "z_bg_spot00_break.h"
+
+#include "ichain.h"
+#include "z64play.h"
+#include "z64save.h"
+
#include "assets/objects/object_spot00_break/object_spot00_break.h"
#define FLAGS 0
diff --git a/src/overlays/actors/ovl_Bg_Spot00_Break/z_bg_spot00_break.h b/src/overlays/actors/ovl_Bg_Spot00_Break/z_bg_spot00_break.h
index de282476d..17e45aa91 100644
--- a/src/overlays/actors/ovl_Bg_Spot00_Break/z_bg_spot00_break.h
+++ b/src/overlays/actors/ovl_Bg_Spot00_Break/z_bg_spot00_break.h
@@ -2,7 +2,7 @@
#define Z_BG_SPOT00_BREAK_H
#include "ultra64.h"
-#include "global.h"
+#include "z64actor.h"
struct BgSpot00Break;
diff --git a/src/overlays/actors/ovl_Bg_Spot00_Hanebasi/z_bg_spot00_hanebasi.c b/src/overlays/actors/ovl_Bg_Spot00_Hanebasi/z_bg_spot00_hanebasi.c
index c60865af1..c305635b8 100644
--- a/src/overlays/actors/ovl_Bg_Spot00_Hanebasi/z_bg_spot00_hanebasi.c
+++ b/src/overlays/actors/ovl_Bg_Spot00_Hanebasi/z_bg_spot00_hanebasi.c
@@ -5,8 +5,22 @@
*/
#include "z_bg_spot00_hanebasi.h"
-#include "assets/objects/object_spot00_objects/object_spot00_objects.h"
+
+#include "libc64/qrand.h"
+#include "gfx.h"
+#include "gfx_setupdl.h"
+#include "ichain.h"
+#include "sfx.h"
+#include "sys_matrix.h"
+#include "z_lib.h"
+#include "z64cutscene_flags.h"
+#include "z64light.h"
+#include "z64play.h"
+#include "z64player.h"
+#include "z64save.h"
+
#include "assets/objects/gameplay_keep/gameplay_keep.h"
+#include "assets/objects/object_spot00_objects/object_spot00_objects.h"
#define FLAGS ACTOR_FLAG_UPDATE_CULLING_DISABLED
diff --git a/src/overlays/actors/ovl_Bg_Spot00_Hanebasi/z_bg_spot00_hanebasi.h b/src/overlays/actors/ovl_Bg_Spot00_Hanebasi/z_bg_spot00_hanebasi.h
index fc6427ae8..7780bea69 100644
--- a/src/overlays/actors/ovl_Bg_Spot00_Hanebasi/z_bg_spot00_hanebasi.h
+++ b/src/overlays/actors/ovl_Bg_Spot00_Hanebasi/z_bg_spot00_hanebasi.h
@@ -2,11 +2,12 @@
#define Z_BG_SPOT00_HANEBASI_H
#include "ultra64.h"
-#include "global.h"
+#include "z64actor.h"
+#include "z64light.h"
struct BgSpot00Hanebasi;
-typedef void (*BgSpot00HanebasiActionFunc)(struct BgSpot00Hanebasi*, PlayState*);
+typedef void (*BgSpot00HanebasiActionFunc)(struct BgSpot00Hanebasi*, struct PlayState*);
typedef struct BgSpot00Hanebasi {
/* 0x0000 */ DynaPolyActor dyna;
diff --git a/src/overlays/actors/ovl_Bg_Spot01_Fusya/z_bg_spot01_fusya.c b/src/overlays/actors/ovl_Bg_Spot01_Fusya/z_bg_spot01_fusya.c
index d8b3cfaba..33f96d547 100644
--- a/src/overlays/actors/ovl_Bg_Spot01_Fusya/z_bg_spot01_fusya.c
+++ b/src/overlays/actors/ovl_Bg_Spot01_Fusya/z_bg_spot01_fusya.c
@@ -5,6 +5,16 @@
*/
#include "z_bg_spot01_fusya.h"
+
+#include "gfx.h"
+#include "gfx_setupdl.h"
+#include "ichain.h"
+#include "sys_matrix.h"
+#include "z_lib.h"
+#include "z64audio.h"
+#include "z64play.h"
+#include "z64save.h"
+
#include "assets/objects/object_spot01_objects/object_spot01_objects.h"
#define FLAGS ACTOR_FLAG_UPDATE_CULLING_DISABLED
diff --git a/src/overlays/actors/ovl_Bg_Spot01_Fusya/z_bg_spot01_fusya.h b/src/overlays/actors/ovl_Bg_Spot01_Fusya/z_bg_spot01_fusya.h
index 1e7a83131..e232c6a90 100644
--- a/src/overlays/actors/ovl_Bg_Spot01_Fusya/z_bg_spot01_fusya.h
+++ b/src/overlays/actors/ovl_Bg_Spot01_Fusya/z_bg_spot01_fusya.h
@@ -2,11 +2,11 @@
#define Z_BG_SPOT01_FUSYA_H
#include "ultra64.h"
-#include "global.h"
+#include "z64actor.h"
struct BgSpot01Fusya;
-typedef void (*BgSpot01FusyaActionFunc)(struct BgSpot01Fusya*, PlayState*);
+typedef void (*BgSpot01FusyaActionFunc)(struct BgSpot01Fusya*, struct PlayState*);
typedef struct BgSpot01Fusya {
/* 0x0000 */ Actor actor;
diff --git a/src/overlays/actors/ovl_Bg_Spot01_Idohashira/z_bg_spot01_idohashira.c b/src/overlays/actors/ovl_Bg_Spot01_Idohashira/z_bg_spot01_idohashira.c
index ba1ff57d8..d5a21a8b6 100644
--- a/src/overlays/actors/ovl_Bg_Spot01_Idohashira/z_bg_spot01_idohashira.c
+++ b/src/overlays/actors/ovl_Bg_Spot01_Idohashira/z_bg_spot01_idohashira.c
@@ -5,8 +5,20 @@
*/
#include "z_bg_spot01_idohashira.h"
-#include "assets/objects/object_spot01_objects/object_spot01_objects.h"
+
+#include "gfx.h"
+#include "gfx_setupdl.h"
+#include "ichain.h"
+#include "regs.h"
+#include "sfx.h"
+#include "sys_matrix.h"
#include "terminal.h"
+#include "z_lib.h"
+#include "z64effect.h"
+#include "z64play.h"
+#include "z64save.h"
+
+#include "assets/objects/object_spot01_objects/object_spot01_objects.h"
#define FLAGS ACTOR_FLAG_UPDATE_CULLING_DISABLED
diff --git a/src/overlays/actors/ovl_Bg_Spot01_Idohashira/z_bg_spot01_idohashira.h b/src/overlays/actors/ovl_Bg_Spot01_Idohashira/z_bg_spot01_idohashira.h
index ae456de8f..8d177d331 100644
--- a/src/overlays/actors/ovl_Bg_Spot01_Idohashira/z_bg_spot01_idohashira.h
+++ b/src/overlays/actors/ovl_Bg_Spot01_Idohashira/z_bg_spot01_idohashira.h
@@ -2,12 +2,12 @@
#define Z_BG_SPOT01_IDOHASHIRA_H
#include "ultra64.h"
-#include "global.h"
+#include "z64actor.h"
struct BgSpot01Idohashira;
-typedef void (*BgSpot01IdohashiraActionFunc)(struct BgSpot01Idohashira*, PlayState*);
-typedef void (*BgSpot01IdohashiraDrawFunc)(struct BgSpot01Idohashira*, PlayState*);
+typedef void (*BgSpot01IdohashiraActionFunc)(struct BgSpot01Idohashira*, struct PlayState*);
+typedef void (*BgSpot01IdohashiraDrawFunc)(struct BgSpot01Idohashira*, struct PlayState*);
typedef struct BgSpot01Idohashira {
/* 0x0000 */ DynaPolyActor dyna;
diff --git a/src/overlays/actors/ovl_Bg_Spot01_Idomizu/z_bg_spot01_idomizu.c b/src/overlays/actors/ovl_Bg_Spot01_Idomizu/z_bg_spot01_idomizu.c
index f2c89a41d..5329d2e0f 100644
--- a/src/overlays/actors/ovl_Bg_Spot01_Idomizu/z_bg_spot01_idomizu.c
+++ b/src/overlays/actors/ovl_Bg_Spot01_Idomizu/z_bg_spot01_idomizu.c
@@ -5,6 +5,16 @@
*/
#include "z_bg_spot01_idomizu.h"
+
+#include "gfx.h"
+#include "gfx_setupdl.h"
+#include "ichain.h"
+#include "sfx.h"
+#include "sys_matrix.h"
+#include "z_lib.h"
+#include "z64play.h"
+#include "z64save.h"
+
#include "assets/objects/object_spot01_objects/object_spot01_objects.h"
#define FLAGS ACTOR_FLAG_DRAW_CULLING_DISABLED
diff --git a/src/overlays/actors/ovl_Bg_Spot01_Idomizu/z_bg_spot01_idomizu.h b/src/overlays/actors/ovl_Bg_Spot01_Idomizu/z_bg_spot01_idomizu.h
index 3c5929714..3d4ff68a6 100644
--- a/src/overlays/actors/ovl_Bg_Spot01_Idomizu/z_bg_spot01_idomizu.h
+++ b/src/overlays/actors/ovl_Bg_Spot01_Idomizu/z_bg_spot01_idomizu.h
@@ -2,11 +2,11 @@
#define Z_BG_SPOT01_IDOMIZU_H
#include "ultra64.h"
-#include "global.h"
+#include "z64actor.h"
struct BgSpot01Idomizu;
-typedef void (*BgSpot01IdomizuActionFunc)(struct BgSpot01Idomizu*, PlayState*);
+typedef void (*BgSpot01IdomizuActionFunc)(struct BgSpot01Idomizu*, struct PlayState*);
typedef struct BgSpot01Idomizu {
/* 0x0000 */ Actor actor;
diff --git a/src/overlays/actors/ovl_Bg_Spot01_Idosoko/z_bg_spot01_idosoko.c b/src/overlays/actors/ovl_Bg_Spot01_Idosoko/z_bg_spot01_idosoko.c
index 1bad86dd4..6dbdd910d 100644
--- a/src/overlays/actors/ovl_Bg_Spot01_Idosoko/z_bg_spot01_idosoko.c
+++ b/src/overlays/actors/ovl_Bg_Spot01_Idosoko/z_bg_spot01_idosoko.c
@@ -5,6 +5,14 @@
*/
#include "z_bg_spot01_idosoko.h"
+
+#include "gfx.h"
+#include "gfx_setupdl.h"
+#include "ichain.h"
+#include "sys_matrix.h"
+#include "z64play.h"
+#include "z64save.h"
+
#include "assets/objects/object_spot01_matoya/object_spot01_matoya.h"
#define FLAGS ACTOR_FLAG_UPDATE_CULLING_DISABLED
diff --git a/src/overlays/actors/ovl_Bg_Spot01_Idosoko/z_bg_spot01_idosoko.h b/src/overlays/actors/ovl_Bg_Spot01_Idosoko/z_bg_spot01_idosoko.h
index c17b0a43e..44981abc0 100644
--- a/src/overlays/actors/ovl_Bg_Spot01_Idosoko/z_bg_spot01_idosoko.h
+++ b/src/overlays/actors/ovl_Bg_Spot01_Idosoko/z_bg_spot01_idosoko.h
@@ -2,11 +2,11 @@
#define Z_BG_SPOT01_IDOSOKO_H
#include "ultra64.h"
-#include "global.h"
+#include "z64actor.h"
struct BgSpot01Idosoko;
-typedef void (*BgSpot01IdosokoActionFunc)(struct BgSpot01Idosoko*, PlayState*);
+typedef void (*BgSpot01IdosokoActionFunc)(struct BgSpot01Idosoko*, struct PlayState*);
typedef struct BgSpot01Idosoko {
/* 0x0000 */ DynaPolyActor dyna;
diff --git a/src/overlays/actors/ovl_Bg_Spot01_Objects2/z_bg_spot01_objects2.c b/src/overlays/actors/ovl_Bg_Spot01_Objects2/z_bg_spot01_objects2.c
index 2ee4c5828..4b7e9eed8 100644
--- a/src/overlays/actors/ovl_Bg_Spot01_Objects2/z_bg_spot01_objects2.c
+++ b/src/overlays/actors/ovl_Bg_Spot01_Objects2/z_bg_spot01_objects2.c
@@ -5,6 +5,12 @@
*/
#include "z_bg_spot01_objects2.h"
+
+#include "ichain.h"
+#include "segmented_address.h"
+#include "z64play.h"
+#include "z64save.h"
+
#include "assets/objects/object_spot01_matoya/object_spot01_matoya.h"
#include "assets/objects/object_spot01_matoyab/object_spot01_matoyab.h"
diff --git a/src/overlays/actors/ovl_Bg_Spot01_Objects2/z_bg_spot01_objects2.h b/src/overlays/actors/ovl_Bg_Spot01_Objects2/z_bg_spot01_objects2.h
index d1d96d045..7ffc3094f 100644
--- a/src/overlays/actors/ovl_Bg_Spot01_Objects2/z_bg_spot01_objects2.h
+++ b/src/overlays/actors/ovl_Bg_Spot01_Objects2/z_bg_spot01_objects2.h
@@ -2,11 +2,11 @@
#define Z_BG_SPOT01_OBJECTS2_H
#include "ultra64.h"
-#include "global.h"
+#include "z64actor.h"
struct BgSpot01Objects2;
-typedef void (*BgSpot01Objects2ActionFunc)(struct BgSpot01Objects2*, PlayState*);
+typedef void (*BgSpot01Objects2ActionFunc)(struct BgSpot01Objects2*, struct PlayState*);
typedef struct BgSpot01Objects2 {
/* 0x0000 */ DynaPolyActor dyna;
diff --git a/src/overlays/actors/ovl_Bg_Spot02_Objects/z_bg_spot02_objects.c b/src/overlays/actors/ovl_Bg_Spot02_Objects/z_bg_spot02_objects.c
index a0d74b4ed..795df9015 100644
--- a/src/overlays/actors/ovl_Bg_Spot02_Objects/z_bg_spot02_objects.c
+++ b/src/overlays/actors/ovl_Bg_Spot02_Objects/z_bg_spot02_objects.c
@@ -5,6 +5,20 @@
*/
#include "z_bg_spot02_objects.h"
+
+#include "gfx.h"
+#include "gfx_setupdl.h"
+#include "ichain.h"
+#include "one_point_cutscene.h"
+#include "segmented_address.h"
+#include "sfx.h"
+#include "sys_matrix.h"
+#include "z_lib.h"
+#include "z64effect.h"
+#include "z64play.h"
+#include "z64player.h"
+#include "z64save.h"
+
#include "assets/objects/object_spot02_objects/object_spot02_objects.h"
#define FLAGS (ACTOR_FLAG_UPDATE_CULLING_DISABLED | ACTOR_FLAG_DRAW_CULLING_DISABLED)
diff --git a/src/overlays/actors/ovl_Bg_Spot02_Objects/z_bg_spot02_objects.h b/src/overlays/actors/ovl_Bg_Spot02_Objects/z_bg_spot02_objects.h
index 873fe15a5..42d4e45b0 100644
--- a/src/overlays/actors/ovl_Bg_Spot02_Objects/z_bg_spot02_objects.h
+++ b/src/overlays/actors/ovl_Bg_Spot02_Objects/z_bg_spot02_objects.h
@@ -2,11 +2,11 @@
#define Z_BG_SPOT02_OBJECTS_H
#include "ultra64.h"
-#include "global.h"
+#include "z64actor.h"
struct BgSpot02Objects;
-typedef void (*BgSpot02ObjectsActionFunc)(struct BgSpot02Objects*, PlayState*);
+typedef void (*BgSpot02ObjectsActionFunc)(struct BgSpot02Objects*, struct PlayState*);
typedef struct BgSpot02Objects {
/* 0x0000 */ DynaPolyActor dyna;
diff --git a/src/overlays/actors/ovl_Bg_Spot03_Taki/z_bg_spot03_taki.c b/src/overlays/actors/ovl_Bg_Spot03_Taki/z_bg_spot03_taki.c
index fccae09ba..501a67735 100644
--- a/src/overlays/actors/ovl_Bg_Spot03_Taki/z_bg_spot03_taki.c
+++ b/src/overlays/actors/ovl_Bg_Spot03_Taki/z_bg_spot03_taki.c
@@ -5,6 +5,16 @@
*/
#include "z_bg_spot03_taki.h"
+
+#include "gfx.h"
+#include "gfx_setupdl.h"
+#include "ichain.h"
+#include "one_point_cutscene.h"
+#include "segmented_address.h"
+#include "sys_matrix.h"
+#include "z64audio.h"
+#include "z64play.h"
+
#include "assets/objects/object_spot03_object/object_spot03_object.h"
#define FLAGS (ACTOR_FLAG_UPDATE_CULLING_DISABLED | ACTOR_FLAG_DRAW_CULLING_DISABLED)
diff --git a/src/overlays/actors/ovl_Bg_Spot03_Taki/z_bg_spot03_taki.h b/src/overlays/actors/ovl_Bg_Spot03_Taki/z_bg_spot03_taki.h
index f6e3daab1..45ad4de4f 100644
--- a/src/overlays/actors/ovl_Bg_Spot03_Taki/z_bg_spot03_taki.h
+++ b/src/overlays/actors/ovl_Bg_Spot03_Taki/z_bg_spot03_taki.h
@@ -2,7 +2,7 @@
#define Z_BG_SPOT03_TAKI_H
#include "ultra64.h"
-#include "global.h"
+#include "z64actor.h"
typedef enum BgSpot03TakiState {
WATERFALL_CLOSED,
@@ -14,7 +14,7 @@ typedef enum BgSpot03TakiState {
struct BgSpot03Taki;
-typedef void (*BgSpot03TakiActionFunc)(struct BgSpot03Taki*, PlayState*);
+typedef void (*BgSpot03TakiActionFunc)(struct BgSpot03Taki*, struct PlayState*);
typedef struct BgSpot03Taki {
/* 0x0000 */ DynaPolyActor dyna;
diff --git a/src/overlays/actors/ovl_Bg_Spot05_Soko/z_bg_spot05_soko.c b/src/overlays/actors/ovl_Bg_Spot05_Soko/z_bg_spot05_soko.c
index 93c30e65a..edb253568 100644
--- a/src/overlays/actors/ovl_Bg_Spot05_Soko/z_bg_spot05_soko.c
+++ b/src/overlays/actors/ovl_Bg_Spot05_Soko/z_bg_spot05_soko.c
@@ -5,6 +5,14 @@
*/
#include "z_bg_spot05_soko.h"
+
+#include "ichain.h"
+#include "one_point_cutscene.h"
+#include "sfx.h"
+#include "z_lib.h"
+#include "z64play.h"
+#include "z64save.h"
+
#include "assets/objects/object_spot05_objects/object_spot05_objects.h"
#define FLAGS 0
diff --git a/src/overlays/actors/ovl_Bg_Spot05_Soko/z_bg_spot05_soko.h b/src/overlays/actors/ovl_Bg_Spot05_Soko/z_bg_spot05_soko.h
index 849e5b226..1aae81879 100644
--- a/src/overlays/actors/ovl_Bg_Spot05_Soko/z_bg_spot05_soko.h
+++ b/src/overlays/actors/ovl_Bg_Spot05_Soko/z_bg_spot05_soko.h
@@ -2,11 +2,11 @@
#define Z_BG_SPOT05_SOKO_H
#include "ultra64.h"
-#include "global.h"
+#include "z64actor.h"
struct BgSpot05Soko;
-typedef void (*BgSpot05SokoActionFunc)(struct BgSpot05Soko*, PlayState*);
+typedef void (*BgSpot05SokoActionFunc)(struct BgSpot05Soko*, struct PlayState*);
typedef struct BgSpot05Soko {
/* 0x0000 */ DynaPolyActor dyna;
diff --git a/src/overlays/actors/ovl_Bg_Spot06_Objects/z_bg_spot06_objects.c b/src/overlays/actors/ovl_Bg_Spot06_Objects/z_bg_spot06_objects.c
index f7576aef8..45b2b1e9f 100644
--- a/src/overlays/actors/ovl_Bg_Spot06_Objects/z_bg_spot06_objects.c
+++ b/src/overlays/actors/ovl_Bg_Spot06_Objects/z_bg_spot06_objects.c
@@ -5,6 +5,19 @@
*/
#include "z_bg_spot06_objects.h"
+
+#include "gfx.h"
+#include "gfx_setupdl.h"
+#include "ichain.h"
+#include "one_point_cutscene.h"
+#include "rand.h"
+#include "sfx.h"
+#include "sys_matrix.h"
+#include "z_lib.h"
+#include "z64effect.h"
+#include "z64play.h"
+#include "z64save.h"
+
#include "assets/objects/object_spot06_objects/object_spot06_objects.h"
#define FLAGS ACTOR_FLAG_HOOKSHOT_PULLS_ACTOR
@@ -56,7 +69,7 @@ ActorProfile Bg_Spot06_Objects_Profile = {
/**/ BgSpot06Objects_Draw,
};
-static ColliderJntSphElementInit sJntSphItemsInit[1] = {
+static ColliderJntSphElementInit sJntSphElementsInit[1] = {
{
{
ELEM_MATERIAL_UNK0,
@@ -80,7 +93,7 @@ static ColliderJntSphInit sJntSphInit = {
COLSHAPE_JNTSPH,
},
1,
- sJntSphItemsInit,
+ sJntSphElementsInit,
};
static InitChainEntry sInitChain[] = {
diff --git a/src/overlays/actors/ovl_Bg_Spot06_Objects/z_bg_spot06_objects.h b/src/overlays/actors/ovl_Bg_Spot06_Objects/z_bg_spot06_objects.h
index 5b4281d01..cbdc1054f 100644
--- a/src/overlays/actors/ovl_Bg_Spot06_Objects/z_bg_spot06_objects.h
+++ b/src/overlays/actors/ovl_Bg_Spot06_Objects/z_bg_spot06_objects.h
@@ -2,11 +2,11 @@
#define Z_BG_SPOT06_OBJECTS_H
#include "ultra64.h"
-#include "global.h"
+#include "z64actor.h"
struct BgSpot06Objects;
-typedef void (*BgSpot06ObjectsActionFunc)(struct BgSpot06Objects*, PlayState*);
+typedef void (*BgSpot06ObjectsActionFunc)(struct BgSpot06Objects*, struct PlayState*);
typedef struct BgSpot06Objects {
/* 0x0000 */ DynaPolyActor dyna;
diff --git a/src/overlays/actors/ovl_Bg_Spot07_Taki/z_bg_spot07_taki.c b/src/overlays/actors/ovl_Bg_Spot07_Taki/z_bg_spot07_taki.c
index 04d06a57a..afb9d0297 100644
--- a/src/overlays/actors/ovl_Bg_Spot07_Taki/z_bg_spot07_taki.c
+++ b/src/overlays/actors/ovl_Bg_Spot07_Taki/z_bg_spot07_taki.c
@@ -5,7 +5,15 @@
*/
#include "z_bg_spot07_taki.h"
+
+#include "gfx.h"
+#include "gfx_setupdl.h"
+#include "ichain.h"
+#include "sys_matrix.h"
#include "versions.h"
+#include "z64play.h"
+#include "z64save.h"
+
#include "assets/objects/object_spot07_object/object_spot07_object.h"
#define FLAGS (ACTOR_FLAG_UPDATE_CULLING_DISABLED | ACTOR_FLAG_DRAW_CULLING_DISABLED)
diff --git a/src/overlays/actors/ovl_Bg_Spot07_Taki/z_bg_spot07_taki.h b/src/overlays/actors/ovl_Bg_Spot07_Taki/z_bg_spot07_taki.h
index dcf6ef8ed..30872233a 100644
--- a/src/overlays/actors/ovl_Bg_Spot07_Taki/z_bg_spot07_taki.h
+++ b/src/overlays/actors/ovl_Bg_Spot07_Taki/z_bg_spot07_taki.h
@@ -2,11 +2,11 @@
#define Z_BG_SPOT07_TAKI_H
#include "ultra64.h"
-#include "global.h"
+#include "z64actor.h"
struct BgSpot07Taki;
-typedef void (*BgSpot07TakiActionFunc)(struct BgSpot07Taki*, PlayState*);
+typedef void (*BgSpot07TakiActionFunc)(struct BgSpot07Taki*, struct PlayState*);
typedef struct BgSpot07Taki {
/* 0x0000 */ DynaPolyActor dyna;
diff --git a/src/overlays/actors/ovl_Bg_Spot08_Bakudankabe/z_bg_spot08_bakudankabe.c b/src/overlays/actors/ovl_Bg_Spot08_Bakudankabe/z_bg_spot08_bakudankabe.c
index e3803b9f4..b54226cec 100644
--- a/src/overlays/actors/ovl_Bg_Spot08_Bakudankabe/z_bg_spot08_bakudankabe.c
+++ b/src/overlays/actors/ovl_Bg_Spot08_Bakudankabe/z_bg_spot08_bakudankabe.c
@@ -5,9 +5,17 @@
*/
#include "z_bg_spot08_bakudankabe.h"
-#include "assets/objects/object_spot08_obj/object_spot08_obj.h"
#include "overlays/effects/ovl_Effect_Ss_Kakera/z_eff_ss_kakera.h"
+
+#include "libc64/qrand.h"
+#include "ichain.h"
+#include "sfx.h"
+#include "z_lib.h"
+#include "z64effect.h"
+#include "z64play.h"
+
#include "assets/objects/gameplay_field_keep/gameplay_field_keep.h"
+#include "assets/objects/object_spot08_obj/object_spot08_obj.h"
#define FLAGS ACTOR_FLAG_IGNORE_POINT_LIGHTS
diff --git a/src/overlays/actors/ovl_Bg_Spot08_Bakudankabe/z_bg_spot08_bakudankabe.h b/src/overlays/actors/ovl_Bg_Spot08_Bakudankabe/z_bg_spot08_bakudankabe.h
index 33c18e1b2..a0436ea9e 100644
--- a/src/overlays/actors/ovl_Bg_Spot08_Bakudankabe/z_bg_spot08_bakudankabe.h
+++ b/src/overlays/actors/ovl_Bg_Spot08_Bakudankabe/z_bg_spot08_bakudankabe.h
@@ -2,7 +2,7 @@
#define Z_BG_SPOT08_BAKUDANKABE_H
#include "ultra64.h"
-#include "global.h"
+#include "z64actor.h"
struct BgSpot08Bakudankabe;
diff --git a/src/overlays/actors/ovl_Bg_Spot08_Iceblock/z_bg_spot08_iceblock.c b/src/overlays/actors/ovl_Bg_Spot08_Iceblock/z_bg_spot08_iceblock.c
index 6ac2bd0fd..4f0bb3756 100644
--- a/src/overlays/actors/ovl_Bg_Spot08_Iceblock/z_bg_spot08_iceblock.c
+++ b/src/overlays/actors/ovl_Bg_Spot08_Iceblock/z_bg_spot08_iceblock.c
@@ -14,6 +14,7 @@
#include "z_lib.h"
#include "z64play.h"
#include "z64player.h"
+#include "z64save.h"
#include "assets/objects/object_spot08_obj/object_spot08_obj.h"
diff --git a/src/overlays/actors/ovl_Bg_Spot09_Obj/z_bg_spot09_obj.c b/src/overlays/actors/ovl_Bg_Spot09_Obj/z_bg_spot09_obj.c
index 00ca47644..449091faa 100644
--- a/src/overlays/actors/ovl_Bg_Spot09_Obj/z_bg_spot09_obj.c
+++ b/src/overlays/actors/ovl_Bg_Spot09_Obj/z_bg_spot09_obj.c
@@ -5,6 +5,14 @@
*/
#include "z_bg_spot09_obj.h"
+
+#include "gfx.h"
+#include "gfx_setupdl.h"
+#include "ichain.h"
+#include "sys_matrix.h"
+#include "z64play.h"
+#include "z64save.h"
+
#include "assets/objects/object_spot09_obj/object_spot09_obj.h"
#define FLAGS 0
diff --git a/src/overlays/actors/ovl_Bg_Spot09_Obj/z_bg_spot09_obj.h b/src/overlays/actors/ovl_Bg_Spot09_Obj/z_bg_spot09_obj.h
index a09ce32ed..491d7380c 100644
--- a/src/overlays/actors/ovl_Bg_Spot09_Obj/z_bg_spot09_obj.h
+++ b/src/overlays/actors/ovl_Bg_Spot09_Obj/z_bg_spot09_obj.h
@@ -2,7 +2,7 @@
#define Z_BG_SPOT09_OBJ_H
#include "ultra64.h"
-#include "global.h"
+#include "z64actor.h"
struct BgSpot09Obj;
diff --git a/src/overlays/actors/ovl_Bg_Spot11_Bakudankabe/z_bg_spot11_bakudankabe.c b/src/overlays/actors/ovl_Bg_Spot11_Bakudankabe/z_bg_spot11_bakudankabe.c
index d0568c23c..1aafed883 100644
--- a/src/overlays/actors/ovl_Bg_Spot11_Bakudankabe/z_bg_spot11_bakudankabe.c
+++ b/src/overlays/actors/ovl_Bg_Spot11_Bakudankabe/z_bg_spot11_bakudankabe.c
@@ -6,6 +6,13 @@
#include "z_bg_spot11_bakudankabe.h"
#include "overlays/effects/ovl_Effect_Ss_Kakera/z_eff_ss_kakera.h"
+
+#include "libc64/qrand.h"
+#include "sfx.h"
+#include "z_lib.h"
+#include "z64effect.h"
+#include "z64play.h"
+
#include "assets/objects/object_spot11_obj/object_spot11_obj.h"
#include "assets/objects/gameplay_field_keep/gameplay_field_keep.h"
diff --git a/src/overlays/actors/ovl_Bg_Spot11_Bakudankabe/z_bg_spot11_bakudankabe.h b/src/overlays/actors/ovl_Bg_Spot11_Bakudankabe/z_bg_spot11_bakudankabe.h
index b18f5c084..5dedab77d 100644
--- a/src/overlays/actors/ovl_Bg_Spot11_Bakudankabe/z_bg_spot11_bakudankabe.h
+++ b/src/overlays/actors/ovl_Bg_Spot11_Bakudankabe/z_bg_spot11_bakudankabe.h
@@ -2,7 +2,7 @@
#define Z_BG_SPOT11_BAKUDANKABE_H
#include "ultra64.h"
-#include "global.h"
+#include "z64actor.h"
struct BgSpot11Bakudankabe;
diff --git a/src/overlays/actors/ovl_Bg_Spot11_Oasis/z_bg_spot11_oasis.c b/src/overlays/actors/ovl_Bg_Spot11_Oasis/z_bg_spot11_oasis.c
index 05987f092..1af76df47 100644
--- a/src/overlays/actors/ovl_Bg_Spot11_Oasis/z_bg_spot11_oasis.c
+++ b/src/overlays/actors/ovl_Bg_Spot11_Oasis/z_bg_spot11_oasis.c
@@ -6,6 +6,21 @@
#include "z_bg_spot11_oasis.h"
#include "overlays/actors/ovl_En_Elf/z_en_elf.h"
+
+#include "libc64/qrand.h"
+#include "gfx.h"
+#include "gfx_setupdl.h"
+#include "ichain.h"
+#include "one_point_cutscene.h"
+#include "sfx.h"
+#include "sys_math3d.h"
+#include "sys_matrix.h"
+#include "z_lib.h"
+#include "z64cutscene_flags.h"
+#include "z64effect.h"
+#include "z64play.h"
+#include "z64player.h"
+
#include "assets/objects/object_spot11_obj/object_spot11_obj.h"
#define FLAGS ACTOR_FLAG_UPDATE_CULLING_DISABLED
diff --git a/src/overlays/actors/ovl_Bg_Spot11_Oasis/z_bg_spot11_oasis.h b/src/overlays/actors/ovl_Bg_Spot11_Oasis/z_bg_spot11_oasis.h
index cae716a00..0f0ed97e6 100644
--- a/src/overlays/actors/ovl_Bg_Spot11_Oasis/z_bg_spot11_oasis.h
+++ b/src/overlays/actors/ovl_Bg_Spot11_Oasis/z_bg_spot11_oasis.h
@@ -2,11 +2,11 @@
#define Z_BG_SPOT11_OASIS_H
#include "ultra64.h"
-#include "global.h"
+#include "z64actor.h"
struct BgSpot11Oasis;
-typedef void (*BgSpot11OasisActionFunc)(struct BgSpot11Oasis*, PlayState*);
+typedef void (*BgSpot11OasisActionFunc)(struct BgSpot11Oasis*, struct PlayState*);
typedef struct BgSpot11Oasis {
/* 0x0000 */ Actor actor;
diff --git a/src/overlays/actors/ovl_Bg_Spot12_Gate/z_bg_spot12_gate.c b/src/overlays/actors/ovl_Bg_Spot12_Gate/z_bg_spot12_gate.c
index b01eb9817..9a36eb287 100644
--- a/src/overlays/actors/ovl_Bg_Spot12_Gate/z_bg_spot12_gate.c
+++ b/src/overlays/actors/ovl_Bg_Spot12_Gate/z_bg_spot12_gate.c
@@ -5,8 +5,15 @@
*/
#include "z_bg_spot12_gate.h"
-#include "assets/objects/object_spot12_obj/object_spot12_obj.h"
+
+#include "ichain.h"
+#include "one_point_cutscene.h"
#include "quake.h"
+#include "sfx.h"
+#include "z_lib.h"
+#include "z64play.h"
+
+#include "assets/objects/object_spot12_obj/object_spot12_obj.h"
#define FLAGS 0
diff --git a/src/overlays/actors/ovl_Bg_Spot12_Gate/z_bg_spot12_gate.h b/src/overlays/actors/ovl_Bg_Spot12_Gate/z_bg_spot12_gate.h
index 2e9989fc2..bb9ef25cf 100644
--- a/src/overlays/actors/ovl_Bg_Spot12_Gate/z_bg_spot12_gate.h
+++ b/src/overlays/actors/ovl_Bg_Spot12_Gate/z_bg_spot12_gate.h
@@ -2,11 +2,11 @@
#define Z_BG_SPOT12_GATE_H
#include "ultra64.h"
-#include "global.h"
+#include "z64actor.h"
struct BgSpot12Gate;
-typedef void (*BgSpot12GateActionFunc)(struct BgSpot12Gate*, PlayState*);
+typedef void (*BgSpot12GateActionFunc)(struct BgSpot12Gate*, struct PlayState*);
typedef struct BgSpot12Gate {
/* 0x0000 */ DynaPolyActor dyna;
diff --git a/src/overlays/actors/ovl_Bg_Spot12_Saku/z_bg_spot12_saku.c b/src/overlays/actors/ovl_Bg_Spot12_Saku/z_bg_spot12_saku.c
index 7fc67b38d..1edeb5946 100644
--- a/src/overlays/actors/ovl_Bg_Spot12_Saku/z_bg_spot12_saku.c
+++ b/src/overlays/actors/ovl_Bg_Spot12_Saku/z_bg_spot12_saku.c
@@ -5,6 +5,13 @@
*/
#include "z_bg_spot12_saku.h"
+
+#include "ichain.h"
+#include "one_point_cutscene.h"
+#include "sfx.h"
+#include "z_lib.h"
+#include "z64play.h"
+
#include "assets/objects/object_spot12_obj/object_spot12_obj.h"
#define FLAGS 0
diff --git a/src/overlays/actors/ovl_Bg_Spot12_Saku/z_bg_spot12_saku.h b/src/overlays/actors/ovl_Bg_Spot12_Saku/z_bg_spot12_saku.h
index d96967300..7ed7751ed 100644
--- a/src/overlays/actors/ovl_Bg_Spot12_Saku/z_bg_spot12_saku.h
+++ b/src/overlays/actors/ovl_Bg_Spot12_Saku/z_bg_spot12_saku.h
@@ -2,11 +2,11 @@
#define Z_BG_SPOT12_SAKU_H
#include "ultra64.h"
-#include "global.h"
+#include "z64actor.h"
struct BgSpot12Saku;
-typedef void (*BgSpot12SakuActionFunc)(struct BgSpot12Saku*, PlayState*);
+typedef void (*BgSpot12SakuActionFunc)(struct BgSpot12Saku*, struct PlayState*);
typedef struct BgSpot12Saku {
/* 0x0000 */ DynaPolyActor dyna;
diff --git a/src/overlays/actors/ovl_Bg_Spot15_Rrbox/z_bg_spot15_rrbox.c b/src/overlays/actors/ovl_Bg_Spot15_Rrbox/z_bg_spot15_rrbox.c
index c0daacf78..d0655135a 100644
--- a/src/overlays/actors/ovl_Bg_Spot15_Rrbox/z_bg_spot15_rrbox.c
+++ b/src/overlays/actors/ovl_Bg_Spot15_Rrbox/z_bg_spot15_rrbox.c
@@ -5,6 +5,15 @@
*/
#include "z_bg_spot15_rrbox.h"
+
+#include "ichain.h"
+#include "sfx.h"
+#include "sys_math3d.h"
+#include "z_lib.h"
+#include "z64play.h"
+#include "z64player.h"
+#include "z64save.h"
+
#include "assets/objects/object_spot15_obj/object_spot15_obj.h"
#define FLAGS 0
diff --git a/src/overlays/actors/ovl_Bg_Spot15_Rrbox/z_bg_spot15_rrbox.h b/src/overlays/actors/ovl_Bg_Spot15_Rrbox/z_bg_spot15_rrbox.h
index 745c65629..d0534e1e7 100644
--- a/src/overlays/actors/ovl_Bg_Spot15_Rrbox/z_bg_spot15_rrbox.h
+++ b/src/overlays/actors/ovl_Bg_Spot15_Rrbox/z_bg_spot15_rrbox.h
@@ -2,11 +2,11 @@
#define Z_BG_SPOT15_RRBOX_H
#include "ultra64.h"
-#include "global.h"
+#include "z64actor.h"
struct BgSpot15Rrbox;
-typedef void (*BgSpot15RrboxActionFunc)(struct BgSpot15Rrbox*, PlayState*);
+typedef void (*BgSpot15RrboxActionFunc)(struct BgSpot15Rrbox*, struct PlayState*);
typedef struct BgSpot15Rrbox {
/* 0x0000 */ DynaPolyActor dyna;
diff --git a/src/overlays/actors/ovl_Bg_Spot15_Saku/z_bg_spot15_saku.c b/src/overlays/actors/ovl_Bg_Spot15_Saku/z_bg_spot15_saku.c
index ca52b057b..c053a6c2d 100644
--- a/src/overlays/actors/ovl_Bg_Spot15_Saku/z_bg_spot15_saku.c
+++ b/src/overlays/actors/ovl_Bg_Spot15_Saku/z_bg_spot15_saku.c
@@ -5,6 +5,14 @@
*/
#include "z_bg_spot15_saku.h"
+
+#include "gfx.h"
+#include "gfx_setupdl.h"
+#include "sfx.h"
+#include "sys_matrix.h"
+#include "z64play.h"
+#include "z64save.h"
+
#include "assets/objects/object_spot15_obj/object_spot15_obj.h"
#define FLAGS 0
diff --git a/src/overlays/actors/ovl_Bg_Spot15_Saku/z_bg_spot15_saku.h b/src/overlays/actors/ovl_Bg_Spot15_Saku/z_bg_spot15_saku.h
index f7ac8d09c..35fcbee90 100644
--- a/src/overlays/actors/ovl_Bg_Spot15_Saku/z_bg_spot15_saku.h
+++ b/src/overlays/actors/ovl_Bg_Spot15_Saku/z_bg_spot15_saku.h
@@ -2,11 +2,11 @@
#define Z_BG_SPOT15_SAKU_H
#include "ultra64.h"
-#include "global.h"
+#include "z64actor.h"
struct BgSpot15Saku;
-typedef void (*BgSpot15SakuActionFunc)(struct BgSpot15Saku*, PlayState*);
+typedef void (*BgSpot15SakuActionFunc)(struct BgSpot15Saku*, struct PlayState*);
typedef struct BgSpot15Saku {
/* 0x0000 */ DynaPolyActor dyna;
diff --git a/src/overlays/actors/ovl_Bg_Spot16_Bombstone/z_bg_spot16_bombstone.c b/src/overlays/actors/ovl_Bg_Spot16_Bombstone/z_bg_spot16_bombstone.c
index f7ba17ed0..b014d7faf 100644
--- a/src/overlays/actors/ovl_Bg_Spot16_Bombstone/z_bg_spot16_bombstone.c
+++ b/src/overlays/actors/ovl_Bg_Spot16_Bombstone/z_bg_spot16_bombstone.c
@@ -1,9 +1,25 @@
#include "z_bg_spot16_bombstone.h"
-#include "assets/objects/object_spot16_obj/object_spot16_obj.h"
-#include "assets/objects/object_bombiwa/object_bombiwa.h"
#include "overlays/actors/ovl_En_Bombf/z_en_bombf.h"
#include "overlays/effects/ovl_Effect_Ss_Kakera/z_eff_ss_kakera.h"
+#include "libc64/qrand.h"
+#include "gfx.h"
+#include "gfx_setupdl.h"
+#include "ichain.h"
+#include "one_point_cutscene.h"
+#include "regs.h"
+#include "sfx.h"
+#include "sys_math3d.h"
+#include "sys_matrix.h"
+#include "z_lib.h"
+#include "z64effect.h"
+#include "z64play.h"
+#include "z64player.h"
+#include "z64save.h"
+
+#include "assets/objects/object_spot16_obj/object_spot16_obj.h"
+#include "assets/objects/object_bombiwa/object_bombiwa.h"
+
#define FLAGS ACTOR_FLAG_UPDATE_CULLING_DISABLED
void BgSpot16Bombstone_Init(Actor* thisx, PlayState* play);
@@ -152,7 +168,7 @@ void func_808B4C4C(BgSpot16Bombstone* this, PlayState* play) {
s32 pad;
Collider_InitJntSph(play, &this->colliderJntSph);
- Collider_SetJntSph(play, &this->colliderJntSph, &this->actor, &sJntSphInit, this->colliderElements);
+ Collider_SetJntSph(play, &this->colliderJntSph, &this->actor, &sJntSphInit, this->colliderJntSphElements);
this->colliderJntSph.elements[0].dim.worldSphere.center.x = this->actor.world.pos.x;
this->colliderJntSph.elements[0].dim.worldSphere.center.y = this->actor.world.pos.y + 50.0f;
this->colliderJntSph.elements[0].dim.worldSphere.center.z = this->actor.world.pos.z;
diff --git a/src/overlays/actors/ovl_Bg_Spot16_Bombstone/z_bg_spot16_bombstone.h b/src/overlays/actors/ovl_Bg_Spot16_Bombstone/z_bg_spot16_bombstone.h
index 01fb4cc3e..577bd3863 100644
--- a/src/overlays/actors/ovl_Bg_Spot16_Bombstone/z_bg_spot16_bombstone.h
+++ b/src/overlays/actors/ovl_Bg_Spot16_Bombstone/z_bg_spot16_bombstone.h
@@ -2,11 +2,11 @@
#define Z_BG_SPOT16_BOMBSTONE_H
#include "ultra64.h"
-#include "global.h"
+#include "z64actor.h"
struct BgSpot16Bombstone;
-typedef void (*BgSpot16BombstoneActionFunc)(struct BgSpot16Bombstone*, PlayState*);
+typedef void (*BgSpot16BombstoneActionFunc)(struct BgSpot16Bombstone*, struct PlayState*);
typedef struct BgSpot16Bombstone {
/* 0x0000 */ Actor actor;
@@ -18,7 +18,7 @@ typedef struct BgSpot16Bombstone {
/* 0x015C */ f32 sinRotation;
/* 0x0160 */ f32 cosRotation;
/* 0x0164 */ ColliderJntSph colliderJntSph;
- /* 0x0184 */ ColliderJntSphElement colliderElements[1];
+ /* 0x0184 */ ColliderJntSphElement colliderJntSphElements[1];
/* 0x01C4 */ ColliderCylinder colliderCylinder;
/* 0x0210 */ s16 unk_210;
/* 0x0212 */ s16 unk_212;
diff --git a/src/overlays/actors/ovl_Bg_Spot16_Doughnut/z_bg_spot16_doughnut.c b/src/overlays/actors/ovl_Bg_Spot16_Doughnut/z_bg_spot16_doughnut.c
index b71c0fd13..c6cf246bc 100644
--- a/src/overlays/actors/ovl_Bg_Spot16_Doughnut/z_bg_spot16_doughnut.c
+++ b/src/overlays/actors/ovl_Bg_Spot16_Doughnut/z_bg_spot16_doughnut.c
@@ -5,8 +5,16 @@
*/
#include "z_bg_spot16_doughnut.h"
-#include "assets/objects/object_efc_doughnut/object_efc_doughnut.h"
+
+#include "gfx.h"
+#include "gfx_setupdl.h"
+#include "ichain.h"
+#include "sys_matrix.h"
#include "terminal.h"
+#include "z64play.h"
+#include "z64save.h"
+
+#include "assets/objects/object_efc_doughnut/object_efc_doughnut.h"
#define FLAGS 0
diff --git a/src/overlays/actors/ovl_Bg_Spot16_Doughnut/z_bg_spot16_doughnut.h b/src/overlays/actors/ovl_Bg_Spot16_Doughnut/z_bg_spot16_doughnut.h
index 051e45cf5..3b7008ef2 100644
--- a/src/overlays/actors/ovl_Bg_Spot16_Doughnut/z_bg_spot16_doughnut.h
+++ b/src/overlays/actors/ovl_Bg_Spot16_Doughnut/z_bg_spot16_doughnut.h
@@ -2,7 +2,7 @@
#define Z_BG_SPOT16_DOUGHNUT_H
#include "ultra64.h"
-#include "global.h"
+#include "z64actor.h"
struct BgSpot16Doughnut;
diff --git a/src/overlays/actors/ovl_Bg_Spot17_Bakudankabe/z_bg_spot17_bakudankabe.c b/src/overlays/actors/ovl_Bg_Spot17_Bakudankabe/z_bg_spot17_bakudankabe.c
index c6eafbdd4..03f7b4514 100644
--- a/src/overlays/actors/ovl_Bg_Spot17_Bakudankabe/z_bg_spot17_bakudankabe.c
+++ b/src/overlays/actors/ovl_Bg_Spot17_Bakudankabe/z_bg_spot17_bakudankabe.c
@@ -6,6 +6,17 @@
#include "z_bg_spot17_bakudankabe.h"
#include "overlays/effects/ovl_Effect_Ss_Kakera/z_eff_ss_kakera.h"
+
+#include "libc64/qrand.h"
+#include "gfx.h"
+#include "gfx_setupdl.h"
+#include "ichain.h"
+#include "sfx.h"
+#include "sys_matrix.h"
+#include "z_lib.h"
+#include "z64effect.h"
+#include "z64play.h"
+
#include "assets/objects/object_spot17_obj/object_spot17_obj.h"
#include "assets/objects/gameplay_field_keep/gameplay_field_keep.h"
diff --git a/src/overlays/actors/ovl_Bg_Spot17_Bakudankabe/z_bg_spot17_bakudankabe.h b/src/overlays/actors/ovl_Bg_Spot17_Bakudankabe/z_bg_spot17_bakudankabe.h
index 892843540..fd88416dd 100644
--- a/src/overlays/actors/ovl_Bg_Spot17_Bakudankabe/z_bg_spot17_bakudankabe.h
+++ b/src/overlays/actors/ovl_Bg_Spot17_Bakudankabe/z_bg_spot17_bakudankabe.h
@@ -2,7 +2,7 @@
#define Z_BG_SPOT17_BAKUDANKABE_H
#include "ultra64.h"
-#include "global.h"
+#include "z64actor.h"
struct BgSpot17Bakudankabe;
diff --git a/src/overlays/actors/ovl_Bg_Spot17_Funen/z_bg_spot17_funen.c b/src/overlays/actors/ovl_Bg_Spot17_Funen/z_bg_spot17_funen.c
index 8ee2e9dad..84973d0b1 100644
--- a/src/overlays/actors/ovl_Bg_Spot17_Funen/z_bg_spot17_funen.c
+++ b/src/overlays/actors/ovl_Bg_Spot17_Funen/z_bg_spot17_funen.c
@@ -5,6 +5,13 @@
*/
#include "z_bg_spot17_funen.h"
+
+#include "gfx.h"
+#include "gfx_setupdl.h"
+#include "ichain.h"
+#include "sys_matrix.h"
+#include "z64play.h"
+
#include "assets/objects/object_spot17_obj/object_spot17_obj.h"
#define FLAGS (ACTOR_FLAG_UPDATE_CULLING_DISABLED | ACTOR_FLAG_DRAW_CULLING_DISABLED)
diff --git a/src/overlays/actors/ovl_Bg_Spot17_Funen/z_bg_spot17_funen.h b/src/overlays/actors/ovl_Bg_Spot17_Funen/z_bg_spot17_funen.h
index 6a44fa14c..737719ea2 100644
--- a/src/overlays/actors/ovl_Bg_Spot17_Funen/z_bg_spot17_funen.h
+++ b/src/overlays/actors/ovl_Bg_Spot17_Funen/z_bg_spot17_funen.h
@@ -2,7 +2,7 @@
#define Z_BG_SPOT17_FUNEN_H
#include "ultra64.h"
-#include "global.h"
+#include "z64actor.h"
struct BgSpot17Funen;
diff --git a/src/overlays/actors/ovl_Bg_Spot18_Basket/z_bg_spot18_basket.c b/src/overlays/actors/ovl_Bg_Spot18_Basket/z_bg_spot18_basket.c
index 75763a8c7..2f36cd503 100644
--- a/src/overlays/actors/ovl_Bg_Spot18_Basket/z_bg_spot18_basket.c
+++ b/src/overlays/actors/ovl_Bg_Spot18_Basket/z_bg_spot18_basket.c
@@ -90,7 +90,7 @@ void func_808B7710(Actor* thisx, PlayState* play) {
BgSpot18Basket* this = (BgSpot18Basket*)thisx;
Collider_InitJntSph(play, &this->colliderJntSph);
- Collider_SetJntSph(play, &this->colliderJntSph, &this->dyna.actor, &sJntSphInit, this->ColliderJntSphElements);
+ Collider_SetJntSph(play, &this->colliderJntSph, &this->dyna.actor, &sJntSphInit, this->colliderJntSphElements);
this->dyna.actor.colChkInfo.mass = MASS_IMMOVABLE;
}
diff --git a/src/overlays/actors/ovl_Bg_Spot18_Basket/z_bg_spot18_basket.h b/src/overlays/actors/ovl_Bg_Spot18_Basket/z_bg_spot18_basket.h
index eb198e09a..460a56fb1 100644
--- a/src/overlays/actors/ovl_Bg_Spot18_Basket/z_bg_spot18_basket.h
+++ b/src/overlays/actors/ovl_Bg_Spot18_Basket/z_bg_spot18_basket.h
@@ -11,7 +11,7 @@ typedef void (*BgSpot18BasketActionFunc)(struct BgSpot18Basket*, struct PlayStat
typedef struct BgSpot18Basket {
/* 0x0000 */ DynaPolyActor dyna;
/* 0x0164 */ ColliderJntSph colliderJntSph;
- /* 0x0184 */ ColliderJntSphElement ColliderJntSphElements[2];
+ /* 0x0184 */ ColliderJntSphElement colliderJntSphElements[2];
/* 0x0204 */ BgSpot18BasketActionFunc actionFunc;
/* 0x0208 */ f32 unk_208;
/* 0x020C */ s16 unk_20C;
diff --git a/src/overlays/actors/ovl_Bg_Spot18_Futa/z_bg_spot18_futa.c b/src/overlays/actors/ovl_Bg_Spot18_Futa/z_bg_spot18_futa.c
index cec6266a2..21bc50671 100644
--- a/src/overlays/actors/ovl_Bg_Spot18_Futa/z_bg_spot18_futa.c
+++ b/src/overlays/actors/ovl_Bg_Spot18_Futa/z_bg_spot18_futa.c
@@ -5,6 +5,11 @@
*/
#include "z_bg_spot18_futa.h"
+
+#include "ichain.h"
+#include "z_lib.h"
+#include "z64play.h"
+
#include "assets/objects/object_spot18_obj/object_spot18_obj.h"
#define FLAGS 0
diff --git a/src/overlays/actors/ovl_Bg_Spot18_Futa/z_bg_spot18_futa.h b/src/overlays/actors/ovl_Bg_Spot18_Futa/z_bg_spot18_futa.h
index 1150611cd..ff0c2cf8a 100644
--- a/src/overlays/actors/ovl_Bg_Spot18_Futa/z_bg_spot18_futa.h
+++ b/src/overlays/actors/ovl_Bg_Spot18_Futa/z_bg_spot18_futa.h
@@ -2,7 +2,7 @@
#define Z_BG_SPOT18_FUTA_H
#include "ultra64.h"
-#include "global.h"
+#include "z64actor.h"
struct BgSpot18Futa;
diff --git a/src/overlays/actors/ovl_Bg_Spot18_Obj/z_bg_spot18_obj.c b/src/overlays/actors/ovl_Bg_Spot18_Obj/z_bg_spot18_obj.c
index 505797f7e..7012e9023 100644
--- a/src/overlays/actors/ovl_Bg_Spot18_Obj/z_bg_spot18_obj.c
+++ b/src/overlays/actors/ovl_Bg_Spot18_Obj/z_bg_spot18_obj.c
@@ -6,6 +6,15 @@
*/
#include "z_bg_spot18_obj.h"
+
+#include "ichain.h"
+#include "sfx.h"
+#include "sys_math3d.h"
+#include "z_lib.h"
+#include "z64play.h"
+#include "z64player.h"
+#include "z64save.h"
+
#include "assets/objects/object_spot18_obj/object_spot18_obj.h"
#define FLAGS 0
diff --git a/src/overlays/actors/ovl_Bg_Spot18_Obj/z_bg_spot18_obj.h b/src/overlays/actors/ovl_Bg_Spot18_Obj/z_bg_spot18_obj.h
index 5e000f646..bfa758afd 100644
--- a/src/overlays/actors/ovl_Bg_Spot18_Obj/z_bg_spot18_obj.h
+++ b/src/overlays/actors/ovl_Bg_Spot18_Obj/z_bg_spot18_obj.h
@@ -2,12 +2,12 @@
#define Z_BG_SPOT18_OBJ_H
#include "ultra64.h"
-#include "global.h"
+#include "z64actor.h"
struct BgSpot18Obj;
-typedef void (*BgSpot18ObjActionFunc)(struct BgSpot18Obj*, PlayState*);
-typedef s32 (*BgSpot18ObjInitFunc)(struct BgSpot18Obj*, PlayState*);
+typedef void (*BgSpot18ObjActionFunc)(struct BgSpot18Obj*, struct PlayState*);
+typedef s32 (*BgSpot18ObjInitFunc)(struct BgSpot18Obj*, struct PlayState*);
typedef struct BgSpot18Obj {
/* 0x0000 */ DynaPolyActor dyna;
diff --git a/src/overlays/actors/ovl_Bg_Spot18_Shutter/z_bg_spot18_shutter.c b/src/overlays/actors/ovl_Bg_Spot18_Shutter/z_bg_spot18_shutter.c
index a078991b4..a92e53a4f 100644
--- a/src/overlays/actors/ovl_Bg_Spot18_Shutter/z_bg_spot18_shutter.c
+++ b/src/overlays/actors/ovl_Bg_Spot18_Shutter/z_bg_spot18_shutter.c
@@ -5,6 +5,14 @@
*/
#include "z_bg_spot18_shutter.h"
+
+#include "ichain.h"
+#include "one_point_cutscene.h"
+#include "sfx.h"
+#include "z_lib.h"
+#include "z64play.h"
+#include "z64save.h"
+
#include "assets/objects/object_spot18_obj/object_spot18_obj.h"
#define FLAGS (ACTOR_FLAG_UPDATE_CULLING_DISABLED | ACTOR_FLAG_DRAW_CULLING_DISABLED)
diff --git a/src/overlays/actors/ovl_Bg_Spot18_Shutter/z_bg_spot18_shutter.h b/src/overlays/actors/ovl_Bg_Spot18_Shutter/z_bg_spot18_shutter.h
index 161fa9bc9..737d30bdb 100644
--- a/src/overlays/actors/ovl_Bg_Spot18_Shutter/z_bg_spot18_shutter.h
+++ b/src/overlays/actors/ovl_Bg_Spot18_Shutter/z_bg_spot18_shutter.h
@@ -2,11 +2,11 @@
#define Z_BG_SPOT18_SHUTTER_H
#include "ultra64.h"
-#include "global.h"
+#include "z64actor.h"
struct BgSpot18Shutter;
-typedef void (*BgSpot18ShutterActionFunc)(struct BgSpot18Shutter*, PlayState*);
+typedef void (*BgSpot18ShutterActionFunc)(struct BgSpot18Shutter*, struct PlayState*);
typedef struct BgSpot18Shutter {
/* 0x0000 */ DynaPolyActor dyna;
diff --git a/src/overlays/actors/ovl_Bg_Toki_Hikari/z_bg_toki_hikari.c b/src/overlays/actors/ovl_Bg_Toki_Hikari/z_bg_toki_hikari.c
index 4ed9f8854..47550f22b 100644
--- a/src/overlays/actors/ovl_Bg_Toki_Hikari/z_bg_toki_hikari.c
+++ b/src/overlays/actors/ovl_Bg_Toki_Hikari/z_bg_toki_hikari.c
@@ -5,6 +5,14 @@
*/
#include "z_bg_toki_hikari.h"
+
+#include "gfx.h"
+#include "gfx_setupdl.h"
+#include "ichain.h"
+#include "sys_matrix.h"
+#include "z64play.h"
+#include "z64save.h"
+
#include "assets/objects/object_toki_objects/object_toki_objects.h"
#define FLAGS ACTOR_FLAG_DRAW_CULLING_DISABLED
diff --git a/src/overlays/actors/ovl_Bg_Toki_Hikari/z_bg_toki_hikari.h b/src/overlays/actors/ovl_Bg_Toki_Hikari/z_bg_toki_hikari.h
index b4c62dba9..3c49b61cc 100644
--- a/src/overlays/actors/ovl_Bg_Toki_Hikari/z_bg_toki_hikari.h
+++ b/src/overlays/actors/ovl_Bg_Toki_Hikari/z_bg_toki_hikari.h
@@ -2,11 +2,11 @@
#define Z_BG_TOKI_HIKARI_H
#include "ultra64.h"
-#include "global.h"
+#include "z64actor.h"
struct BgTokiHikari;
-typedef void (*BgTokiHikariActionFunc)(struct BgTokiHikari*, PlayState*);
+typedef void (*BgTokiHikariActionFunc)(struct BgTokiHikari*, struct PlayState*);
typedef struct BgTokiHikari {
/* 0x0000 */ Actor actor;
diff --git a/src/overlays/actors/ovl_Bg_Toki_Swd/z_bg_toki_swd.c b/src/overlays/actors/ovl_Bg_Toki_Swd/z_bg_toki_swd.c
index 8dcc00db3..a3a385696 100644
--- a/src/overlays/actors/ovl_Bg_Toki_Swd/z_bg_toki_swd.c
+++ b/src/overlays/actors/ovl_Bg_Toki_Swd/z_bg_toki_swd.c
@@ -5,6 +5,19 @@
*/
#include "z_bg_toki_swd.h"
+
+#include "gfx.h"
+#include "gfx_setupdl.h"
+#include "ichain.h"
+#include "seqcmd.h"
+#include "sequence.h"
+#include "sfx.h"
+#include "sys_matrix.h"
+#include "z64cutscene_flags.h"
+#include "z64play.h"
+#include "z64player.h"
+#include "z64save.h"
+
#include "assets/objects/object_toki_objects/object_toki_objects.h"
#define FLAGS ACTOR_FLAG_UPDATE_CULLING_DISABLED
diff --git a/src/overlays/actors/ovl_Bg_Toki_Swd/z_bg_toki_swd.h b/src/overlays/actors/ovl_Bg_Toki_Swd/z_bg_toki_swd.h
index 0a16201e6..5fdb9e069 100644
--- a/src/overlays/actors/ovl_Bg_Toki_Swd/z_bg_toki_swd.h
+++ b/src/overlays/actors/ovl_Bg_Toki_Swd/z_bg_toki_swd.h
@@ -2,11 +2,11 @@
#define Z_BG_TOKI_SWD_H
#include "ultra64.h"
-#include "global.h"
+#include "z64actor.h"
struct BgTokiSwd;
-typedef void (*BgTokiSwdActionFunc)(struct BgTokiSwd*, PlayState*);
+typedef void (*BgTokiSwdActionFunc)(struct BgTokiSwd*, struct PlayState*);
typedef struct BgTokiSwd {
/* 0x0000 */ Actor actor;
diff --git a/src/overlays/actors/ovl_Bg_Toki_Swd/z_bg_toki_swd_cutscene_data_1.c b/src/overlays/actors/ovl_Bg_Toki_Swd/z_bg_toki_swd_cutscene_data_1.c
index f11a8a551..123a797a7 100644
--- a/src/overlays/actors/ovl_Bg_Toki_Swd/z_bg_toki_swd_cutscene_data_1.c
+++ b/src/overlays/actors/ovl_Bg_Toki_Swd/z_bg_toki_swd_cutscene_data_1.c
@@ -1,5 +1,5 @@
-#include "z_bg_toki_swd.h"
#include "z64cutscene_commands.h"
+#include "z64player.h"
// clang-format off
CutsceneData gPullMasterSwordCs[] = {
diff --git a/src/overlays/actors/ovl_Bg_Toki_Swd/z_bg_toki_swd_cutscene_data_2.c b/src/overlays/actors/ovl_Bg_Toki_Swd/z_bg_toki_swd_cutscene_data_2.c
index de138790d..3e2790170 100644
--- a/src/overlays/actors/ovl_Bg_Toki_Swd/z_bg_toki_swd_cutscene_data_2.c
+++ b/src/overlays/actors/ovl_Bg_Toki_Swd/z_bg_toki_swd_cutscene_data_2.c
@@ -1,5 +1,5 @@
-#include "z_bg_toki_swd.h"
#include "z64cutscene_commands.h"
+#include "z64player.h"
// clang-format off
CutsceneData gPlaceMasterSwordCs[] = {
diff --git a/src/overlays/actors/ovl_Bg_Toki_Swd/z_bg_toki_swd_cutscene_data_3.c b/src/overlays/actors/ovl_Bg_Toki_Swd/z_bg_toki_swd_cutscene_data_3.c
index c6c5e4eb6..3e5ccb4ea 100644
--- a/src/overlays/actors/ovl_Bg_Toki_Swd/z_bg_toki_swd_cutscene_data_3.c
+++ b/src/overlays/actors/ovl_Bg_Toki_Swd/z_bg_toki_swd_cutscene_data_3.c
@@ -1,5 +1,5 @@
-#include "z_bg_toki_swd.h"
#include "z64cutscene_commands.h"
+#include "z64player.h"
// clang-format off
CutsceneData gRevealMasterSwordCs[] = {
diff --git a/src/overlays/actors/ovl_Bg_Treemouth/z_bg_treemouth.c b/src/overlays/actors/ovl_Bg_Treemouth/z_bg_treemouth.c
index d245fce7c..5a544c301 100644
--- a/src/overlays/actors/ovl_Bg_Treemouth/z_bg_treemouth.c
+++ b/src/overlays/actors/ovl_Bg_Treemouth/z_bg_treemouth.c
@@ -5,10 +5,22 @@
*/
#include "z_bg_treemouth.h"
-#include "versions.h"
-#include "assets/objects/object_spot04_objects/object_spot04_objects.h"
#include "overlays/effects/ovl_Effect_Ss_Hahen/z_eff_ss_hahen.h"
+#include "libc64/qrand.h"
+#include "gfx.h"
+#include "gfx_setupdl.h"
+#include "ichain.h"
+#include "sfx.h"
+#include "sys_matrix.h"
+#include "versions.h"
+#include "z64effect.h"
+#include "z64play.h"
+#include "z64player.h"
+#include "z64save.h"
+
+#include "assets/objects/object_spot04_objects/object_spot04_objects.h"
+
#define FLAGS (ACTOR_FLAG_UPDATE_CULLING_DISABLED | ACTOR_FLAG_DRAW_CULLING_DISABLED)
void BgTreemouth_Init(Actor* thisx, PlayState* play);
diff --git a/src/overlays/actors/ovl_Bg_Treemouth/z_bg_treemouth.h b/src/overlays/actors/ovl_Bg_Treemouth/z_bg_treemouth.h
index dc5a5f545..7fea6f8e7 100644
--- a/src/overlays/actors/ovl_Bg_Treemouth/z_bg_treemouth.h
+++ b/src/overlays/actors/ovl_Bg_Treemouth/z_bg_treemouth.h
@@ -2,11 +2,11 @@
#define Z_BG_TREEMOUTH_H
#include "ultra64.h"
-#include "global.h"
+#include "z64actor.h"
struct BgTreemouth;
-typedef void (*BgTreemouthActionFunc)(struct BgTreemouth*, PlayState*);
+typedef void (*BgTreemouthActionFunc)(struct BgTreemouth*, struct PlayState*);
typedef struct BgTreemouth {
/* 0x0000 */ DynaPolyActor dyna;
diff --git a/src/overlays/actors/ovl_Bg_Treemouth/z_bg_treemouth_cutscene_data.c b/src/overlays/actors/ovl_Bg_Treemouth/z_bg_treemouth_cutscene_data.c
index 020b2972b..c254318d4 100644
--- a/src/overlays/actors/ovl_Bg_Treemouth/z_bg_treemouth_cutscene_data.c
+++ b/src/overlays/actors/ovl_Bg_Treemouth/z_bg_treemouth_cutscene_data.c
@@ -1,5 +1,6 @@
-#include "z_bg_treemouth.h"
+#include "sequence.h"
#include "z64cutscene_commands.h"
+#include "z64player.h"
// clang-format off
CutsceneData gDekuTreeMeetingCs[] = {
diff --git a/src/overlays/actors/ovl_Bg_Umajump/z_bg_umajump.c b/src/overlays/actors/ovl_Bg_Umajump/z_bg_umajump.c
index dbd5148b7..63a73aaf4 100644
--- a/src/overlays/actors/ovl_Bg_Umajump/z_bg_umajump.c
+++ b/src/overlays/actors/ovl_Bg_Umajump/z_bg_umajump.c
@@ -5,6 +5,12 @@
*/
#include "z_bg_umajump.h"
+
+#include "ichain.h"
+#include "regs.h"
+#include "z64play.h"
+#include "z64save.h"
+
#include "assets/objects/object_umajump/object_umajump.h"
#define FLAGS 0
diff --git a/src/overlays/actors/ovl_Bg_Umajump/z_bg_umajump.h b/src/overlays/actors/ovl_Bg_Umajump/z_bg_umajump.h
index 19142ec4c..067b5195c 100644
--- a/src/overlays/actors/ovl_Bg_Umajump/z_bg_umajump.h
+++ b/src/overlays/actors/ovl_Bg_Umajump/z_bg_umajump.h
@@ -2,7 +2,7 @@
#define Z_BG_UMAJUMP_H
#include "ultra64.h"
-#include "global.h"
+#include "z64actor.h"
struct BgUmaJump;
diff --git a/src/overlays/actors/ovl_Bg_Vb_Sima/z_bg_vb_sima.c b/src/overlays/actors/ovl_Bg_Vb_Sima/z_bg_vb_sima.c
index 87e6c54ed..679519f1b 100644
--- a/src/overlays/actors/ovl_Bg_Vb_Sima/z_bg_vb_sima.c
+++ b/src/overlays/actors/ovl_Bg_Vb_Sima/z_bg_vb_sima.c
@@ -5,9 +5,21 @@
*/
#include "z_bg_vb_sima.h"
-#include "assets/objects/object_fd/object_fd.h"
#include "overlays/actors/ovl_Boss_Fd/z_boss_fd.h"
+#include "libc64/qrand.h"
+#include "gfx.h"
+#include "gfx_setupdl.h"
+#include "ichain.h"
+#include "rand.h"
+#include "sfx.h"
+#include "sys_matrix.h"
+#include "z_lib.h"
+#include "z64effect.h"
+#include "z64play.h"
+
+#include "assets/objects/object_fd/object_fd.h"
+
#define FLAGS 0
void BgVbSima_Init(Actor* thisx, PlayState* play);
diff --git a/src/overlays/actors/ovl_Bg_Vb_Sima/z_bg_vb_sima.h b/src/overlays/actors/ovl_Bg_Vb_Sima/z_bg_vb_sima.h
index c279ae393..1dcee1b59 100644
--- a/src/overlays/actors/ovl_Bg_Vb_Sima/z_bg_vb_sima.h
+++ b/src/overlays/actors/ovl_Bg_Vb_Sima/z_bg_vb_sima.h
@@ -2,7 +2,7 @@
#define Z_BG_VB_SIMA_H
#include "ultra64.h"
-#include "global.h"
+#include "z64actor.h"
struct BgVbSima;
diff --git a/src/overlays/actors/ovl_Bg_Ydan_Hasi/z_bg_ydan_hasi.c b/src/overlays/actors/ovl_Bg_Ydan_Hasi/z_bg_ydan_hasi.c
index df6e12f85..f759a9814 100644
--- a/src/overlays/actors/ovl_Bg_Ydan_Hasi/z_bg_ydan_hasi.c
+++ b/src/overlays/actors/ovl_Bg_Ydan_Hasi/z_bg_ydan_hasi.c
@@ -5,6 +5,16 @@
*/
#include "z_bg_ydan_hasi.h"
+
+#include "gfx.h"
+#include "gfx_setupdl.h"
+#include "ichain.h"
+#include "one_point_cutscene.h"
+#include "sfx.h"
+#include "sys_matrix.h"
+#include "z_lib.h"
+#include "z64play.h"
+
#include "assets/objects/object_ydan_objects/object_ydan_objects.h"
#define FLAGS (ACTOR_FLAG_UPDATE_CULLING_DISABLED | ACTOR_FLAG_DRAW_CULLING_DISABLED)
diff --git a/src/overlays/actors/ovl_Bg_Ydan_Hasi/z_bg_ydan_hasi.h b/src/overlays/actors/ovl_Bg_Ydan_Hasi/z_bg_ydan_hasi.h
index 616cd4250..a308c6ebc 100644
--- a/src/overlays/actors/ovl_Bg_Ydan_Hasi/z_bg_ydan_hasi.h
+++ b/src/overlays/actors/ovl_Bg_Ydan_Hasi/z_bg_ydan_hasi.h
@@ -2,11 +2,11 @@
#define Z_BG_YDAN_HASI_H
#include "ultra64.h"
-#include "global.h"
+#include "z64actor.h"
struct BgYdanHasi;
-typedef void (*BgYdanHasiActionFunc)(struct BgYdanHasi*, PlayState*);
+typedef void (*BgYdanHasiActionFunc)(struct BgYdanHasi*, struct PlayState*);
typedef struct BgYdanHasi {
/* 0x0000 */ DynaPolyActor dyna;
diff --git a/src/overlays/actors/ovl_Bg_Ydan_Maruta/z_bg_ydan_maruta.c b/src/overlays/actors/ovl_Bg_Ydan_Maruta/z_bg_ydan_maruta.c
index ea045b8eb..becd2a11c 100644
--- a/src/overlays/actors/ovl_Bg_Ydan_Maruta/z_bg_ydan_maruta.c
+++ b/src/overlays/actors/ovl_Bg_Ydan_Maruta/z_bg_ydan_maruta.c
@@ -5,6 +5,13 @@
*/
#include "z_bg_ydan_maruta.h"
+
+#include "ichain.h"
+#include "one_point_cutscene.h"
+#include "sfx.h"
+#include "z_lib.h"
+#include "z64play.h"
+
#include "assets/objects/object_ydan_objects/object_ydan_objects.h"
#define FLAGS 0
diff --git a/src/overlays/actors/ovl_Bg_Ydan_Maruta/z_bg_ydan_maruta.h b/src/overlays/actors/ovl_Bg_Ydan_Maruta/z_bg_ydan_maruta.h
index ff857fe1a..450c550b3 100644
--- a/src/overlays/actors/ovl_Bg_Ydan_Maruta/z_bg_ydan_maruta.h
+++ b/src/overlays/actors/ovl_Bg_Ydan_Maruta/z_bg_ydan_maruta.h
@@ -2,11 +2,11 @@
#define Z_BG_YDAN_MARUTA_H
#include "ultra64.h"
-#include "global.h"
+#include "z64actor.h"
struct BgYdanMaruta;
-typedef void (*BgYdanMarutaActionFunc)(struct BgYdanMaruta*, PlayState*);
+typedef void (*BgYdanMarutaActionFunc)(struct BgYdanMaruta*, struct PlayState*);
typedef struct BgYdanMaruta {
/* 0x0000 */ DynaPolyActor dyna;
diff --git a/src/overlays/actors/ovl_Bg_Ydan_Sp/z_bg_ydan_sp.c b/src/overlays/actors/ovl_Bg_Ydan_Sp/z_bg_ydan_sp.c
index 2d9b6f929..0034cfb4c 100644
--- a/src/overlays/actors/ovl_Bg_Ydan_Sp/z_bg_ydan_sp.c
+++ b/src/overlays/actors/ovl_Bg_Ydan_Sp/z_bg_ydan_sp.c
@@ -5,6 +5,21 @@
*/
#include "z_bg_ydan_sp.h"
+
+#include "libc64/qrand.h"
+#include "gfx.h"
+#include "gfx_setupdl.h"
+#include "ichain.h"
+#include "one_point_cutscene.h"
+#include "rand.h"
+#include "segmented_address.h"
+#include "sfx.h"
+#include "sys_matrix.h"
+#include "z_lib.h"
+#include "z64effect.h"
+#include "z64play.h"
+#include "z64player.h"
+
#include "assets/objects/object_ydan_objects/object_ydan_objects.h"
#define FLAGS 0
diff --git a/src/overlays/actors/ovl_Bg_Ydan_Sp/z_bg_ydan_sp.h b/src/overlays/actors/ovl_Bg_Ydan_Sp/z_bg_ydan_sp.h
index e134ac6f2..b2138e23a 100644
--- a/src/overlays/actors/ovl_Bg_Ydan_Sp/z_bg_ydan_sp.h
+++ b/src/overlays/actors/ovl_Bg_Ydan_Sp/z_bg_ydan_sp.h
@@ -2,11 +2,11 @@
#define Z_BG_YDAN_SP_H
#include "ultra64.h"
-#include "global.h"
+#include "z64actor.h"
struct BgYdanSp;
-typedef void (*BgYdanSpActionFunc)(struct BgYdanSp*, PlayState*);
+typedef void (*BgYdanSpActionFunc)(struct BgYdanSp*, struct PlayState*);
typedef struct BgYdanSp {
/* 0x0000 */ DynaPolyActor dyna;
diff --git a/src/overlays/actors/ovl_Bg_Zg/z_bg_zg.c b/src/overlays/actors/ovl_Bg_Zg/z_bg_zg.c
index 958e3c3f4..68bacc26c 100644
--- a/src/overlays/actors/ovl_Bg_Zg/z_bg_zg.c
+++ b/src/overlays/actors/ovl_Bg_Zg/z_bg_zg.c
@@ -5,8 +5,17 @@
*/
#include "z_bg_zg.h"
-#include "assets/objects/object_zg/object_zg.h"
+
+#include "gfx.h"
+#include "gfx_setupdl.h"
+#include "ichain.h"
+#include "regs.h"
+#include "sfx.h"
+#include "sys_matrix.h"
#include "terminal.h"
+#include "z64play.h"
+
+#include "assets/objects/object_zg/object_zg.h"
#define FLAGS ACTOR_FLAG_UPDATE_CULLING_DISABLED
diff --git a/src/overlays/actors/ovl_Bg_Zg/z_bg_zg.h b/src/overlays/actors/ovl_Bg_Zg/z_bg_zg.h
index a5355defd..c7f1add3a 100644
--- a/src/overlays/actors/ovl_Bg_Zg/z_bg_zg.h
+++ b/src/overlays/actors/ovl_Bg_Zg/z_bg_zg.h
@@ -2,12 +2,12 @@
#define Z_BG_ZG_H
#include "ultra64.h"
-#include "global.h"
+#include "z64actor.h"
struct BgZg;
-typedef void (*BgZgActionFunc)(struct BgZg*, PlayState*);
-typedef void (*BgZgDrawFunc)(struct BgZg*, PlayState*);
+typedef void (*BgZgActionFunc)(struct BgZg*, struct PlayState*);
+typedef void (*BgZgDrawFunc)(struct BgZg*, struct PlayState*);
typedef struct BgZg {
/* 0x0000 */ DynaPolyActor dyna;
diff --git a/src/overlays/actors/ovl_Boss_Dodongo/z_boss_dodongo.c b/src/overlays/actors/ovl_Boss_Dodongo/z_boss_dodongo.c
index d28f674f5..bfc700c6d 100644
--- a/src/overlays/actors/ovl_Boss_Dodongo/z_boss_dodongo.c
+++ b/src/overlays/actors/ovl_Boss_Dodongo/z_boss_dodongo.c
@@ -1,6 +1,27 @@
#include "z_boss_dodongo.h"
-#include "assets/objects/object_kingdodongo/object_kingdodongo.h"
#include "overlays/actors/ovl_Door_Warp1/z_door_warp1.h"
+
+#include "libc64/math64.h"
+#include "libc64/qrand.h"
+#include "attributes.h"
+#include "gfx.h"
+#include "gfx_setupdl.h"
+#include "ichain.h"
+#include "rand.h"
+#include "regs.h"
+#include "rumble.h"
+#include "segmented_address.h"
+#include "seqcmd.h"
+#include "sequence.h"
+#include "sfx.h"
+#include "sys_matrix.h"
+#include "z_lib.h"
+#include "z64effect.h"
+#include "z64play.h"
+#include "z64player.h"
+#include "z64save.h"
+
+#include "assets/objects/object_kingdodongo/object_kingdodongo.h"
#include "assets/scenes/dungeons/ddan_boss/ddan_boss_room_1.h"
#define FLAGS \
@@ -48,6 +69,7 @@ ActorProfile Boss_Dodongo_Profile = {
};
#include "z_boss_dodongo_data.inc.c"
+#include "assets/overlays/ovl_Boss_Dodongo/ovl_Boss_Dodongo.c"
static InitChainEntry sInitChain[] = {
ICHAIN_U8(attentionRangeType, ATTENTION_RANGE_5, ICHAIN_CONTINUE),
diff --git a/src/overlays/actors/ovl_Boss_Dodongo/z_boss_dodongo.h b/src/overlays/actors/ovl_Boss_Dodongo/z_boss_dodongo.h
index 098deb930..191487f13 100644
--- a/src/overlays/actors/ovl_Boss_Dodongo/z_boss_dodongo.h
+++ b/src/overlays/actors/ovl_Boss_Dodongo/z_boss_dodongo.h
@@ -2,11 +2,11 @@
#define Z_BOSS_DODONGO_H
#include "ultra64.h"
-#include "global.h"
+#include "z64actor.h"
struct BossDodongo;
-typedef void (*BossDodongoActionFunc)(struct BossDodongo*, PlayState*);
+typedef void (*BossDodongoActionFunc)(struct BossDodongo*, struct PlayState*);
#define BOSS_DODONGO_EFFECT_COUNT 80
diff --git a/src/overlays/actors/ovl_Boss_Dodongo/z_boss_dodongo_data.inc.c b/src/overlays/actors/ovl_Boss_Dodongo/z_boss_dodongo_data.inc.c
index d4ac8f7f0..3d0061bb3 100644
--- a/src/overlays/actors/ovl_Boss_Dodongo/z_boss_dodongo_data.inc.c
+++ b/src/overlays/actors/ovl_Boss_Dodongo/z_boss_dodongo_data.inc.c
@@ -1,4 +1,4 @@
-#include "z_boss_dodongo.h"
+#include "z64collision_check.h"
static u8 D_808C7000[] = {
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 0, 0, 1, 0, 0, 1, 1,
@@ -236,5 +236,3 @@ static ColliderJntSphInit sJntSphInit = {
};
static Vec3f sUnkZeroVec = { 0.0f, 0.0f, 0.0f };
-
-#include "assets/overlays/ovl_Boss_Dodongo/ovl_Boss_Dodongo.c"
diff --git a/src/overlays/actors/ovl_Boss_Fd/z_boss_fd.c b/src/overlays/actors/ovl_Boss_Fd/z_boss_fd.c
index e086659bf..12913dbe0 100644
--- a/src/overlays/actors/ovl_Boss_Fd/z_boss_fd.c
+++ b/src/overlays/actors/ovl_Boss_Fd/z_boss_fd.c
@@ -5,12 +5,31 @@
*/
#include "z_boss_fd.h"
-#include "assets/objects/object_fd/object_fd.h"
#include "overlays/actors/ovl_En_Vb_Ball/z_en_vb_ball.h"
#include "overlays/actors/ovl_Bg_Vb_Sima/z_bg_vb_sima.h"
#include "overlays/actors/ovl_Boss_Fd2/z_boss_fd2.h"
#include "overlays/actors/ovl_Door_Warp1/z_door_warp1.h"
+
+#include "libc64/math64.h"
+#include "libc64/qrand.h"
+#include "attributes.h"
+#include "gfx.h"
+#include "gfx_setupdl.h"
+#include "ichain.h"
+#include "rand.h"
+#include "segmented_address.h"
+#include "seqcmd.h"
+#include "sequence.h"
+#include "sfx.h"
+#include "sys_matrix.h"
+#include "z_lib.h"
+#include "z64effect.h"
+#include "z64play.h"
+#include "z64player.h"
+#include "z64save.h"
+
#include "assets/objects/gameplay_keep/gameplay_keep.h"
+#include "assets/objects/object_fd/object_fd.h"
#define FLAGS \
(ACTOR_FLAG_ATTENTION_ENABLED | ACTOR_FLAG_HOSTILE | ACTOR_FLAG_UPDATE_CULLING_DISABLED | \
diff --git a/src/overlays/actors/ovl_Boss_Fd/z_boss_fd.h b/src/overlays/actors/ovl_Boss_Fd/z_boss_fd.h
index eb2a1e0ca..1ec72040c 100644
--- a/src/overlays/actors/ovl_Boss_Fd/z_boss_fd.h
+++ b/src/overlays/actors/ovl_Boss_Fd/z_boss_fd.h
@@ -2,11 +2,11 @@
#define Z_BOSS_FD_H
#include "ultra64.h"
-#include "global.h"
+#include "z64actor.h"
struct BossFd;
-typedef void (*BossFdActionFunc)(struct BossFd*, PlayState*);
+typedef void (*BossFdActionFunc)(struct BossFd*, struct PlayState*);
typedef enum BossFdActionState {
/* -1 */ BOSSFD_WAIT_INTRO = -1,
diff --git a/src/overlays/actors/ovl_Boss_Fd/z_boss_fd_colchk.inc.c b/src/overlays/actors/ovl_Boss_Fd/z_boss_fd_colchk.inc.c
index 78dda01d3..1012117e5 100644
--- a/src/overlays/actors/ovl_Boss_Fd/z_boss_fd_colchk.inc.c
+++ b/src/overlays/actors/ovl_Boss_Fd/z_boss_fd_colchk.inc.c
@@ -1,6 +1,6 @@
#include "z64collision_check.h"
-static ColliderJntSphElementInit sJntSphItemsInit[19] = {
+static ColliderJntSphElementInit sJntSphElementsInit[19] = {
{
{
ELEM_MATERIAL_UNK3,
@@ -222,5 +222,5 @@ static ColliderJntSphInit sJntSphInit = {
COLSHAPE_JNTSPH,
},
19,
- sJntSphItemsInit,
+ sJntSphElementsInit,
};
diff --git a/src/overlays/actors/ovl_Boss_Fd2/z_boss_fd2.c b/src/overlays/actors/ovl_Boss_Fd2/z_boss_fd2.c
index 065f5ce03..27c5d82e9 100644
--- a/src/overlays/actors/ovl_Boss_Fd2/z_boss_fd2.c
+++ b/src/overlays/actors/ovl_Boss_Fd2/z_boss_fd2.c
@@ -5,10 +5,26 @@
*/
#include "z_boss_fd2.h"
-#include "assets/objects/object_fd2/object_fd2.h"
#include "overlays/actors/ovl_Boss_Fd/z_boss_fd.h"
#include "overlays/actors/ovl_Door_Warp1/z_door_warp1.h"
+
+#include "attributes.h"
+#include "gfx.h"
+#include "gfx_setupdl.h"
+#include "ichain.h"
+#include "rand.h"
+#include "segmented_address.h"
+#include "seqcmd.h"
+#include "sequence.h"
+#include "sfx.h"
+#include "sys_math.h"
+#include "sys_matrix.h"
#include "terminal.h"
+#include "z_lib.h"
+#include "z64play.h"
+#include "z64player.h"
+
+#include "assets/objects/object_fd2/object_fd2.h"
#define FLAGS \
(ACTOR_FLAG_ATTENTION_ENABLED | ACTOR_FLAG_HOSTILE | ACTOR_FLAG_UPDATE_CULLING_DISABLED | \
diff --git a/src/overlays/actors/ovl_Boss_Fd2/z_boss_fd2.h b/src/overlays/actors/ovl_Boss_Fd2/z_boss_fd2.h
index 15bb14c0c..d9fbde0ad 100644
--- a/src/overlays/actors/ovl_Boss_Fd2/z_boss_fd2.h
+++ b/src/overlays/actors/ovl_Boss_Fd2/z_boss_fd2.h
@@ -2,11 +2,11 @@
#define Z_BOSS_FD2_H
#include "ultra64.h"
-#include "global.h"
+#include "z64actor.h"
struct BossFd2;
-typedef void (*BossFd2ActionFunc)(struct BossFd2*, PlayState*);
+typedef void (*BossFd2ActionFunc)(struct BossFd2*, struct PlayState*);
typedef enum BossFd2Signal {
/* 0 */ FD2_SIGNAL_NONE,
diff --git a/src/overlays/actors/ovl_Boss_Ganon/z_boss_ganon.c b/src/overlays/actors/ovl_Boss_Ganon/z_boss_ganon.c
index a51e9fb4b..3459d841f 100644
--- a/src/overlays/actors/ovl_Boss_Ganon/z_boss_ganon.c
+++ b/src/overlays/actors/ovl_Boss_Ganon/z_boss_ganon.c
@@ -23,8 +23,7 @@
#include "z64effect.h"
#include "z64play.h"
#include "z64player.h"
-
-#include "global.h"
+#include "z64save.h"
#include "assets/overlays/ovl_Boss_Ganon/ovl_Boss_Ganon.h"
#include "assets/objects/object_ganon/object_ganon.h"
diff --git a/src/overlays/actors/ovl_Boss_Ganon2/z_boss_ganon2.c b/src/overlays/actors/ovl_Boss_Ganon2/z_boss_ganon2.c
index 8d73bf78c..3bf7e4b96 100644
--- a/src/overlays/actors/ovl_Boss_Ganon2/z_boss_ganon2.c
+++ b/src/overlays/actors/ovl_Boss_Ganon2/z_boss_ganon2.c
@@ -20,6 +20,7 @@
#include "z64effect.h"
#include "z64play.h"
#include "z64player.h"
+#include "z64save.h"
#include "assets/objects/object_ganon/object_ganon.h"
#include "assets/objects/object_ganon2/object_ganon2.h"
@@ -27,6 +28,9 @@
#include "assets/objects/object_geff/object_geff.h"
#include "assets/overlays/ovl_Boss_Ganon2/ovl_Boss_Ganon2.h"
+#pragma increment_block_number "gc-eu:128 gc-eu-mq:128 gc-jp:128 gc-jp-ce:128 gc-jp-mq:128 gc-us:128 gc-us-mq:128" \
+ "ique-cn:128"
+
#define FLAGS \
(ACTOR_FLAG_ATTENTION_ENABLED | ACTOR_FLAG_HOSTILE | ACTOR_FLAG_UPDATE_CULLING_DISABLED | \
ACTOR_FLAG_DRAW_CULLING_DISABLED)
@@ -87,7 +91,7 @@ static Vec3f D_80906D6C = { 0.0f, 0.0f, 500.0f };
static u8 D_80906D78 = 0;
-static ColliderJntSphElementInit sJntSphItemsInit1[] = {
+static ColliderJntSphElementInit sJntSphElementsInit1[] = {
{
{
ELEM_MATERIAL_UNK0,
@@ -275,11 +279,11 @@ static ColliderJntSphInit sJntSphInit1 = {
OC2_FIRST_ONLY | OC2_TYPE_1,
COLSHAPE_JNTSPH,
},
- ARRAY_COUNT(sJntSphItemsInit1),
- sJntSphItemsInit1,
+ ARRAY_COUNT(sJntSphElementsInit1),
+ sJntSphElementsInit1,
};
-static ColliderJntSphElementInit sJntSphItemsInit2[] = {
+static ColliderJntSphElementInit sJntSphElementsInit2[] = {
{
{
ELEM_MATERIAL_UNK2,
@@ -313,8 +317,8 @@ static ColliderJntSphInit sJntSphInit2 = {
OC2_TYPE_1,
COLSHAPE_JNTSPH,
},
- ARRAY_COUNT(sJntSphItemsInit2),
- sJntSphItemsInit2,
+ ARRAY_COUNT(sJntSphElementsInit2),
+ sJntSphElementsInit2,
};
static Vec3f D_8090EB20;
diff --git a/src/overlays/actors/ovl_Boss_Ganondrof/z_boss_ganondrof.c b/src/overlays/actors/ovl_Boss_Ganondrof/z_boss_ganondrof.c
index 7473f8d2d..cc30350bc 100644
--- a/src/overlays/actors/ovl_Boss_Ganondrof/z_boss_ganondrof.c
+++ b/src/overlays/actors/ovl_Boss_Ganondrof/z_boss_ganondrof.c
@@ -5,13 +5,32 @@
*/
#include "z_boss_ganondrof.h"
-#include "assets/objects/object_gnd/object_gnd.h"
#include "overlays/actors/ovl_En_fHG/z_en_fhg.h"
#include "overlays/actors/ovl_En_Fhg_Fire/z_en_fhg_fire.h"
#include "overlays/effects/ovl_Effect_Ss_Fhg_Flash/z_eff_ss_fhg_flash.h"
#include "overlays/effects/ovl_Effect_Ss_Hahen/z_eff_ss_hahen.h"
#include "overlays/actors/ovl_Door_Warp1/z_door_warp1.h"
+#include "libc64/math64.h"
+#include "libc64/qrand.h"
+#include "attributes.h"
+#include "gfx.h"
+#include "gfx_setupdl.h"
+#include "ichain.h"
+#include "rand.h"
+#include "segmented_address.h"
+#include "seqcmd.h"
+#include "sequence.h"
+#include "sfx.h"
+#include "sys_matrix.h"
+#include "z_lib.h"
+#include "z64effect.h"
+#include "z64light.h"
+#include "z64play.h"
+#include "z64player.h"
+
+#include "assets/objects/object_gnd/object_gnd.h"
+
#define FLAGS \
(ACTOR_FLAG_ATTENTION_ENABLED | ACTOR_FLAG_HOSTILE | ACTOR_FLAG_UPDATE_CULLING_DISABLED | \
ACTOR_FLAG_DRAW_CULLING_DISABLED)
@@ -294,10 +313,10 @@ void BossGanondrof_Init(Actor* thisx, PlayState* play) {
BossGanondrof_SetupPaintings(this);
}
- Collider_InitCylinder(play, &this->colliderBody);
- Collider_InitCylinder(play, &this->colliderSpear);
- Collider_SetCylinder(play, &this->colliderBody, &this->actor, &sCylinderInitBody);
- Collider_SetCylinder(play, &this->colliderSpear, &this->actor, &sCylinderInitSpear);
+ Collider_InitCylinder(play, &this->bodyCollider);
+ Collider_InitCylinder(play, &this->spearCollider);
+ Collider_SetCylinder(play, &this->bodyCollider, &this->actor, &sCylinderInitBody);
+ Collider_SetCylinder(play, &this->spearCollider, &this->actor, &sCylinderInitSpear);
this->actor.flags &= ~ACTOR_FLAG_ATTENTION_ENABLED;
if (Flags_GetClear(play, play->roomCtx.curRoom.num)) {
Actor_Kill(&this->actor);
@@ -317,8 +336,8 @@ void BossGanondrof_Destroy(Actor* thisx, PlayState* play) {
PRINTF("DT1\n");
SkelAnime_Free(&this->skelAnime, play);
- Collider_DestroyCylinder(play, &this->colliderBody);
- Collider_DestroyCylinder(play, &this->colliderSpear);
+ Collider_DestroyCylinder(play, &this->bodyCollider);
+ Collider_DestroyCylinder(play, &this->spearCollider);
if (this->actor.params == GND_REAL_BOSS) {
LightContext_RemoveLight(play, &play->lightCtx, this->lightNode);
}
@@ -461,9 +480,9 @@ void BossGanondrof_Paintings(BossGanondrof* this, PlayState* play) {
if (this->flyMode != GND_FLY_PAINTING) {
BossGanondrof_SetupNeutral(this, -20.0f);
this->timers[0] = 100;
- this->colliderBody.dim.radius = 20;
- this->colliderBody.dim.height = 60;
- this->colliderBody.dim.yShift = -33;
+ this->bodyCollider.dim.radius = 20;
+ this->bodyCollider.dim.height = 60;
+ this->bodyCollider.dim.yShift = -33;
Actor_PlaySfx(&this->actor, NA_SE_EN_FANTOM_LAUGH);
this->actor.naviEnemyId = NAVI_ENEMY_PHANTOM_GANON_PHASE_2;
} else {
@@ -775,7 +794,7 @@ void BossGanondrof_SetupBlock(BossGanondrof* this, PlayState* play) {
}
void BossGanondrof_Block(BossGanondrof* this, PlayState* play) {
- this->colliderBody.base.colMaterial = COL_MATERIAL_METAL;
+ this->bodyCollider.base.colMaterial = COL_MATERIAL_METAL;
SkelAnime_Update(&this->skelAnime);
this->actor.world.pos.x += this->actor.velocity.x;
this->actor.world.pos.z += this->actor.velocity.z;
@@ -804,7 +823,7 @@ void BossGanondrof_Charge(BossGanondrof* this, PlayState* play) {
f32 dxCenter = thisx->world.pos.x - GND_BOSSROOM_CENTER_X;
f32 dzCenter = thisx->world.pos.z - GND_BOSSROOM_CENTER_Z;
- this->colliderBody.base.colMaterial = COL_MATERIAL_METAL;
+ this->bodyCollider.base.colMaterial = COL_MATERIAL_METAL;
SkelAnime_Update(&this->skelAnime);
switch (this->work[GND_ACTION_STATE]) {
case CHARGE_WINDUP:
@@ -1231,13 +1250,13 @@ void BossGanondrof_CollisionCheck(BossGanondrof* this, PlayState* play) {
if (this->work[GND_INVINC_TIMER] != 0) {
this->work[GND_INVINC_TIMER]--;
this->returnCount = 0;
- this->colliderBody.base.acFlags &= ~AC_HIT;
+ this->bodyCollider.base.acFlags &= ~AC_HIT;
} else {
- acHit = this->colliderBody.base.acFlags & AC_HIT;
+ acHit = this->bodyCollider.base.acFlags & AC_HIT;
if ((acHit && ((s8)this->actor.colChkInfo.health > 0)) || (this->returnCount != 0)) {
if (acHit) {
- this->colliderBody.base.acFlags &= ~AC_HIT;
- acHitElem = this->colliderBody.elem.acHitElem;
+ this->bodyCollider.base.acFlags &= ~AC_HIT;
+ acHitElem = this->bodyCollider.elem.acHitElem;
}
if (this->flyMode != GND_FLY_PAINTING) {
if (acHit && (this->actionFunc != BossGanondrof_Stunned) &&
@@ -1300,7 +1319,7 @@ void BossGanondrof_Update(Actor* thisx, PlayState* play) {
PRINTF("MOVE START %d\n", this->actor.params);
this->actor.flags &= ~ACTOR_FLAG_HOOKSHOT_PULLS_PLAYER;
- this->colliderBody.base.colMaterial = COL_MATERIAL_HIT3;
+ this->bodyCollider.base.colMaterial = COL_MATERIAL_HIT3;
if (this->killActor) {
Actor_Kill(&this->actor);
return;
@@ -1328,20 +1347,20 @@ void BossGanondrof_Update(Actor* thisx, PlayState* play) {
}
PRINTF("MOVE END\n");
- BossGanondrof_SetColliderPos(&this->targetPos, &this->colliderBody);
- BossGanondrof_SetColliderPos(&this->spearTip, &this->colliderSpear);
+ BossGanondrof_SetColliderPos(&this->targetPos, &this->bodyCollider);
+ BossGanondrof_SetColliderPos(&this->spearTip, &this->spearCollider);
if ((this->flyMode == GND_FLY_PAINTING) && !horse->bossGndInPainting) {
- CollisionCheck_SetAC(play, &play->colChkCtx, &this->colliderBody.base);
+ CollisionCheck_SetAC(play, &play->colChkCtx, &this->bodyCollider.base);
}
if ((this->actionFunc == BossGanondrof_Stunned) && (this->timers[0] > 1)) {
- CollisionCheck_SetAC(play, &play->colChkCtx, &this->colliderBody.base);
- CollisionCheck_SetOC(play, &play->colChkCtx, &this->colliderBody.base);
+ CollisionCheck_SetAC(play, &play->colChkCtx, &this->bodyCollider.base);
+ CollisionCheck_SetOC(play, &play->colChkCtx, &this->bodyCollider.base);
} else if (this->actionFunc == BossGanondrof_Block) {
- CollisionCheck_SetAC(play, &play->colChkCtx, &this->colliderBody.base);
+ CollisionCheck_SetAC(play, &play->colChkCtx, &this->bodyCollider.base);
} else if (this->actionFunc == BossGanondrof_Charge) {
- CollisionCheck_SetAC(play, &play->colChkCtx, &this->colliderBody.base);
- CollisionCheck_SetAT(play, &play->colChkCtx, &this->colliderBody.base);
- CollisionCheck_SetAT(play, &play->colChkCtx, &this->colliderSpear.base);
+ CollisionCheck_SetAC(play, &play->colChkCtx, &this->bodyCollider.base);
+ CollisionCheck_SetAT(play, &play->colChkCtx, &this->bodyCollider.base);
+ CollisionCheck_SetAT(play, &play->colChkCtx, &this->spearCollider.base);
}
this->actor.focus.pos = this->targetPos;
diff --git a/src/overlays/actors/ovl_Boss_Ganondrof/z_boss_ganondrof.h b/src/overlays/actors/ovl_Boss_Ganondrof/z_boss_ganondrof.h
index 142aea02b..1fed43e42 100644
--- a/src/overlays/actors/ovl_Boss_Ganondrof/z_boss_ganondrof.h
+++ b/src/overlays/actors/ovl_Boss_Ganondrof/z_boss_ganondrof.h
@@ -2,11 +2,12 @@
#define Z_BOSS_GANONDROF_H
#include "ultra64.h"
-#include "global.h"
+#include "z64actor.h"
+#include "z64light.h"
struct BossGanondrof;
-typedef void (*BossGanondrofActionFunc)(struct BossGanondrof*, PlayState*);
+typedef void (*BossGanondrofActionFunc)(struct BossGanondrof*, struct PlayState*);
#define GND_REAL_BOSS 1
#define GND_FAKE_BOSS 10
@@ -97,8 +98,8 @@ typedef struct BossGanondrof {
/* 0x0454 */ f32 rideRotY[30]; // possibly only 25 used
/* 0x04CC */ LightNode* lightNode;
/* 0x04D0 */ LightInfo lightInfo;
- /* 0x04E0 */ ColliderCylinder colliderBody;
- /* 0x052C */ ColliderCylinder colliderSpear;
+ /* 0x04E0 */ ColliderCylinder bodyCollider;
+ /* 0x052C */ ColliderCylinder spearCollider;
} BossGanondrof; // size = 0x0578
#endif
diff --git a/src/overlays/actors/ovl_Boss_Goma/z_boss_goma.c b/src/overlays/actors/ovl_Boss_Goma/z_boss_goma.c
index 5f24de4df..c1719b8e6 100644
--- a/src/overlays/actors/ovl_Boss_Goma/z_boss_goma.c
+++ b/src/overlays/actors/ovl_Boss_Goma/z_boss_goma.c
@@ -27,6 +27,7 @@
#include "z64environment.h"
#include "z64play.h"
#include "z64player.h"
+#include "z64save.h"
#include "assets/objects/object_goma/object_goma.h"
@@ -89,7 +90,7 @@ ActorProfile Boss_Goma_Profile = {
/**/ BossGoma_Draw,
};
-static ColliderJntSphElementInit sColliderJntSphElementInit[13] = {
+static ColliderJntSphElementInit sColliderJntSphElementsInit[13] = {
{
{
ELEM_MATERIAL_UNK3,
@@ -245,7 +246,7 @@ static ColliderJntSphInit sColliderJntSphInit = {
COLSHAPE_JNTSPH,
},
13,
- sColliderJntSphElementInit,
+ sColliderJntSphElementsInit,
};
static u8 sClearPixelTableFirstPass[16 * 16] = {
diff --git a/src/overlays/actors/ovl_Boss_Mo/z_boss_mo.c b/src/overlays/actors/ovl_Boss_Mo/z_boss_mo.c
index fc82d8000..cbb82fd9a 100644
--- a/src/overlays/actors/ovl_Boss_Mo/z_boss_mo.c
+++ b/src/overlays/actors/ovl_Boss_Mo/z_boss_mo.c
@@ -5,10 +5,37 @@
*/
#include "z_boss_mo.h"
-#include "assets/objects/object_mo/object_mo.h"
#include "overlays/actors/ovl_Door_Warp1/z_door_warp1.h"
-#include "assets/objects/gameplay_keep/gameplay_keep.h"
+
+#include "libc64/math64.h"
+#include "libc64/qrand.h"
+#include "attributes.h"
+#include "controller.h"
+#include "gfx.h"
+#include "gfx_setupdl.h"
+#include "ichain.h"
+#include "letterbox.h"
+#include "rand.h"
+#include "regs.h"
+#include "rumble.h"
+#include "segmented_address.h"
+#include "seqcmd.h"
+#include "sequence.h"
+#include "sfx.h"
+#include "sys_matrix.h"
#include "terminal.h"
+#include "z_lib.h"
+#include "z64audio.h"
+#include "z64effect.h"
+#include "z64play.h"
+#include "z64player.h"
+#include "z64save.h"
+#include "z64skin_matrix.h"
+
+#include "global.h"
+
+#include "assets/objects/gameplay_keep/gameplay_keep.h"
+#include "assets/objects/object_mo/object_mo.h"
#pragma increment_block_number "gc-eu:128 gc-eu-mq:128 gc-jp:128 gc-jp-ce:128 gc-jp-mq:128 gc-us:128 gc-us-mq:128" \
"pal-1.0:128 pal-1.1:128"
@@ -389,7 +416,7 @@ void BossMo_Init(Actor* thisx, PlayState* play2) {
this->actor.world.pos.y = MO_WATER_LEVEL(play);
this->actor.prevPos = this->targetPos = this->actor.world.pos;
Collider_InitJntSph(play, &this->tentCollider);
- Collider_SetJntSph(play, &this->tentCollider, &this->actor, &sJntSphInit, this->tentElements);
+ Collider_SetJntSph(play, &this->tentCollider, &this->actor, &sJntSphInit, this->tentColliderElements);
this->tentMaxAngle = 1.0f;
}
}
@@ -1151,7 +1178,7 @@ void BossMo_TentCollisionCheck(BossMo* this, PlayState* play) {
s16 i2;
ColliderElement* acHitElem;
- for (i1 = 0; i1 < ARRAY_COUNT(this->tentElements); i1++) {
+ for (i1 = 0; i1 < ARRAY_COUNT(this->tentColliderElements); i1++) {
if (this->tentCollider.elements[i1].base.acElemFlags & ACELEM_HIT) {
for (i2 = 0; i2 < 19; i2++) {
diff --git a/src/overlays/actors/ovl_Boss_Mo/z_boss_mo.h b/src/overlays/actors/ovl_Boss_Mo/z_boss_mo.h
index 1b7641817..88867ceed 100644
--- a/src/overlays/actors/ovl_Boss_Mo/z_boss_mo.h
+++ b/src/overlays/actors/ovl_Boss_Mo/z_boss_mo.h
@@ -2,11 +2,11 @@
#define Z_BOSS_MO_H
#include "ultra64.h"
-#include "global.h"
+#include "z64actor.h"
struct BossMo;
-typedef void (*BossMoActionFunc)(struct BossMo*, PlayState*);
+typedef void (*BossMoActionFunc)(struct BossMo*, struct PlayState*);
typedef enum BossMoTentS16Var {
/* 0 */ MO_TENT_ACTION_STATE,
@@ -124,7 +124,7 @@ typedef struct BossMo {
/* 0x100C */ f32 subCamYawShake;
/* 0x1010 */ Vec3f tentTipPos;
/* 0x101C */ ColliderJntSph tentCollider;
- /* 0x103C */ ColliderJntSphElement tentElements[19];
+ /* 0x103C */ ColliderJntSphElement tentColliderElements[19];
/* 0x14FC */ ColliderCylinder coreCollider;
/* 0x1548 */ char unk_1548[0x44];
} BossMo; // size = 0x158C
diff --git a/src/overlays/actors/ovl_Boss_Sst/z_boss_sst.c b/src/overlays/actors/ovl_Boss_Sst/z_boss_sst.c
index 2e7a467c2..3cb53006c 100644
--- a/src/overlays/actors/ovl_Boss_Sst/z_boss_sst.c
+++ b/src/overlays/actors/ovl_Boss_Sst/z_boss_sst.c
@@ -26,15 +26,14 @@
#include "z64effect.h"
#include "z64play.h"
#include "z64player.h"
+#include "z64save.h"
#include "z64skin_matrix.h"
-#include "global.h"
-
#include "assets/objects/object_sst/object_sst.h"
#include "assets/objects/gameplay_keep/gameplay_keep.h"
-#pragma increment_block_number "gc-eu:128 gc-eu-mq:128 gc-jp:128 gc-jp-ce:128 gc-jp-mq:128 gc-us:128 gc-us-mq:128" \
- "pal-1.0:128 pal-1.1:128"
+#pragma increment_block_number "gc-eu:0 gc-eu-mq:0 gc-jp:0 gc-jp-ce:0 gc-jp-mq:0 gc-us:0 gc-us-mq:0 pal-1.0:128" \
+ "pal-1.1:128"
#define FLAGS \
(ACTOR_FLAG_ATTENTION_ENABLED | ACTOR_FLAG_HOSTILE | ACTOR_FLAG_UPDATE_CULLING_DISABLED | \
@@ -296,7 +295,7 @@ void BossSst_Init(Actor* thisx, PlayState* play2) {
BossSst* this = (BossSst*)thisx;
Actor_ProcessInitChain(&this->actor, sInitChain);
- Collider_InitCylinder(play, &this->colliderCyl);
+ Collider_InitCylinder(play, &this->colliderCylinder);
Collider_InitJntSph(play, &this->colliderJntSph);
CollisionCheck_SetInfo(&this->actor.colChkInfo, &sDamageTable, &sColChkInfoInit);
Flags_SetSwitch(play, 0x14);
@@ -306,8 +305,8 @@ void BossSst_Init(Actor* thisx, PlayState* play2) {
SkelAnime_InitFlex(play, &this->skelAnime, &gBongoHeadSkel, &gBongoHeadEyeOpenIdleAnim, this->jointTable,
this->morphTable, 45);
ActorShape_Init(&this->actor.shape, 70000.0f, ActorShadow_DrawCircle, 95.0f);
- Collider_SetJntSph(play, &this->colliderJntSph, &this->actor, &sJntSphInitHead, this->colliderItems);
- Collider_SetCylinder(play, &this->colliderCyl, &this->actor, &sCylinderInitHead);
+ Collider_SetJntSph(play, &this->colliderJntSph, &this->actor, &sJntSphInitHead, this->colliderJntSphElements);
+ Collider_SetCylinder(play, &this->colliderCylinder, &this->actor, &sCylinderInitHead);
sHead = this;
this->actor.world.pos.x = ROOM_CENTER_X + 50.0f;
this->actor.world.pos.y = ROOM_CENTER_Y + 0.0f;
@@ -339,8 +338,8 @@ void BossSst_Init(Actor* thisx, PlayState* play2) {
Actor_ChangeCategory(play, &play->actorCtx, &this->actor, ACTORCAT_BOSS);
}
} else {
- Collider_SetJntSph(play, &this->colliderJntSph, &this->actor, &sJntSphInitHand, this->colliderItems);
- Collider_SetCylinder(play, &this->colliderCyl, &this->actor, &sCylinderInitHand);
+ Collider_SetJntSph(play, &this->colliderJntSph, &this->actor, &sJntSphInitHand, this->colliderJntSphElements);
+ Collider_SetCylinder(play, &this->colliderCylinder, &this->actor, &sCylinderInitHand);
if (this->actor.params == BONGO_LEFT_HAND) {
SkelAnime_InitFlex(play, &this->skelAnime, &gBongoLeftHandSkel, &gBongoLeftHandIdleAnim, this->jointTable,
this->morphTable, 27);
@@ -365,7 +364,7 @@ void BossSst_Destroy(Actor* thisx, PlayState* play) {
BossSst* this = (BossSst*)thisx;
Collider_DestroyJntSph(play, &this->colliderJntSph);
- Collider_DestroyCylinder(play, &this->colliderCyl);
+ Collider_DestroyCylinder(play, &this->colliderCylinder);
Audio_StopSfxByPos(&this->center);
}
@@ -727,7 +726,7 @@ void BossSst_HeadDamagedHand(BossSst* this, PlayState* play) {
void BossSst_HeadSetupReadyCharge(BossSst* this) {
Animation_MorphToLoop(&this->skelAnime, &gBongoHeadEyeOpenIdleAnim, -5.0f);
this->actor.speed = 0.0f;
- this->colliderCyl.base.acFlags |= AC_ON;
+ this->colliderCylinder.base.acFlags |= AC_ON;
this->actionFunc = BossSst_HeadReadyCharge;
}
@@ -803,7 +802,7 @@ void BossSst_HeadSetupEndCharge(BossSst* this) {
Animation_MorphToLoop(&this->skelAnime, &gBongoHeadEyeCloseIdleAnim, -20.0f);
this->targetYaw = Actor_WorldYawTowardPoint(&this->actor, &sRoomCenter);
this->colliderJntSph.base.atFlags &= ~(AT_ON | AT_HIT);
- this->colliderCyl.base.acFlags &= ~AC_ON;
+ this->colliderCylinder.base.acFlags &= ~AC_ON;
this->radius *= -1.0f;
this->actionFunc = BossSst_HeadEndCharge;
}
@@ -820,7 +819,7 @@ void BossSst_HeadEndCharge(BossSst* this, PlayState* play) {
void BossSst_HeadSetupFrozenHand(BossSst* this) {
Animation_MorphToLoop(&this->skelAnime, &gBongoHeadEyeOpenIdleAnim, -5.0f);
this->ready = false;
- this->colliderCyl.base.acFlags |= AC_ON;
+ this->colliderCylinder.base.acFlags |= AC_ON;
this->actionFunc = BossSst_HeadFrozenHand;
}
@@ -833,7 +832,7 @@ void BossSst_HeadFrozenHand(BossSst* this, PlayState* play) {
void BossSst_HeadSetupUnfreezeHand(BossSst* this) {
Animation_MorphToPlayOnce(&this->skelAnime, &gBongoHeadEyeCloseAnim, -5.0f);
- this->colliderCyl.base.acFlags &= ~AC_ON;
+ this->colliderCylinder.base.acFlags &= ~AC_ON;
this->actionFunc = BossSst_HeadUnfreezeHand;
}
@@ -848,7 +847,7 @@ void BossSst_HeadSetupStunned(BossSst* this) {
Actor_SetColorFilter(&this->actor, COLORFILTER_COLORFLAG_BLUE, 255, COLORFILTER_BUFFLAG_OPA,
Animation_GetLastFrame(&gBongoHeadKnockoutAnim));
this->colliderJntSph.base.atFlags &= ~(AT_ON | AT_HIT);
- this->colliderCyl.base.acFlags &= ~AC_ON;
+ this->colliderCylinder.base.acFlags &= ~AC_ON;
this->vVanish = false;
this->actor.flags &= ~ACTOR_FLAG_REACT_TO_LENS;
BossSst_HeadSfx(this, NA_SE_EN_SHADEST_FREEZE);
@@ -900,8 +899,8 @@ void BossSst_HeadStunned(BossSst* this, PlayState* play) {
void BossSst_HeadSetupVulnerable(BossSst* this) {
Animation_MorphToLoop(&this->skelAnime, &gBongoHeadStunnedAnim, -5.0f);
- this->colliderCyl.base.acFlags |= AC_ON;
- this->colliderCyl.elem.acDmgInfo.dmgFlags = DMG_SWORD | DMG_DEKU_STICK;
+ this->colliderCylinder.base.acFlags |= AC_ON;
+ this->colliderCylinder.elem.acDmgInfo.dmgFlags = DMG_SWORD | DMG_DEKU_STICK;
this->actor.speed = 0.0f;
this->colliderJntSph.elements[10].base.acElemFlags |= (ACELEM_ON | ACELEM_HOOKABLE);
this->colliderJntSph.elements[0].base.acElemFlags &= ~ACELEM_ON;
@@ -942,7 +941,7 @@ void BossSst_HeadSetupDamage(BossSst* this) {
Animation_GetLastFrame(&gBongoHeadDamageAnim));
Actor_SetColorFilter(&sHands[RIGHT]->actor, COLORFILTER_COLORFLAG_RED, 255, COLORFILTER_BUFFLAG_OPA,
Animation_GetLastFrame(&gBongoHeadDamageAnim));
- this->colliderCyl.base.acFlags &= ~AC_ON;
+ this->colliderCylinder.base.acFlags &= ~AC_ON;
BossSst_HeadSfx(this, NA_SE_EN_SHADEST_DAMAGE);
this->actionFunc = BossSst_HeadDamage;
}
@@ -959,8 +958,8 @@ void BossSst_HeadDamage(BossSst* this, PlayState* play) {
void BossSst_HeadSetupRecover(BossSst* this) {
Animation_MorphToPlayOnce(&this->skelAnime, &gBongoHeadRecoverAnim, -5.0f);
- this->colliderCyl.base.acFlags &= ~AC_ON;
- this->colliderCyl.elem.acDmgInfo.dmgFlags = DMG_DEFAULT;
+ this->colliderCylinder.base.acFlags &= ~AC_ON;
+ this->colliderCylinder.elem.acDmgInfo.dmgFlags = DMG_DEFAULT;
this->colliderJntSph.elements[10].base.acElemFlags &= ~(ACELEM_ON | ACELEM_HOOKABLE);
this->colliderJntSph.elements[0].base.acElemFlags |= ACELEM_ON;
this->vVanish = true;
@@ -1046,7 +1045,7 @@ void BossSst_HeadSetupDeath(BossSst* this, PlayState* play) {
Actor_SetColorFilter(&sHands[LEFT]->actor, COLORFILTER_COLORFLAG_RED, 255, COLORFILTER_BUFFLAG_OPA, 60);
Actor_SetColorFilter(&sHands[RIGHT]->actor, COLORFILTER_COLORFLAG_RED, 255, COLORFILTER_BUFFLAG_OPA, 60);
this->timer = 60;
- this->colliderCyl.base.acFlags &= ~AC_ON;
+ this->colliderCylinder.base.acFlags &= ~AC_ON;
this->colliderJntSph.base.ocFlags1 &= ~OC1_ON;
sHands[LEFT]->colliderJntSph.base.ocFlags1 &= ~OC1_ON;
sHands[RIGHT]->colliderJntSph.base.ocFlags1 &= ~OC1_ON;
@@ -1536,9 +1535,9 @@ void BossSst_HandSlam(BossSst* this, PlayState* play) {
this->ready = true;
Actor_PlaySfx(&this->actor, NA_SE_EN_SHADEST_TAIKO_LOW);
BossSst_SpawnShockwave(this);
- this->colliderCyl.base.atFlags |= AT_ON;
- Collider_UpdateCylinder(&this->actor, &this->colliderCyl);
- this->colliderCyl.dim.radius = sCylinderInitHand.dim.radius;
+ this->colliderCylinder.base.atFlags |= AT_ON;
+ Collider_UpdateCylinder(&this->actor, &this->colliderCylinder);
+ this->colliderCylinder.dim.radius = sCylinderInitHand.dim.radius;
}
}
@@ -2582,8 +2581,8 @@ void BossSst_HandCollisionCheck(BossSst* this, PlayState* play) {
}
void BossSst_HeadCollisionCheck(BossSst* this, PlayState* play) {
- if (this->colliderCyl.base.acFlags & AC_HIT) {
- this->colliderCyl.base.acFlags &= ~AC_HIT;
+ if (this->colliderCylinder.base.acFlags & AC_HIT) {
+ this->colliderCylinder.base.acFlags &= ~AC_HIT;
if ((this->actor.colChkInfo.damageEffect != 0) || (this->actor.colChkInfo.damage != 0)) {
if (this->actionFunc == BossSst_HeadVulnerable) {
if (Actor_ApplyDamage(&this->actor) == 0) {
@@ -2615,13 +2614,13 @@ void BossSst_UpdateHand(Actor* thisx, PlayState* play) {
BossSst* this = (BossSst*)thisx;
BossSstHandTrail* trail;
- if (this->colliderCyl.base.atFlags & AT_ON) {
+ if (this->colliderCylinder.base.atFlags & AT_ON) {
if ((this->effects[0].move < 5) ||
(this->actor.xzDistToPlayer < ((this->effects[2].scale * 0.01f) * sCylinderInitHand.dim.radius)) ||
- (this->colliderCyl.base.atFlags & AT_HIT)) {
- this->colliderCyl.base.atFlags &= ~(AT_ON | AT_HIT);
+ (this->colliderCylinder.base.atFlags & AT_HIT)) {
+ this->colliderCylinder.base.atFlags &= ~(AT_ON | AT_HIT);
} else {
- this->colliderCyl.dim.radius = (this->effects[0].scale * 0.01f) * sCylinderInitHand.dim.radius;
+ this->colliderCylinder.dim.radius = (this->effects[0].scale * 0.01f) * sCylinderInitHand.dim.radius;
}
}
@@ -2648,8 +2647,8 @@ void BossSst_UpdateHand(Actor* thisx, PlayState* play) {
CollisionCheck_SetOC(play, &play->colChkCtx, &this->colliderJntSph.base);
}
- if (this->colliderCyl.base.atFlags & AT_ON) {
- CollisionCheck_SetAT(play, &play->colChkCtx, &this->colliderCyl.base);
+ if (this->colliderCylinder.base.atFlags & AT_ON) {
+ CollisionCheck_SetAT(play, &play->colChkCtx, &this->colliderCylinder.base);
}
if ((HAND_STATE(this) != HAND_DEATH) && (HAND_STATE(this) != HAND_WAIT) && (HAND_STATE(this) != HAND_BEAT) &&
@@ -2696,14 +2695,14 @@ void BossSst_UpdateHead(Actor* thisx, PlayState* play2) {
}
#if OOT_VERSION < NTSC_1_2
- if (this->colliderCyl.base.acFlags & AC_ON) {
- CollisionCheck_SetAC(play, &play->colChkCtx, &this->colliderCyl.base);
+ if (this->colliderCylinder.base.acFlags & AC_ON) {
+ CollisionCheck_SetAC(play, &play->colChkCtx, &this->colliderCylinder.base);
}
CollisionCheck_SetAC(play, &play->colChkCtx, &this->colliderJntSph.base);
#else
if ((this->actionFunc != BossSst_HeadLurk) && (this->actionFunc != BossSst_HeadIntro)) {
- if (this->colliderCyl.base.acFlags & AC_ON) {
- CollisionCheck_SetAC(play, &play->colChkCtx, &this->colliderCyl.base);
+ if (this->colliderCylinder.base.acFlags & AC_ON) {
+ CollisionCheck_SetAC(play, &play->colChkCtx, &this->colliderCylinder.base);
}
CollisionCheck_SetAC(play, &play->colChkCtx, &this->colliderJntSph.base);
}
@@ -2884,9 +2883,9 @@ void BossSst_PostHeadDraw(PlayState* play, s32 limbIndex, Gfx** dList, Vec3s* ro
if (limbIndex == 8) {
Matrix_MultVec3f(&zeroVec, &this->actor.focus.pos);
Matrix_MultVec3f(&headVec, &headPos);
- this->colliderCyl.dim.pos.x = headPos.x;
- this->colliderCyl.dim.pos.y = headPos.y;
- this->colliderCyl.dim.pos.z = headPos.z;
+ this->colliderCylinder.dim.pos.x = headPos.x;
+ this->colliderCylinder.dim.pos.y = headPos.y;
+ this->colliderCylinder.dim.pos.z = headPos.z;
}
Collider_UpdateSpheres(limbIndex, &this->colliderJntSph);
diff --git a/src/overlays/actors/ovl_Boss_Sst/z_boss_sst.h b/src/overlays/actors/ovl_Boss_Sst/z_boss_sst.h
index af358d2dc..caf4891cc 100644
--- a/src/overlays/actors/ovl_Boss_Sst/z_boss_sst.h
+++ b/src/overlays/actors/ovl_Boss_Sst/z_boss_sst.h
@@ -46,8 +46,8 @@ typedef struct BossSst {
/* 0x03C4 */ f32 radius;
/* 0x03C8 */ Vec3f center;
/* 0x03D4 */ ColliderJntSph colliderJntSph;
- /* 0x03F4 */ ColliderJntSphElement colliderItems[11];
- /* 0x06B4 */ ColliderCylinder colliderCyl;
+ /* 0x03F4 */ ColliderJntSphElement colliderJntSphElements[11];
+ /* 0x06B4 */ ColliderCylinder colliderCylinder;
/* 0x0700 */ BossSstEffect effects[BOSS_SST_EFFECT_COUNT];
/* 0x09D0 */ s16 trailIndex;
/* 0x09D2 */ s16 trailCount;
diff --git a/src/overlays/actors/ovl_Boss_Sst/z_boss_sst_colchk.inc.c b/src/overlays/actors/ovl_Boss_Sst/z_boss_sst_colchk.inc.c
index 4cbb650d7..0016ff93d 100644
--- a/src/overlays/actors/ovl_Boss_Sst/z_boss_sst_colchk.inc.c
+++ b/src/overlays/actors/ovl_Boss_Sst/z_boss_sst_colchk.inc.c
@@ -1,6 +1,6 @@
#include "z64collision_check.h"
-static ColliderJntSphElementInit sJntSphItemsInitHand[11] = {
+static ColliderJntSphElementInit sJntSphElementsInitHand[11] = {
{
{
ELEM_MATERIAL_UNK1,
@@ -134,10 +134,10 @@ static ColliderJntSphInit sJntSphInitHand = {
COLSHAPE_JNTSPH,
},
11,
- sJntSphItemsInitHand,
+ sJntSphElementsInitHand,
};
-static ColliderJntSphElementInit sJntSphItemsInitHead[11] = {
+static ColliderJntSphElementInit sJntSphElementsInitHead[11] = {
{
{
ELEM_MATERIAL_UNK1,
@@ -271,7 +271,7 @@ static ColliderJntSphInit sJntSphInitHead = {
COLSHAPE_JNTSPH,
},
11,
- sJntSphItemsInitHead,
+ sJntSphElementsInitHead,
};
static ColliderCylinderInit sCylinderInitHead = {
diff --git a/src/overlays/actors/ovl_Boss_Tw/z_boss_tw.c b/src/overlays/actors/ovl_Boss_Tw/z_boss_tw.c
index 110c3325e..50bb35218 100644
--- a/src/overlays/actors/ovl_Boss_Tw/z_boss_tw.c
+++ b/src/overlays/actors/ovl_Boss_Tw/z_boss_tw.c
@@ -1,7 +1,28 @@
#include "z_boss_tw.h"
+#include "overlays/actors/ovl_Door_Warp1/z_door_warp1.h"
+
+#include "libc64/math64.h"
+#include "libc64/qrand.h"
+#include "attributes.h"
+#include "controller.h"
+#include "gfx.h"
+#include "gfx_setupdl.h"
+#include "ichain.h"
+#include "rand.h"
+#include "rumble.h"
+#include "segmented_address.h"
+#include "seqcmd.h"
+#include "sequence.h"
+#include "sfx.h"
+#include "sys_matrix.h"
+#include "z_lib.h"
+#include "z64play.h"
+#include "z64player.h"
+#include "z64save.h"
+#include "z64skin_matrix.h"
+
#include "assets/objects/gameplay_keep/gameplay_keep.h"
#include "assets/objects/object_tw/object_tw.h"
-#include "overlays/actors/ovl_Door_Warp1/z_door_warp1.h"
#define FLAGS \
(ACTOR_FLAG_ATTENTION_ENABLED | ACTOR_FLAG_HOSTILE | ACTOR_FLAG_UPDATE_CULLING_DISABLED | \
diff --git a/src/overlays/actors/ovl_Boss_Tw/z_boss_tw.h b/src/overlays/actors/ovl_Boss_Tw/z_boss_tw.h
index eb2a4ef74..df62aeff3 100644
--- a/src/overlays/actors/ovl_Boss_Tw/z_boss_tw.h
+++ b/src/overlays/actors/ovl_Boss_Tw/z_boss_tw.h
@@ -2,11 +2,11 @@
#define Z_BOSS_TW_H
#include "ultra64.h"
-#include "global.h"
+#include "z64actor.h"
struct BossTw;
-typedef void (*BossTwActionFunc)(struct BossTw* this, PlayState* play);
+typedef void (*BossTwActionFunc)(struct BossTw* this, struct PlayState* play);
typedef enum TwWork {
/* 0 */ CS_TIMER_1,
diff --git a/src/overlays/actors/ovl_Boss_Va/z_boss_va.c b/src/overlays/actors/ovl_Boss_Va/z_boss_va.c
index fa9448d12..90b5bb7c4 100644
--- a/src/overlays/actors/ovl_Boss_Va/z_boss_va.c
+++ b/src/overlays/actors/ovl_Boss_Va/z_boss_va.c
@@ -5,12 +5,31 @@
*/
#include "z_boss_va.h"
-#include "assets/objects/object_bv/object_bv.h"
#include "overlays/actors/ovl_En_Boom/z_en_boom.h"
+
+#include "libc64/qrand.h"
+#include "attributes.h"
+#include "gfx.h"
+#include "gfx_setupdl.h"
+#include "rand.h"
+#include "regs.h"
+#include "segmented_address.h"
+#include "seqcmd.h"
+#include "sequence.h"
+#include "sfx.h"
+#include "sys_math.h"
+#include "sys_matrix.h"
+#include "z_lib.h"
+#include "z64audio.h"
+#include "z64effect.h"
+#include "z64play.h"
+#include "z64save.h"
+
#include "assets/objects/gameplay_keep/gameplay_keep.h"
+#include "assets/objects/object_bv/object_bv.h"
#pragma increment_block_number "gc-eu:128 gc-eu-mq:128 gc-jp:128 gc-jp-ce:128 gc-jp-mq:128 gc-us:128 gc-us-mq:128" \
- "ntsc-1.2:128 pal-1.0:128 pal-1.1:128"
+ "ntsc-1.0:128 ntsc-1.1:128 ntsc-1.2:128 pal-1.0:128 pal-1.1:128"
#define FLAGS \
(ACTOR_FLAG_ATTENTION_ENABLED | ACTOR_FLAG_HOSTILE | ACTOR_FLAG_UPDATE_CULLING_DISABLED | \
@@ -612,7 +631,9 @@ void BossVa_Init(Actor* thisx, PlayState* play2) {
break;
default:
this->actor.flags |= ACTOR_FLAG_SFX_FOR_PLAYER_BODY_HIT;
- SkelAnime_Init(play, &this->skelAnime, &gBarinadeBariSkel, &gBarinadeBariAnim, NULL, NULL, 0);
+ //! @bug Flex skeleton is used as normal skeleton
+ SkelAnime_Init(play, &this->skelAnime, (SkeletonHeader*)&gBarinadeBariSkel, &gBarinadeBariAnim, NULL, NULL,
+ 0);
this->actor.shape.yOffset = 400.0f;
break;
case BOSSVA_DOOR:
@@ -680,8 +701,8 @@ void BossVa_Init(Actor* thisx, PlayState* play2) {
}
this->zapHeadPos.x = 1.0f;
- Collider_InitCylinder(play, &this->colliderBody);
- Collider_SetCylinder(play, &this->colliderBody, &this->actor, &sCylinderInit);
+ Collider_InitCylinder(play, &this->bodyCollider);
+ Collider_SetCylinder(play, &this->bodyCollider, &this->actor, &sCylinderInit);
for (i = BOSSVA_ZAPPER_3; i >= BOSSVA_SUPPORT_1; i--) {
Actor_SpawnAsChild(
@@ -702,8 +723,9 @@ void BossVa_Init(Actor* thisx, PlayState* play2) {
case BOSSVA_SUPPORT_1:
case BOSSVA_SUPPORT_2:
case BOSSVA_SUPPORT_3:
- Collider_InitJntSph(play, &this->colliderSph);
- Collider_SetJntSph(play, &this->colliderSph, &this->actor, &sJntSphInitSupport, this->elements);
+ Collider_InitJntSph(play, &this->colliderJntSph);
+ Collider_SetJntSph(play, &this->colliderJntSph, &this->actor, &sJntSphInitSupport,
+ this->colliderJntSphElements);
if (sCsState < BOSSVA_BATTLE) {
BossVa_SetupSupportIntro(this, play);
} else {
@@ -731,8 +753,9 @@ void BossVa_Init(Actor* thisx, PlayState* play2) {
BossVa_SetupDoor(this, play);
break;
default:
- Collider_InitJntSph(play, &this->colliderSph);
- Collider_SetJntSph(play, &this->colliderSph, &this->actor, &sJntSphInitBari, this->elements);
+ Collider_InitJntSph(play, &this->colliderJntSph);
+ Collider_SetJntSph(play, &this->colliderJntSph, &this->actor, &sJntSphInitBari,
+ this->colliderJntSphElements);
Collider_InitQuad(play, &this->colliderLightning);
Collider_SetQuad(play, &this->colliderLightning, &this->actor, &sQuadInit);
this->unk_1D8.x = 1.0f;
@@ -752,8 +775,8 @@ void BossVa_Destroy(Actor* thisx, PlayState* play) {
BossVa* this = (BossVa*)thisx;
SkelAnime_Free(&this->skelAnime, play);
- Collider_DestroyJntSph(play, &this->colliderSph);
- Collider_DestroyCylinder(play, &this->colliderBody);
+ Collider_DestroyJntSph(play, &this->colliderJntSph);
+ Collider_DestroyCylinder(play, &this->bodyCollider);
}
void BossVa_SetupIntro(BossVa* this) {
@@ -1071,9 +1094,9 @@ void BossVa_BodyPhase1(BossVa* this, PlayState* play) {
}
}
- if (this->colliderBody.base.atFlags & AT_HIT) {
- this->colliderBody.base.atFlags &= ~AT_HIT;
- if (this->colliderBody.base.at == &player->actor) {
+ if (this->bodyCollider.base.atFlags & AT_HIT) {
+ this->bodyCollider.base.atFlags &= ~AT_HIT;
+ if (this->bodyCollider.base.at == &player->actor) {
Actor_SetPlayerKnockbackLargeNoDamage(play, &this->actor, 8.0f, this->actor.yawTowardsPlayer, 8.0f);
}
}
@@ -1101,9 +1124,9 @@ void BossVa_BodyPhase1(BossVa* this, PlayState* play) {
Actor_PlaySfx(&this->actor, NA_SE_EN_BALINADE_BL_SPARK - SFX_FLAG);
}
- Collider_UpdateCylinder(&this->actor, &this->colliderBody);
- CollisionCheck_SetOC(play, &play->colChkCtx, &this->colliderBody.base);
- CollisionCheck_SetAT(play, &play->colChkCtx, &this->colliderBody.base);
+ Collider_UpdateCylinder(&this->actor, &this->bodyCollider);
+ CollisionCheck_SetOC(play, &play->colChkCtx, &this->bodyCollider.base);
+ CollisionCheck_SetAT(play, &play->colChkCtx, &this->bodyCollider.base);
func_800F436C(&this->actor.projectedPos, NA_SE_EN_BALINADE_LEVEL - SFX_FLAG, 1.0f);
}
@@ -1133,17 +1156,17 @@ void BossVa_BodyPhase2(BossVa* this, PlayState* play) {
Actor_SetColorFilter(&this->actor, COLORFILTER_COLORFLAG_BLUE, 255, COLORFILTER_BUFFLAG_OPA, 160);
this->actor.colorFilterTimer = this->invincibilityTimer;
} else {
- this->colliderBody.elem.acDmgInfo.dmgFlags = DMG_BOOMERANG;
+ this->bodyCollider.elem.acDmgInfo.dmgFlags = DMG_BOOMERANG;
}
}
- if (this->colliderBody.base.acFlags & AC_HIT) {
- this->colliderBody.base.acFlags &= ~AC_HIT;
+ if (this->bodyCollider.base.acFlags & AC_HIT) {
+ this->bodyCollider.base.acFlags &= ~AC_HIT;
- if (this->colliderBody.base.ac->id == ACTOR_EN_BOOM) {
+ if (this->bodyCollider.base.ac->id == ACTOR_EN_BOOM) {
sPhase2Timer &= 0xFE00;
Actor_SetColorFilter(&this->actor, COLORFILTER_COLORFLAG_BLUE, 255, COLORFILTER_BUFFLAG_OPA, 160);
- this->colliderBody.elem.acDmgInfo.dmgFlags = DMG_SWORD | DMG_BOOMERANG | DMG_DEKU_STICK;
+ this->bodyCollider.elem.acDmgInfo.dmgFlags = DMG_SWORD | DMG_BOOMERANG | DMG_DEKU_STICK;
} else {
sKillBari++;
if ((this->actor.colorFilterTimer != 0) && !(this->actor.colorFilterParams & 0x4000)) {
@@ -1161,11 +1184,11 @@ void BossVa_BodyPhase2(BossVa* this, PlayState* play) {
Actor_PlaySfx(&this->actor, NA_SE_EN_BALINADE_FAINT);
}
- if (this->colliderBody.base.atFlags & AT_HIT) {
- this->colliderBody.base.atFlags &= ~AT_HIT;
+ if (this->bodyCollider.base.atFlags & AT_HIT) {
+ this->bodyCollider.base.atFlags &= ~AT_HIT;
sPhase2Timer = (sPhase2Timer + 0x18) & 0xFFF0;
- if (this->colliderBody.base.at == &player->actor) {
+ if (this->bodyCollider.base.at == &player->actor) {
Actor_SetPlayerKnockbackLargeNoDamage(play, &this->actor, 8.0f, this->actor.yawTowardsPlayer, 8.0f);
Actor_PlaySfx(&player->actor, NA_SE_PL_BODY_HIT);
}
@@ -1209,14 +1232,14 @@ void BossVa_BodyPhase2(BossVa* this, PlayState* play) {
this->actor.focus.pos = this->actor.world.pos;
this->actor.focus.pos.y += 45.0f;
- Collider_UpdateCylinder(&this->actor, &this->colliderBody);
- CollisionCheck_SetOC(play, &play->colChkCtx, &this->colliderBody.base);
+ Collider_UpdateCylinder(&this->actor, &this->bodyCollider);
+ CollisionCheck_SetOC(play, &play->colChkCtx, &this->bodyCollider.base);
if (this->actor.colorFilterTimer == 0) {
- CollisionCheck_SetAT(play, &play->colChkCtx, &this->colliderBody.base);
+ CollisionCheck_SetAT(play, &play->colChkCtx, &this->bodyCollider.base);
}
if ((this->actor.colorFilterTimer == 0) || !(this->actor.colorFilterParams & 0x4000)) {
- CollisionCheck_SetAC(play, &play->colChkCtx, &this->colliderBody.base);
+ CollisionCheck_SetAC(play, &play->colChkCtx, &this->bodyCollider.base);
}
func_800F436C(&this->actor.projectedPos, NA_SE_EN_BALINADE_LEVEL - SFX_FLAG,
@@ -1224,7 +1247,7 @@ void BossVa_BodyPhase2(BossVa* this, PlayState* play) {
}
void BossVa_SetupBodyPhase3(BossVa* this) {
- this->colliderBody.elem.acDmgInfo.dmgFlags = DMG_BOOMERANG;
+ this->bodyCollider.elem.acDmgInfo.dmgFlags = DMG_BOOMERANG;
this->actor.speed = 0.0f;
sPhase3StopMoving = false;
BossVa_SetupAction(this, BossVa_BodyPhase3);
@@ -1239,16 +1262,16 @@ void BossVa_BodyPhase3(BossVa* this, PlayState* play) {
sp62 = Math_Vec3f_Yaw(&this->actor.world.pos, &this->actor.home.pos);
this->unk_1B0 += 0xCE4;
this->bodyGlow = (s16)(Math_SinS(this->unk_1B0) * 50.0f) + 150;
- if (this->colliderBody.base.atFlags & AT_HIT) {
- this->colliderBody.base.atFlags &= ~AT_HIT;
- if (this->colliderBody.base.at == &player->actor) {
+ if (this->bodyCollider.base.atFlags & AT_HIT) {
+ this->bodyCollider.base.atFlags &= ~AT_HIT;
+ if (this->bodyCollider.base.at == &player->actor) {
Actor_SetPlayerKnockbackLargeNoDamage(play, &this->actor, 8.0f, this->actor.yawTowardsPlayer, 8.0f);
this->actor.world.rot.y += (s16)Rand_CenteredFloat(0x2EE0) + 0x8000;
Actor_PlaySfx(&player->actor, NA_SE_PL_BODY_HIT);
}
}
- if (this->colliderBody.base.acFlags & AC_HIT) {
+ if (this->bodyCollider.base.acFlags & AC_HIT) {
this->skelAnime.curFrame = 0.0f;
Actor_SetColorFilter(&this->actor, COLORFILTER_COLORFLAG_BLUE, 255, COLORFILTER_BUFFLAG_OPA, 12);
Actor_PlaySfx(&this->actor, NA_SE_EN_BALINADE_FAINT);
@@ -1326,11 +1349,11 @@ void BossVa_BodyPhase3(BossVa* this, PlayState* play) {
Actor_PlaySfx(&this->actor, NA_SE_EN_BALINADE_BL_SPARK - SFX_FLAG);
}
- Collider_UpdateCylinder(&this->actor, &this->colliderBody);
- CollisionCheck_SetOC(play, &play->colChkCtx, &this->colliderBody.base);
- CollisionCheck_SetAT(play, &play->colChkCtx, &this->colliderBody.base);
+ Collider_UpdateCylinder(&this->actor, &this->bodyCollider);
+ CollisionCheck_SetOC(play, &play->colChkCtx, &this->bodyCollider.base);
+ CollisionCheck_SetAT(play, &play->colChkCtx, &this->bodyCollider.base);
if (this->timer == 0) {
- CollisionCheck_SetAC(play, &play->colChkCtx, &this->colliderBody.base);
+ CollisionCheck_SetAC(play, &play->colChkCtx, &this->bodyCollider.base);
}
func_800F436C(&this->actor.projectedPos, NA_SE_EN_BALINADE_LEVEL - SFX_FLAG,
@@ -1349,7 +1372,7 @@ void BossVa_SetupBodyPhase4(BossVa* this, PlayState* play) {
this->timer = -30;
}
- this->colliderBody.dim.radius = 55;
+ this->bodyCollider.dim.radius = 55;
BossVa_SetupAction(this, BossVa_BodyPhase4);
}
@@ -1360,9 +1383,9 @@ void BossVa_BodyPhase4(BossVa* this, PlayState* play) {
this->unk_1B0 = (this->unk_1B0 + (s16)((sFightPhase - PHASE_4 + 1) * 1000.0f)) + 0xCE4;
this->bodyGlow = (s16)(Math_SinS(this->unk_1B0) * 50.0f) + 150;
- if (this->colliderBody.base.atFlags & AT_HIT) {
- this->colliderBody.base.atFlags &= ~AT_HIT;
- if (this->colliderBody.base.at == &player->actor) {
+ if (this->bodyCollider.base.atFlags & AT_HIT) {
+ this->bodyCollider.base.atFlags &= ~AT_HIT;
+ if (this->bodyCollider.base.at == &player->actor) {
Actor_SetPlayerKnockbackLargeNoDamage(play, &this->actor, 8.0f, this->actor.yawTowardsPlayer, 8.0f);
this->actor.world.rot.y += (s16)Rand_CenteredFloat(0x2EE0) + 0x8000;
Actor_PlaySfx(&player->actor, NA_SE_PL_BODY_HIT);
@@ -1372,8 +1395,8 @@ void BossVa_BodyPhase4(BossVa* this, PlayState* play) {
Actor_PlaySfx(&this->actor, NA_SE_EN_BALINADE_BL_SPARK - SFX_FLAG);
}
- if (this->colliderBody.base.acFlags & AC_HIT) {
- this->colliderBody.base.acFlags &= ~AC_HIT;
+ if (this->bodyCollider.base.acFlags & AC_HIT) {
+ this->bodyCollider.base.acFlags &= ~AC_HIT;
this->skelAnime.curFrame = 0.0f;
if (this->timer >= 0) {
if (this->invincibilityTimer == 0) {
@@ -1403,8 +1426,8 @@ void BossVa_BodyPhase4(BossVa* this, PlayState* play) {
Actor_PlaySfx(&this->actor, NA_SE_EN_BALINADE_FAINT);
}
}
- } else if (this->colliderBody.base.ac->id == ACTOR_EN_BOOM) {
- boomerang = (EnBoom*)this->colliderBody.base.ac;
+ } else if (this->bodyCollider.base.ac->id == ACTOR_EN_BOOM) {
+ boomerang = (EnBoom*)this->bodyCollider.base.ac;
boomerang->returnTimer = 0;
boomerang->moveTo = &player->actor;
boomerang->actor.world.rot.y = boomerang->actor.yawTowardsPlayer;
@@ -1428,7 +1451,7 @@ void BossVa_BodyPhase4(BossVa* this, PlayState* play) {
}
Math_SmoothStepToF(&this->actor.speed, ((sFightPhase - PHASE_4 + 1) * 1.5f) + 4.0f, 1.0f, 0.25f, 0.0f);
}
- this->colliderBody.elem.acDmgInfo.dmgFlags = DMG_BOOMERANG;
+ this->bodyCollider.elem.acDmgInfo.dmgFlags = DMG_BOOMERANG;
} else {
Math_SmoothStepToS(&this->vaBodySpinRate, 0, 1, 0x96, 0);
if (this->timer > 0) {
@@ -1436,7 +1459,7 @@ void BossVa_BodyPhase4(BossVa* this, PlayState* play) {
this->timer = 35;
}
Math_SmoothStepToF(&this->actor.shape.yOffset, -480.0f, 1.0f, 30.0f, 0.0f);
- this->colliderBody.elem.acDmgInfo.dmgFlags = DMG_SWORD | DMG_BOOMERANG | DMG_DEKU_STICK;
+ this->bodyCollider.elem.acDmgInfo.dmgFlags = DMG_SWORD | DMG_BOOMERANG | DMG_DEKU_STICK;
this->timer--;
} else {
if ((player->stateFlags1 & PLAYER_STATE1_26) && (this->timer < -60)) {
@@ -1498,13 +1521,13 @@ void BossVa_BodyPhase4(BossVa* this, PlayState* play) {
}
Actor_UpdateBgCheckInfo(play, &this->actor, 30.0f, 70.0f, 0.0f, UPDBGCHECKINFO_FLAG_0);
- Collider_UpdateCylinder(&this->actor, &this->colliderBody);
- CollisionCheck_SetOC(play, &play->colChkCtx, &this->colliderBody.base);
+ Collider_UpdateCylinder(&this->actor, &this->bodyCollider);
+ CollisionCheck_SetOC(play, &play->colChkCtx, &this->bodyCollider.base);
if (this->invincibilityTimer == 0) {
- CollisionCheck_SetAC(play, &play->colChkCtx, &this->colliderBody.base);
+ CollisionCheck_SetAC(play, &play->colChkCtx, &this->bodyCollider.base);
}
if ((this->vaBodySpinRate > 0x3E8) || (this->actor.shape.yOffset < -1200.0f)) {
- CollisionCheck_SetAT(play, &play->colChkCtx, &this->colliderBody.base);
+ CollisionCheck_SetAT(play, &play->colChkCtx, &this->bodyCollider.base);
}
func_800F436C(&this->actor.projectedPos, NA_SE_EN_BALINADE_LEVEL - SFX_FLAG,
(this->vaBodySpinRate * 0.00025f) + 1.0f);
@@ -1745,11 +1768,11 @@ void BossVa_SupportAttached(BossVa* this, PlayState* play) {
Actor_PlaySfx(&this->actor, NA_SE_EN_BALINADE_BL_SPARK - SFX_FLAG);
}
- if (this->colliderSph.base.acFlags & AC_HIT) {
+ if (this->colliderJntSph.base.acFlags & AC_HIT) {
BossVa_SetupSupportCut(this, play);
} else {
if (this->actor.colorFilterTimer == 0) {
- CollisionCheck_SetAC(play, &play->colChkCtx, &this->colliderSph.base);
+ CollisionCheck_SetAC(play, &play->colChkCtx, &this->colliderJntSph.base);
}
if ((this->timer % 2) == 0) {
@@ -2548,23 +2571,23 @@ void BossVa_BariPhase3Attack(BossVa* this, PlayState* play) {
Math_SmoothStepToS(&this->vaBariUnused.z, this->vaBariUnused.x, 1, 0x1E, 0);
this->vaBariUnused.y += this->vaBariUnused.z;
- if ((this->colliderLightning.base.atFlags & AT_HIT) || (this->colliderSph.base.atFlags & AT_HIT)) {
- if ((this->colliderLightning.base.at == &player->actor) || (this->colliderSph.base.at == &player->actor)) {
+ if ((this->colliderLightning.base.atFlags & AT_HIT) || (this->colliderJntSph.base.atFlags & AT_HIT)) {
+ if ((this->colliderLightning.base.at == &player->actor) || (this->colliderJntSph.base.at == &player->actor)) {
Actor_SetPlayerKnockbackLargeNoDamage(play, &this->actor, 8.0f, GET_BODY(this)->actor.yawTowardsPlayer,
8.0f);
Actor_PlaySfx(&player->actor, NA_SE_PL_BODY_HIT);
- this->colliderSph.base.at = NULL;
+ this->colliderJntSph.base.at = NULL;
this->colliderLightning.base.at = NULL;
}
this->colliderLightning.base.atFlags &= ~AT_HIT;
- this->colliderSph.base.atFlags &= ~AT_HIT;
+ this->colliderJntSph.base.atFlags &= ~AT_HIT;
}
- if (this->colliderSph.base.acFlags & AC_HIT) {
- this->colliderSph.base.acFlags &= ~AC_HIT;
- if ((this->colliderSph.base.ac->id == ACTOR_EN_BOOM) && (sp52 >= 128)) {
- boomerang = (EnBoom*)this->colliderSph.base.ac;
+ if (this->colliderJntSph.base.acFlags & AC_HIT) {
+ this->colliderJntSph.base.acFlags &= ~AC_HIT;
+ if ((this->colliderJntSph.base.ac->id == ACTOR_EN_BOOM) && (sp52 >= 128)) {
+ boomerang = (EnBoom*)this->colliderJntSph.base.ac;
boomerang->returnTimer = 0;
boomerang->moveTo = &player->actor;
boomerang->actor.world.rot.y = boomerang->actor.yawTowardsPlayer;
@@ -2587,14 +2610,14 @@ void BossVa_BariPhase3Attack(BossVa* this, PlayState* play) {
if (sp52 >= 128) {
BossVa_Spark(play, this, 1, 75, 15.0f, 7.0f, SPARK_TETHER, 1.0f, true);
- CollisionCheck_SetAC(play, &play->colChkCtx, &this->colliderSph.base);
+ CollisionCheck_SetAC(play, &play->colChkCtx, &this->colliderJntSph.base);
sPhase3StopMoving = false;
} else {
sPhase3StopMoving = true;
}
CollisionCheck_SetAT(play, &play->colChkCtx, &this->colliderLightning.base);
- CollisionCheck_SetAT(play, &play->colChkCtx, &this->colliderSph.base);
+ CollisionCheck_SetAT(play, &play->colChkCtx, &this->colliderJntSph.base);
if ((play->gameplayFrames % 4) == 0) {
Math_SmoothStepToS(&this->unk_1F0, 0x78, 1, 0xA, 0);
}
@@ -2644,17 +2667,17 @@ void BossVa_BariPhase2Attack(BossVa* this, PlayState* play) {
return;
}
- if ((this->colliderLightning.base.atFlags & AT_HIT) || (this->colliderSph.base.atFlags & AT_HIT)) {
- if ((this->colliderLightning.base.at == &player->actor) || (this->colliderSph.base.at == &player->actor)) {
+ if ((this->colliderLightning.base.atFlags & AT_HIT) || (this->colliderJntSph.base.atFlags & AT_HIT)) {
+ if ((this->colliderLightning.base.at == &player->actor) || (this->colliderJntSph.base.at == &player->actor)) {
Actor_SetPlayerKnockbackLargeNoDamage(play, &this->actor, 8.0f, GET_BODY(this)->actor.yawTowardsPlayer,
8.0f);
Actor_PlaySfx(&player->actor, NA_SE_PL_BODY_HIT);
- this->colliderSph.base.at = NULL;
+ this->colliderJntSph.base.at = NULL;
this->colliderLightning.base.at = NULL;
}
this->colliderLightning.base.atFlags &= ~AT_HIT;
- this->colliderSph.base.atFlags &= ~AT_HIT;
+ this->colliderJntSph.base.atFlags &= ~AT_HIT;
}
Math_SmoothStepToF(&this->actor.world.pos.y, 4.0f, 1.0f, 2.0f, 0.0f);
@@ -2675,11 +2698,11 @@ void BossVa_BariPhase2Attack(BossVa* this, PlayState* play) {
Math_SmoothStepToF(&this->unk_1A0, (Math_SinS(sPhase2Timer * 0x190) * sp4C) + 320.0f, 1.0f, 10.0f, 0.0f);
Math_SmoothStepToS(&this->unk_1AC, sp50 + 0x1F4, 1, 0x3C, 0);
this->actor.world.pos.y += 2.0f * Math_SinF(this->unk_1A4);
- if (this->colliderSph.base.acFlags & AC_HIT) {
- this->colliderSph.base.acFlags &= ~AC_HIT;
+ if (this->colliderJntSph.base.acFlags & AC_HIT) {
+ this->colliderJntSph.base.acFlags &= ~AC_HIT;
- if ((this->colliderSph.base.ac->id == ACTOR_EN_BOOM) && (sp52 >= 64)) {
- boomerang = (EnBoom*)this->colliderSph.base.ac;
+ if ((this->colliderJntSph.base.ac->id == ACTOR_EN_BOOM) && (sp52 >= 64)) {
+ boomerang = (EnBoom*)this->colliderJntSph.base.ac;
boomerang->returnTimer = 0;
boomerang->moveTo = &player->actor;
boomerang->actor.world.rot.y = boomerang->actor.yawTowardsPlayer;
@@ -2688,7 +2711,7 @@ void BossVa_BariPhase2Attack(BossVa* this, PlayState* play) {
}
CollisionCheck_SetAT(play, &play->colChkCtx, &this->colliderLightning.base);
- CollisionCheck_SetAT(play, &play->colChkCtx, &this->colliderSph.base);
+ CollisionCheck_SetAT(play, &play->colChkCtx, &this->colliderJntSph.base);
} else {
this->actor.flags |= ACTOR_FLAG_ATTENTION_ENABLED;
Math_SmoothStepToS(&this->unk_1AC, sp50 + 150, 1, 0x3C, 0);
@@ -2703,13 +2726,13 @@ void BossVa_BariPhase2Attack(BossVa* this, PlayState* play) {
}
this->actor.world.pos.y += Math_SinF(this->unk_1A4) * 4.0f;
- if (this->colliderSph.base.acFlags & AC_HIT) {
+ if (this->colliderJntSph.base.acFlags & AC_HIT) {
BossVa_KillBari(this, play);
}
}
Math_SmoothStepToS(&this->actor.shape.rot.x, 0, 1, 0x5DC, 0);
- CollisionCheck_SetAC(play, &play->colChkCtx, &this->colliderSph.base);
+ CollisionCheck_SetAC(play, &play->colChkCtx, &this->colliderJntSph.base);
if ((play->gameplayFrames % 4) == 0) {
Math_SmoothStepToS(&this->unk_1F0, 0x78, 1, 0xA, 0);
}
@@ -2742,7 +2765,7 @@ void BossVa_BariPhase3Stunned(BossVa* this, PlayState* play) {
Vec3f sp40 = GET_BODY(this)->unk_1D8;
this->actor.world.rot.x = Math_Vec3f_Pitch(&GET_BODY(this)->actor.world.pos, &this->actor.world.pos);
- if (this->colliderSph.base.acFlags & AC_HIT) {
+ if (this->colliderJntSph.base.acFlags & AC_HIT) {
BossVa_KillBari(this, play);
return;
}
@@ -2750,7 +2773,7 @@ void BossVa_BariPhase3Stunned(BossVa* this, PlayState* play) {
this->unk_1A4 += Rand_ZeroOne() * 0.5f;
Math_SmoothStepToF(&this->actor.world.pos.y, 4.0f, 1.0f, 2.0f, 0.0f);
this->actor.world.pos.y += Math_SinF(this->unk_1A4) * 3.0f;
- CollisionCheck_SetAC(play, &play->colChkCtx, &this->colliderSph.base);
+ CollisionCheck_SetAC(play, &play->colChkCtx, &this->colliderJntSph.base);
if ((play->gameplayFrames % 4) == 0) {
Math_SmoothStepToS(&this->unk_1F0, 0x28, 1, 0xA, 0);
BossVa_Spark(play, this, 1, this->unk_1F0, 25.0f, 20.0f, SPARK_BARI, 2.0f, true);
@@ -2819,10 +2842,10 @@ void BossVa_Update(Actor* thisx, PlayState* play2) {
switch (this->actor.params) {
case BOSSVA_BODY:
- if (this->colliderBody.base.acFlags & AC_HIT) {
- this->colliderBody.base.acFlags &= ~AC_HIT;
- if (this->colliderBody.base.ac->id == ACTOR_EN_BOOM) {
- boomerang = (EnBoom*)this->colliderBody.base.ac;
+ if (this->bodyCollider.base.acFlags & AC_HIT) {
+ this->bodyCollider.base.acFlags &= ~AC_HIT;
+ if (this->bodyCollider.base.ac->id == ACTOR_EN_BOOM) {
+ boomerang = (EnBoom*)this->bodyCollider.base.ac;
boomerang->returnTimer = 0;
}
}
@@ -2972,7 +2995,7 @@ void BossVa_SupportPostLimbDraw(PlayState* play, s32 limbIndex, Gfx** dList, Vec
switch (limbIndex) {
case 4:
Matrix_MultVec3f(&sZeroVec, &this->actor.focus.pos);
- Collider_UpdateSpheres(0, &this->colliderSph);
+ Collider_UpdateSpheres(0, &this->colliderJntSph);
break;
case 7:
Matrix_MultVec3f(&sZeroVec, &this->armTip);
@@ -3228,7 +3251,7 @@ void BossVa_Draw(Actor* thisx, PlayState* play) {
if (!this->isDead) {
SkelAnime_DrawOpa(play, this->skelAnime.skeleton, this->skelAnime.jointTable,
BossVa_BariOverrideLimbDraw, BossVa_BariPostLimbDraw, this);
- Collider_UpdateSpheres(0, &this->colliderSph);
+ Collider_UpdateSpheres(0, &this->colliderJntSph);
if (sCsState < BOSSVA_BATTLE) {
spBC = GET_BODY(this)->actor.world.pos;
} else {
diff --git a/src/overlays/actors/ovl_Boss_Va/z_boss_va.h b/src/overlays/actors/ovl_Boss_Va/z_boss_va.h
index f5e6c8a89..628831ad2 100644
--- a/src/overlays/actors/ovl_Boss_Va/z_boss_va.h
+++ b/src/overlays/actors/ovl_Boss_Va/z_boss_va.h
@@ -2,11 +2,11 @@
#define Z_BOSS_VA_H
#include "ultra64.h"
-#include "global.h"
+#include "z64actor.h"
struct BossVa;
-typedef void (*BossVaActionFunc)(struct BossVa*, PlayState*);
+typedef void (*BossVaActionFunc)(struct BossVa*, struct PlayState*);
typedef struct BossVa {
/* 0x0000 */ Actor actor;
@@ -41,9 +41,9 @@ typedef struct BossVa {
/* 0x01FC */ Vec3f effectPos[10];
/* 0x0274 */ Vec3f unk_274; // Unused body position
/* 0x0280 */ Vec3f unk_280; // Unused body position
- /* 0x028C */ ColliderCylinder colliderBody;
- /* 0x02D8 */ ColliderJntSph colliderSph;
- /* 0x02F8 */ ColliderJntSphElement elements[1];
+ /* 0x028C */ ColliderCylinder bodyCollider;
+ /* 0x02D8 */ ColliderJntSph colliderJntSph;
+ /* 0x02F8 */ ColliderJntSphElement colliderJntSphElements[1];
/* 0x0338 */ ColliderQuad colliderLightning;
} BossVa; // size = 0x03B8
diff --git a/src/overlays/actors/ovl_Demo_6K/z_demo_6k.c b/src/overlays/actors/ovl_Demo_6K/z_demo_6k.c
index 7657cf743..d61720cdf 100644
--- a/src/overlays/actors/ovl_Demo_6K/z_demo_6k.c
+++ b/src/overlays/actors/ovl_Demo_6K/z_demo_6k.c
@@ -5,11 +5,26 @@
*/
#include "z_demo_6k.h"
+#include "overlays/actors/ovl_Eff_Dust/z_eff_dust.h"
+
+#include "gfx.h"
+#include "gfx_setupdl.h"
+#include "rand.h"
+#include "segmented_address.h"
+#include "sequence.h"
+#include "sfx.h"
+#include "sys_matrix.h"
#include "terminal.h"
+#include "z_lib.h"
+#include "z64audio.h"
+#include "z64effect.h"
+#include "z64light.h"
+#include "z64play.h"
+#include "z64player.h"
+
#include "assets/objects/gameplay_keep/gameplay_keep.h"
#include "assets/objects/object_demo_6k/object_demo_6k.h"
#include "assets/objects/object_gnd_magic/object_gnd_magic.h"
-#include "overlays/actors/ovl_Eff_Dust/z_eff_dust.h"
#define FLAGS ACTOR_FLAG_UPDATE_CULLING_DISABLED
diff --git a/src/overlays/actors/ovl_Demo_6K/z_demo_6k.h b/src/overlays/actors/ovl_Demo_6K/z_demo_6k.h
index 09d9c175f..5849ccc23 100644
--- a/src/overlays/actors/ovl_Demo_6K/z_demo_6k.h
+++ b/src/overlays/actors/ovl_Demo_6K/z_demo_6k.h
@@ -2,11 +2,12 @@
#define Z_DEMO_6K_H
#include "ultra64.h"
-#include "global.h"
+#include "z64actor.h"
+#include "z64light.h"
struct Demo6K;
-typedef void (*Demo6KActionFunc)(struct Demo6K*, PlayState*);
+typedef void (*Demo6KActionFunc)(struct Demo6K*, struct PlayState*);
typedef struct Demo6K {
/* 0x0000 */ Actor actor;
diff --git a/src/overlays/actors/ovl_Demo_Du/z_demo_du.c b/src/overlays/actors/ovl_Demo_Du/z_demo_du.c
index a5e7139f0..9a1993da1 100644
--- a/src/overlays/actors/ovl_Demo_Du/z_demo_du.c
+++ b/src/overlays/actors/ovl_Demo_Du/z_demo_du.c
@@ -1,8 +1,21 @@
#include "z_demo_du.h"
-#include "assets/objects/object_du/object_du.h"
#include "overlays/actors/ovl_Demo_Effect/z_demo_effect.h"
#include "overlays/actors/ovl_Door_Warp1/z_door_warp1.h"
+
+#include "libc64/qrand.h"
+#include "gfx.h"
+#include "gfx_setupdl.h"
+#include "regs.h"
+#include "segmented_address.h"
+#include "sfx.h"
#include "terminal.h"
+#include "z_lib.h"
+#include "z64effect.h"
+#include "z64play.h"
+#include "z64player.h"
+#include "z64save.h"
+
+#include "assets/objects/object_du/object_du.h"
#define FLAGS ACTOR_FLAG_UPDATE_CULLING_DISABLED
diff --git a/src/overlays/actors/ovl_Demo_Du/z_demo_du.h b/src/overlays/actors/ovl_Demo_Du/z_demo_du.h
index d46f03145..ede2756e0 100644
--- a/src/overlays/actors/ovl_Demo_Du/z_demo_du.h
+++ b/src/overlays/actors/ovl_Demo_Du/z_demo_du.h
@@ -2,7 +2,7 @@
#define Z_DEMO_DU_H
#include "ultra64.h"
-#include "global.h"
+#include "z64actor.h"
struct DemoDu;
diff --git a/src/overlays/actors/ovl_Demo_Du/z_demo_du_cutscene_data.inc.c b/src/overlays/actors/ovl_Demo_Du/z_demo_du_cutscene_data.inc.c
index 06dbb35c1..ad83a2418 100644
--- a/src/overlays/actors/ovl_Demo_Du/z_demo_du_cutscene_data.inc.c
+++ b/src/overlays/actors/ovl_Demo_Du/z_demo_du_cutscene_data.inc.c
@@ -1,5 +1,6 @@
-#include "z_demo_du.h"
+#include "sequence.h"
#include "z64cutscene_commands.h"
+#include "z64player.h"
// clang-format off
static CutsceneData gFireMedallionCs[] = {
diff --git a/src/overlays/actors/ovl_Demo_Ec/z_demo_ec.c b/src/overlays/actors/ovl_Demo_Ec/z_demo_ec.c
index 3f19529df..303c4f724 100644
--- a/src/overlays/actors/ovl_Demo_Ec/z_demo_ec.c
+++ b/src/overlays/actors/ovl_Demo_Ec/z_demo_ec.c
@@ -5,7 +5,15 @@
*/
#include "z_demo_ec.h"
+
+#include "gfx.h"
+#include "gfx_setupdl.h"
+#include "segmented_address.h"
#include "terminal.h"
+#include "z_lib.h"
+#include "z64play.h"
+#include "z64save.h"
+
#include "assets/objects/object_zo/object_zo.h"
#include "assets/objects/object_ec/object_ec.h"
#include "assets/objects/object_ma2/object_ma2.h"
diff --git a/src/overlays/actors/ovl_Demo_Ec/z_demo_ec.h b/src/overlays/actors/ovl_Demo_Ec/z_demo_ec.h
index fe7148350..494338b27 100644
--- a/src/overlays/actors/ovl_Demo_Ec/z_demo_ec.h
+++ b/src/overlays/actors/ovl_Demo_Ec/z_demo_ec.h
@@ -2,13 +2,13 @@
#define Z_DEMO_EC_H
#include "ultra64.h"
-#include "global.h"
+#include "z64actor.h"
struct DemoEc;
-typedef void (*DemoEcInitFunc)(struct DemoEc*, PlayState*);
-typedef void (*DemoEcUpdateFunc)(struct DemoEc*, PlayState*);
-typedef void (*DemoEcDrawFunc)(struct DemoEc*, PlayState*);
+typedef void (*DemoEcInitFunc)(struct DemoEc*, struct PlayState*);
+typedef void (*DemoEcUpdateFunc)(struct DemoEc*, struct PlayState*);
+typedef void (*DemoEcDrawFunc)(struct DemoEc*, struct PlayState*);
typedef struct DemoEc {
/* 0x0000 */ Actor actor;
diff --git a/src/overlays/actors/ovl_Demo_Effect/z_demo_effect.c b/src/overlays/actors/ovl_Demo_Effect/z_demo_effect.c
index 69db3f243..78517cad0 100644
--- a/src/overlays/actors/ovl_Demo_Effect/z_demo_effect.c
+++ b/src/overlays/actors/ovl_Demo_Effect/z_demo_effect.c
@@ -17,10 +17,10 @@
#include "z64audio.h"
#include "z64curve.h"
#include "z64draw.h"
+#include "z64cutscene_flags.h"
#include "z64effect.h"
#include "z64play.h"
-
-#include "global.h"
+#include "z64save.h"
#include "assets/objects/gameplay_keep/gameplay_keep.h"
#include "assets/objects/object_efc_crystal_light/object_efc_crystal_light.h"
diff --git a/src/overlays/actors/ovl_Demo_Ext/z_demo_ext.c b/src/overlays/actors/ovl_Demo_Ext/z_demo_ext.c
index caae4cff1..55713d413 100644
--- a/src/overlays/actors/ovl_Demo_Ext/z_demo_ext.c
+++ b/src/overlays/actors/ovl_Demo_Ext/z_demo_ext.c
@@ -5,7 +5,16 @@
*/
#include "z_demo_ext.h"
+
+#include "gfx.h"
+#include "gfx_setupdl.h"
+#include "regs.h"
+#include "sfx.h"
+#include "sys_matrix.h"
#include "terminal.h"
+#include "z64play.h"
+#include "z64skin.h"
+
#include "assets/objects/object_fhg/object_fhg.h"
#define FLAGS ACTOR_FLAG_UPDATE_CULLING_DISABLED
diff --git a/src/overlays/actors/ovl_Demo_Ext/z_demo_ext.h b/src/overlays/actors/ovl_Demo_Ext/z_demo_ext.h
index dbed1bf1f..2eadc4af6 100644
--- a/src/overlays/actors/ovl_Demo_Ext/z_demo_ext.h
+++ b/src/overlays/actors/ovl_Demo_Ext/z_demo_ext.h
@@ -2,12 +2,12 @@
#define Z_DEMO_EXT_H
#include "ultra64.h"
-#include "global.h"
+#include "z64actor.h"
struct DemoExt;
-typedef void (*DemoExtActionFunc)(struct DemoExt*, PlayState*);
-typedef void (*DemoExtDrawFunc)(Actor*, PlayState*);
+typedef void (*DemoExtActionFunc)(struct DemoExt*, struct PlayState*);
+typedef void (*DemoExtDrawFunc)(Actor*, struct PlayState*);
typedef struct DemoExt {
/* 0x0000 */ Actor actor;
diff --git a/src/overlays/actors/ovl_Demo_Gj/z_demo_gj.c b/src/overlays/actors/ovl_Demo_Gj/z_demo_gj.c
index 307cc9bf0..1cfb0ef82 100644
--- a/src/overlays/actors/ovl_Demo_Gj/z_demo_gj.c
+++ b/src/overlays/actors/ovl_Demo_Gj/z_demo_gj.c
@@ -21,6 +21,7 @@
#include "z64effect.h"
#include "z64play.h"
#include "z64player.h"
+#include "z64save.h"
#include "assets/objects/object_gj/object_gj.h"
@@ -128,19 +129,19 @@ s32 DemoGj_HitByExplosion(DemoGj* this, PlayState* play, ColliderCylinder* cylin
void DemoGj_DestroyCylinder(DemoGj* this, PlayState* play) {
switch (DemoGj_GetType(this)) {
case DEMOGJ_TYPE_DESTRUCTABLE_RUBBLE_1:
- Collider_DestroyCylinder(play, &this->cylinders[0]);
- Collider_DestroyCylinder(play, &this->cylinders[1]);
- Collider_DestroyCylinder(play, &this->cylinders[2]);
+ Collider_DestroyCylinder(play, &this->colliderCylinders[0]);
+ Collider_DestroyCylinder(play, &this->colliderCylinders[1]);
+ Collider_DestroyCylinder(play, &this->colliderCylinders[2]);
break;
case DEMOGJ_TYPE_DESTRUCTABLE_RUBBLE_2:
- Collider_DestroyCylinder(play, &this->cylinders[0]);
- Collider_DestroyCylinder(play, &this->cylinders[1]);
- Collider_DestroyCylinder(play, &this->cylinders[2]);
+ Collider_DestroyCylinder(play, &this->colliderCylinders[0]);
+ Collider_DestroyCylinder(play, &this->colliderCylinders[1]);
+ Collider_DestroyCylinder(play, &this->colliderCylinders[2]);
break;
case DEMOGJ_TYPE_DESTRUCTABLE_RUBBLE_TALL:
- Collider_DestroyCylinder(play, &this->cylinders[0]);
+ Collider_DestroyCylinder(play, &this->colliderCylinders[0]);
break;
}
}
@@ -987,9 +988,9 @@ void DemoGj_DrawRubbleAroundArena(DemoGj* this, PlayState* play) {
// Inits the three cylinders with `sCylinderInit1`
void DemoGj_InitDestructableRubble1(DemoGj* this, PlayState* play) {
DemoGj_InitSetIndices(this, play, 15, 0, NULL);
- DemoGj_InitCylinder(this, play, &this->cylinders[0], &sCylinderInit1);
- DemoGj_InitCylinder(this, play, &this->cylinders[1], &sCylinderInit1);
- DemoGj_InitCylinder(this, play, &this->cylinders[2], &sCylinderInit1);
+ DemoGj_InitCylinder(this, play, &this->colliderCylinders[0], &sCylinderInit1);
+ DemoGj_InitCylinder(this, play, &this->colliderCylinders[1], &sCylinderInit1);
+ DemoGj_InitCylinder(this, play, &this->colliderCylinders[2], &sCylinderInit1);
}
#if DEBUG_FEATURES
@@ -1002,9 +1003,9 @@ void DemoGj_DoNothing1(DemoGj* this, PlayState* play) {
* Used by DEMOGJ_TYPE_DESTRUCTABLE_RUBBLE_1
*/
void func_8097AEE8(DemoGj* this, PlayState* play) {
- ColliderCylinder* cylinder0 = &this->cylinders[0];
- ColliderCylinder* cylinder1 = &this->cylinders[1];
- ColliderCylinder* cylinder2 = &this->cylinders[2];
+ ColliderCylinder* cylinder0 = &this->colliderCylinders[0];
+ ColliderCylinder* cylinder1 = &this->colliderCylinders[1];
+ ColliderCylinder* cylinder2 = &this->colliderCylinders[2];
Vec3f* actorPos = &this->dyna.actor.world.pos;
s32 pad;
s16 theta = this->dyna.actor.world.rot.y;
@@ -1026,9 +1027,9 @@ void func_8097AEE8(DemoGj* this, PlayState* play) {
void DemoGj_SetCylindersAsAC(DemoGj* this, PlayState* play) {
s32 pad[2];
- Collider* cylinder0 = &this->cylinders[0].base;
- Collider* cylinder1 = &this->cylinders[1].base;
- Collider* cylinder2 = &this->cylinders[2].base;
+ Collider* cylinder0 = &this->colliderCylinders[0].base;
+ Collider* cylinder1 = &this->colliderCylinders[1].base;
+ Collider* cylinder2 = &this->colliderCylinders[2].base;
s32 pad2[3];
CollisionCheck_SetAC(play, &play->colChkCtx, cylinder0);
@@ -1060,13 +1061,13 @@ void func_8097B128(DemoGj* this, PlayState* play) {
}
s32 DemoGj_HasCylinderAnyExploded(DemoGj* this, PlayState* play) {
- if (DemoGj_HitByExplosion(this, play, &this->cylinders[0])) {
+ if (DemoGj_HitByExplosion(this, play, &this->colliderCylinders[0])) {
return true;
}
- if (DemoGj_HitByExplosion(this, play, &this->cylinders[1])) {
+ if (DemoGj_HitByExplosion(this, play, &this->colliderCylinders[1])) {
return true;
}
- if (DemoGj_HitByExplosion(this, play, &this->cylinders[2])) {
+ if (DemoGj_HitByExplosion(this, play, &this->colliderCylinders[2])) {
return true;
}
return false;
@@ -1124,9 +1125,9 @@ void DemoGj_DrawDestructableRubble1(DemoGj* this, PlayState* play) {
// Inits the three cylinders with `sCylinderInit2`
void DemoGj_InitDestructableRubble2(DemoGj* this, PlayState* play) {
DemoGj_InitSetIndices(this, play, 16, 0, NULL);
- DemoGj_InitCylinder(this, play, &this->cylinders[0], &sCylinderInit2);
- DemoGj_InitCylinder(this, play, &this->cylinders[1], &sCylinderInit2);
- DemoGj_InitCylinder(this, play, &this->cylinders[2], &sCylinderInit2);
+ DemoGj_InitCylinder(this, play, &this->colliderCylinders[0], &sCylinderInit2);
+ DemoGj_InitCylinder(this, play, &this->colliderCylinders[1], &sCylinderInit2);
+ DemoGj_InitCylinder(this, play, &this->colliderCylinders[2], &sCylinderInit2);
}
#if DEBUG_FEATURES
@@ -1136,9 +1137,9 @@ void DemoGj_DoNothing2(DemoGj* this, PlayState* play) {
// Moves the ColliderCylinder's relative to the actor's position.
void func_8097B450(DemoGj* this, PlayState* play) {
- ColliderCylinder* cylinder0 = &this->cylinders[0];
- ColliderCylinder* cylinder1 = &this->cylinders[1];
- ColliderCylinder* cylinder2 = &this->cylinders[2];
+ ColliderCylinder* cylinder0 = &this->colliderCylinders[0];
+ ColliderCylinder* cylinder1 = &this->colliderCylinders[1];
+ ColliderCylinder* cylinder2 = &this->colliderCylinders[2];
Vec3f* actorPos = &this->dyna.actor.world.pos;
s32 pad;
s16 theta = this->dyna.actor.world.rot.y;
@@ -1160,9 +1161,9 @@ void func_8097B450(DemoGj* this, PlayState* play) {
void DemoGj_SetCylindersAsAC2(DemoGj* this, PlayState* play) {
s32 pad[2];
- Collider* cylinder0 = &this->cylinders[0].base;
- Collider* cylinder1 = &this->cylinders[1].base;
- Collider* cylinder2 = &this->cylinders[2].base;
+ Collider* cylinder0 = &this->colliderCylinders[0].base;
+ Collider* cylinder1 = &this->colliderCylinders[1].base;
+ Collider* cylinder2 = &this->colliderCylinders[2].base;
s32 pad2[3];
CollisionCheck_SetAC(play, &play->colChkCtx, cylinder0);
@@ -1172,13 +1173,13 @@ void DemoGj_SetCylindersAsAC2(DemoGj* this, PlayState* play) {
// Does the same as `DemoGj_HasCylinderAnyExploded`
s32 DemoGj_HasCylinderAnyExploded2(DemoGj* this, PlayState* play) {
- if (DemoGj_HitByExplosion(this, play, &this->cylinders[0])) {
+ if (DemoGj_HitByExplosion(this, play, &this->colliderCylinders[0])) {
return true;
}
- if (DemoGj_HitByExplosion(this, play, &this->cylinders[1])) {
+ if (DemoGj_HitByExplosion(this, play, &this->colliderCylinders[1])) {
return true;
}
- if (DemoGj_HitByExplosion(this, play, &this->cylinders[2])) {
+ if (DemoGj_HitByExplosion(this, play, &this->colliderCylinders[2])) {
return true;
}
return false;
@@ -1259,7 +1260,7 @@ void DemoGj_DemoGj_InitDestructableRubble2(DemoGj* this, PlayState* play) {
// Inits the first cylinder (only that one) with `sCylinderInit3`
void DemoGj_InitDestructableRubbleTall(DemoGj* this, PlayState* play) {
DemoGj_InitSetIndices(this, play, 17, 0, NULL);
- DemoGj_InitCylinder(this, play, &this->cylinders[0], &sCylinderInit3);
+ DemoGj_InitCylinder(this, play, &this->colliderCylinders[0], &sCylinderInit3);
}
#if DEBUG_FEATURES
@@ -1301,7 +1302,7 @@ void func_8097B9BC(DemoGj* this, PlayState* play) {
*/
void func_8097BA48(DemoGj* this, PlayState* play) {
Actor* thisx = &this->dyna.actor;
- ColliderCylinder* cylinder = &this->cylinders[0];
+ ColliderCylinder* cylinder = &this->colliderCylinders[0];
s32 pad[2];
if (func_809797E4(this, 4)) {
diff --git a/src/overlays/actors/ovl_Demo_Gj/z_demo_gj.h b/src/overlays/actors/ovl_Demo_Gj/z_demo_gj.h
index 01a829f4f..313788893 100644
--- a/src/overlays/actors/ovl_Demo_Gj/z_demo_gj.h
+++ b/src/overlays/actors/ovl_Demo_Gj/z_demo_gj.h
@@ -17,7 +17,7 @@ typedef struct DemoGj {
/* 0x0178 */ BossGanon2* ganon;
/* 0x017C */ s32 isTransformedIntoGanon; // flag
/* 0x0180 */ s32 isRotated; // flag
- /* 0x0184 */ ColliderCylinder cylinders[3];
+ /* 0x0184 */ ColliderCylinder colliderCylinders[3];
/* 0x0268 */ s32 killFlag; // This actor never sets this flag, but it reads it. If set to `true` and the actor type is DEMOGJ_TYPE_DESTRUCTABLE_RUBBLE_1, DEMOGJ_TYPE_DESTRUCTABLE_RUBBLE_2 or DEMOGJ_TYPE_DESTRUCTABLE_RUBBLE_TALL, then the actor will be killed and will drop the specified amount of collectibles.
/* 0x026C */ Vec3f unk_26C; // This actor never sets this. Specifies which direction will this actor explode when killed using `killFlag`.
} DemoGj; // size = 0x0278
diff --git a/src/overlays/actors/ovl_Demo_Go/z_demo_go.c b/src/overlays/actors/ovl_Demo_Go/z_demo_go.c
index 01c173dcc..139e38a45 100644
--- a/src/overlays/actors/ovl_Demo_Go/z_demo_go.c
+++ b/src/overlays/actors/ovl_Demo_Go/z_demo_go.c
@@ -5,8 +5,18 @@
*/
#include "z_demo_go.h"
-#include "assets/objects/object_oF1d_map/object_oF1d_map.h"
+
+#include "gfx.h"
+#include "gfx_setupdl.h"
+#include "regs.h"
+#include "segmented_address.h"
+#include "sfx.h"
#include "terminal.h"
+#include "z_lib.h"
+#include "z64play.h"
+#include "z64skin_matrix.h"
+
+#include "assets/objects/object_oF1d_map/object_oF1d_map.h"
#define FLAGS ACTOR_FLAG_UPDATE_CULLING_DISABLED
diff --git a/src/overlays/actors/ovl_Demo_Go/z_demo_go.h b/src/overlays/actors/ovl_Demo_Go/z_demo_go.h
index 969fdd8e0..9abd5ed41 100644
--- a/src/overlays/actors/ovl_Demo_Go/z_demo_go.h
+++ b/src/overlays/actors/ovl_Demo_Go/z_demo_go.h
@@ -2,12 +2,12 @@
#define Z_DEMO_GO_H
#include "ultra64.h"
-#include "global.h"
+#include "z64actor.h"
struct DemoGo;
-typedef void (*DemoGoActionFunc)(struct DemoGo*, PlayState*);
-typedef void (*DemoGoDrawFunc)(struct DemoGo*, PlayState*);
+typedef void (*DemoGoActionFunc)(struct DemoGo*, struct PlayState*);
+typedef void (*DemoGoDrawFunc)(struct DemoGo*, struct PlayState*);
typedef struct DemoGo {
/* 0x0000 */ Actor actor;
diff --git a/src/overlays/actors/ovl_Demo_Gt/z_demo_gt.c b/src/overlays/actors/ovl_Demo_Gt/z_demo_gt.c
index 6e2a8023d..ebb9da34e 100644
--- a/src/overlays/actors/ovl_Demo_Gt/z_demo_gt.c
+++ b/src/overlays/actors/ovl_Demo_Gt/z_demo_gt.c
@@ -16,6 +16,7 @@
#include "z64effect.h"
#include "z64frame_advance.h"
#include "z64play.h"
+#include "z64save.h"
#include "assets/objects/object_gt/object_gt.h"
#include "assets/objects/object_geff/object_geff.h"
diff --git a/src/overlays/actors/ovl_Demo_Ik/z_demo_ik.c b/src/overlays/actors/ovl_Demo_Ik/z_demo_ik.c
index 82db3d7fa..cab53df6a 100644
--- a/src/overlays/actors/ovl_Demo_Ik/z_demo_ik.c
+++ b/src/overlays/actors/ovl_Demo_Ik/z_demo_ik.c
@@ -1,5 +1,13 @@
#include "z_demo_ik.h"
+
+#include "gfx.h"
+#include "gfx_setupdl.h"
+#include "sfx.h"
+#include "sys_matrix.h"
#include "terminal.h"
+#include "z64effect.h"
+#include "z64play.h"
+
#include "assets/objects/object_ik/object_ik.h"
#define FLAGS ACTOR_FLAG_UPDATE_CULLING_DISABLED
@@ -159,7 +167,7 @@ void DemoIk_MoveToStartPos(DemoIk* this, PlayState* play, s32 cueChannel) {
void DemoIk_Type1Init(DemoIk* this, PlayState* play) {
s32 pad[3];
- SkeletonHeader* skeleton;
+ FlexSkeletonHeader* skeleton;
AnimationHeader* animation;
f32 phi_f0;
@@ -181,7 +189,8 @@ void DemoIk_Type1Init(DemoIk* this, PlayState* play) {
// No break is required for matching
}
ActorShape_Init(&this->actor.shape, 0.0f, ActorShadow_DrawCircle, phi_f0);
- SkelAnime_Init(play, &this->skelAnime, skeleton, NULL, this->jointTable, this->morphTable, 2);
+ //! @bug Flex skeleton is used as normal skeleton
+ SkelAnime_Init(play, &this->skelAnime, (SkeletonHeader*)skeleton, NULL, this->jointTable, this->morphTable, 2);
Animation_Change(&this->skelAnime, animation, 1.0f, 0.0f, Animation_GetLastFrame(animation), ANIMMODE_ONCE, 0.0f);
}
diff --git a/src/overlays/actors/ovl_Demo_Ik/z_demo_ik.h b/src/overlays/actors/ovl_Demo_Ik/z_demo_ik.h
index 3b21af566..b4f2ca74e 100644
--- a/src/overlays/actors/ovl_Demo_Ik/z_demo_ik.h
+++ b/src/overlays/actors/ovl_Demo_Ik/z_demo_ik.h
@@ -2,12 +2,12 @@
#define Z_DEMO_IK_H
#include "ultra64.h"
-#include "global.h"
+#include "z64actor.h"
struct DemoIk;
-typedef void (*DemoIkActionFunc)(struct DemoIk* this, PlayState* play);
-typedef void (*DemoIkDrawFunc)(struct DemoIk* this, PlayState* play);
+typedef void (*DemoIkActionFunc)(struct DemoIk* this, struct PlayState* play);
+typedef void (*DemoIkDrawFunc)(struct DemoIk* this, struct PlayState* play);
typedef struct DemoIk {
/* 0x0000 */ Actor actor;
diff --git a/src/overlays/actors/ovl_Demo_Im/z_demo_im.c b/src/overlays/actors/ovl_Demo_Im/z_demo_im.c
index 7e359f662..95d68dd2b 100644
--- a/src/overlays/actors/ovl_Demo_Im/z_demo_im.c
+++ b/src/overlays/actors/ovl_Demo_Im/z_demo_im.c
@@ -7,9 +7,21 @@
#include "z_demo_im.h"
#include "overlays/actors/ovl_En_Arrow/z_en_arrow.h"
#include "overlays/actors/ovl_Door_Warp1/z_door_warp1.h"
+
+#include "gfx.h"
+#include "gfx_setupdl.h"
+#include "regs.h"
+#include "segmented_address.h"
+#include "sfx.h"
+#include "sys_matrix.h"
+#include "terminal.h"
+#include "z_lib.h"
+#include "z64play.h"
+#include "z64player.h"
+#include "z64save.h"
+
#include "assets/scenes/indoors/nakaniwa/nakaniwa_scene.h"
#include "assets/objects/object_im/object_im.h"
-#include "terminal.h"
#define FLAGS (ACTOR_FLAG_ATTENTION_ENABLED | ACTOR_FLAG_UPDATE_CULLING_DISABLED)
diff --git a/src/overlays/actors/ovl_Demo_Im/z_demo_im.h b/src/overlays/actors/ovl_Demo_Im/z_demo_im.h
index 94744969b..9477c21d8 100644
--- a/src/overlays/actors/ovl_Demo_Im/z_demo_im.h
+++ b/src/overlays/actors/ovl_Demo_Im/z_demo_im.h
@@ -2,12 +2,12 @@
#define Z_DEMO_IM_H
#include "ultra64.h"
-#include "global.h"
+#include "z64actor.h"
struct DemoIm;
-typedef void (*DemoImActionFunc)(struct DemoIm*, PlayState*);
-typedef void (*DemoImDrawFunc)(struct DemoIm*, PlayState*);
+typedef void (*DemoImActionFunc)(struct DemoIm*, struct PlayState*);
+typedef void (*DemoImDrawFunc)(struct DemoIm*, struct PlayState*);
typedef enum ImpaLimb {
/* 0x00 */ IMPA_LIMB_NONE,
diff --git a/src/overlays/actors/ovl_Demo_Im/z_demo_im_cutscene_data.inc.c b/src/overlays/actors/ovl_Demo_Im/z_demo_im_cutscene_data.inc.c
index f56097680..7a9a0dde8 100644
--- a/src/overlays/actors/ovl_Demo_Im/z_demo_im_cutscene_data.inc.c
+++ b/src/overlays/actors/ovl_Demo_Im/z_demo_im_cutscene_data.inc.c
@@ -1,4 +1,4 @@
-#include "z_demo_im.h"
+#include "sequence.h"
#include "z64cutscene_commands.h"
// clang-format off
diff --git a/src/overlays/actors/ovl_Demo_Kankyo/z_demo_kankyo.c b/src/overlays/actors/ovl_Demo_Kankyo/z_demo_kankyo.c
index 50ae630b5..e3ac3e78f 100644
--- a/src/overlays/actors/ovl_Demo_Kankyo/z_demo_kankyo.c
+++ b/src/overlays/actors/ovl_Demo_Kankyo/z_demo_kankyo.c
@@ -1,13 +1,28 @@
#include "z_demo_kankyo.h"
-#include "global.h"
+
+#include "libc64/qrand.h"
+#include "attributes.h"
+#include "gfx.h"
+#include "gfx_setupdl.h"
+#include "segmented_address.h"
+#include "sfx.h"
+#include "sys_matrix.h"
#include "versions.h"
+#include "z_lib.h"
#include "z64cutscene_commands.h"
+#include "z64cutscene_flags.h"
+#include "z64cutscene_spline.h"
+#include "z64olib.h"
+#include "z64play.h"
+#include "z64player.h"
+#include "z64save.h"
+
#include "assets/objects/gameplay_keep/gameplay_keep.h"
#include "assets/objects/object_efc_star_field/object_efc_star_field.h"
#include "assets/objects/object_toki_objects/object_toki_objects.h"
-#pragma increment_block_number "gc-eu:128 gc-eu-mq:128 gc-jp:128 gc-jp-ce:128 gc-jp-mq:128 gc-us:128 gc-us-mq:128" \
- "ique-cn:128 ntsc-1.0:128 ntsc-1.1:128 ntsc-1.2:128 pal-1.0:128 pal-1.1:128"
+#pragma increment_block_number "gc-eu:0 gc-eu-mq:0 gc-jp:0 gc-jp-ce:0 gc-jp-mq:0 gc-us:0 gc-us-mq:0 ique-cn:0" \
+ "ntsc-1.0:0 ntsc-1.1:0 ntsc-1.2:0 pal-1.0:0 pal-1.1:0"
#define FLAGS (ACTOR_FLAG_UPDATE_CULLING_DISABLED | ACTOR_FLAG_DRAW_CULLING_DISABLED)
diff --git a/src/overlays/actors/ovl_Demo_Kankyo/z_demo_kankyo_cutscene_data1.c b/src/overlays/actors/ovl_Demo_Kankyo/z_demo_kankyo_cutscene_data1.c
index 3a0a95a90..4e17a4a53 100644
--- a/src/overlays/actors/ovl_Demo_Kankyo/z_demo_kankyo_cutscene_data1.c
+++ b/src/overlays/actors/ovl_Demo_Kankyo/z_demo_kankyo_cutscene_data1.c
@@ -1,4 +1,3 @@
-#include "z_demo_kankyo.h"
#include "z64cutscene_commands.h"
// clang-format off
diff --git a/src/overlays/actors/ovl_Demo_Kekkai/z_demo_kekkai.c b/src/overlays/actors/ovl_Demo_Kekkai/z_demo_kekkai.c
index 8c6ded165..2a79aef45 100644
--- a/src/overlays/actors/ovl_Demo_Kekkai/z_demo_kekkai.c
+++ b/src/overlays/actors/ovl_Demo_Kekkai/z_demo_kekkai.c
@@ -5,6 +5,21 @@
*/
#include "z_demo_kekkai.h"
+
+#include "libu64/debug.h"
+#include "gfx.h"
+#include "gfx_setupdl.h"
+#include "rand.h"
+#include "segmented_address.h"
+#include "sequence.h"
+#include "sfx.h"
+#include "sys_matrix.h"
+#include "z_lib.h"
+#include "z64audio.h"
+#include "z64effect.h"
+#include "z64play.h"
+#include "z64save.h"
+
#include "assets/objects/object_demo_kekkai/object_demo_kekkai.h"
#include "assets/scenes/dungeons/ganontika/ganontika_scene.h"
diff --git a/src/overlays/actors/ovl_Demo_Kekkai/z_demo_kekkai.h b/src/overlays/actors/ovl_Demo_Kekkai/z_demo_kekkai.h
index 8e396c4ec..182b1d587 100644
--- a/src/overlays/actors/ovl_Demo_Kekkai/z_demo_kekkai.h
+++ b/src/overlays/actors/ovl_Demo_Kekkai/z_demo_kekkai.h
@@ -2,11 +2,11 @@
#define Z_DEMO_KEKKAI_H
#include "ultra64.h"
-#include "global.h"
+#include "z64actor.h"
struct DemoKekkai;
-typedef void (*DemoKekkaiUpdateFunc)(struct DemoKekkai* this, PlayState* play);
+typedef void (*DemoKekkaiUpdateFunc)(struct DemoKekkai* this, struct PlayState* play);
typedef struct DemoKekkai {
/* 0x0000 */ Actor actor;
diff --git a/src/overlays/actors/ovl_Demo_Sa/z_demo_sa.c b/src/overlays/actors/ovl_Demo_Sa/z_demo_sa.c
index 36e521701..3b6ed448d 100644
--- a/src/overlays/actors/ovl_Demo_Sa/z_demo_sa.c
+++ b/src/overlays/actors/ovl_Demo_Sa/z_demo_sa.c
@@ -7,9 +7,20 @@
#include "z_demo_sa.h"
#include "overlays/actors/ovl_En_Elf/z_en_elf.h"
#include "overlays/actors/ovl_Door_Warp1/z_door_warp1.h"
-#include "assets/objects/object_sa/object_sa.h"
+#include "gfx.h"
+#include "gfx_setupdl.h"
+#include "regs.h"
+#include "segmented_address.h"
+#include "sfx.h"
+#include "sequence.h"
#include "terminal.h"
+#include "z_lib.h"
+#include "z64play.h"
+#include "z64player.h"
+#include "z64save.h"
+
+#include "assets/objects/object_sa/object_sa.h"
#define FLAGS ACTOR_FLAG_UPDATE_CULLING_DISABLED
diff --git a/src/overlays/actors/ovl_Demo_Sa/z_demo_sa.h b/src/overlays/actors/ovl_Demo_Sa/z_demo_sa.h
index 1f66c4fec..639d50a63 100644
--- a/src/overlays/actors/ovl_Demo_Sa/z_demo_sa.h
+++ b/src/overlays/actors/ovl_Demo_Sa/z_demo_sa.h
@@ -2,12 +2,12 @@
#define Z_DEMO_SA_H
#include "ultra64.h"
-#include "global.h"
+#include "z64actor.h"
struct DemoSa;
-typedef void (*DemoSaActionFunc)(struct DemoSa*, PlayState*);
-typedef void (*DemoSaDrawFunc)(struct DemoSa*, PlayState*);
+typedef void (*DemoSaActionFunc)(struct DemoSa*, struct PlayState*);
+typedef void (*DemoSaDrawFunc)(struct DemoSa*, struct PlayState*);
typedef struct DemoSa {
/* 0x0000 */ Actor actor;
diff --git a/src/overlays/actors/ovl_Demo_Shd/z_demo_shd.c b/src/overlays/actors/ovl_Demo_Shd/z_demo_shd.c
index d5cb025e4..549daf0db 100644
--- a/src/overlays/actors/ovl_Demo_Shd/z_demo_shd.c
+++ b/src/overlays/actors/ovl_Demo_Shd/z_demo_shd.c
@@ -6,6 +6,13 @@
#include "z_demo_shd.h"
+#include "gfx.h"
+#include "gfx_setupdl.h"
+#include "sequence.h"
+#include "sys_matrix.h"
+#include "z64audio.h"
+#include "z64play.h"
+
#define FLAGS (ACTOR_FLAG_UPDATE_CULLING_DISABLED | ACTOR_FLAG_DRAW_CULLING_DISABLED)
void DemoShd_Init(Actor* thisx, PlayState* play);
diff --git a/src/overlays/actors/ovl_Demo_Shd/z_demo_shd.h b/src/overlays/actors/ovl_Demo_Shd/z_demo_shd.h
index fe9198f62..eb62a3983 100644
--- a/src/overlays/actors/ovl_Demo_Shd/z_demo_shd.h
+++ b/src/overlays/actors/ovl_Demo_Shd/z_demo_shd.h
@@ -2,11 +2,11 @@
#define Z_DEMO_SHD_H
#include "ultra64.h"
-#include "global.h"
+#include "z64actor.h"
struct DemoShd;
-typedef void (*DemoShdActionFunc)(struct DemoShd*, PlayState*);
+typedef void (*DemoShdActionFunc)(struct DemoShd*, struct PlayState*);
typedef struct DemoShd {
/* 0x0000 */ Actor actor;
diff --git a/src/overlays/actors/ovl_Demo_Tre_Lgt/z_demo_tre_lgt.c b/src/overlays/actors/ovl_Demo_Tre_Lgt/z_demo_tre_lgt.c
index 67adb46e7..dcafdfed2 100644
--- a/src/overlays/actors/ovl_Demo_Tre_Lgt/z_demo_tre_lgt.c
+++ b/src/overlays/actors/ovl_Demo_Tre_Lgt/z_demo_tre_lgt.c
@@ -1,5 +1,13 @@
#include "z_demo_tre_lgt.h"
#include "overlays/actors/ovl_En_Box/z_en_box.h"
+
+#include "gfx.h"
+#include "gfx_setupdl.h"
+#include "sfx.h"
+#include "z64curve.h"
+#include "z64play.h"
+#include "z64save.h"
+
#include "assets/objects/object_box/object_box.h"
#define FLAGS ACTOR_FLAG_UPDATE_CULLING_DISABLED
diff --git a/src/overlays/actors/ovl_Demo_Tre_Lgt/z_demo_tre_lgt.h b/src/overlays/actors/ovl_Demo_Tre_Lgt/z_demo_tre_lgt.h
index 0cad6996d..47f6c3564 100644
--- a/src/overlays/actors/ovl_Demo_Tre_Lgt/z_demo_tre_lgt.h
+++ b/src/overlays/actors/ovl_Demo_Tre_Lgt/z_demo_tre_lgt.h
@@ -2,11 +2,12 @@
#define Z_DEMO_TRE_LGT_H
#include "ultra64.h"
-#include "global.h"
+#include "z64actor.h"
+#include "z64curve.h"
struct DemoTreLgt;
-typedef void (*DemoTreLgtActionFunc)(struct DemoTreLgt*, PlayState*);
+typedef void (*DemoTreLgtActionFunc)(struct DemoTreLgt*, struct PlayState*);
typedef struct DemoTreLgt {
/* 0x0000 */ Actor actor;
diff --git a/src/overlays/actors/ovl_Door_Ana/z_door_ana.c b/src/overlays/actors/ovl_Door_Ana/z_door_ana.c
index 40f487883..4034dafc9 100644
--- a/src/overlays/actors/ovl_Door_Ana/z_door_ana.c
+++ b/src/overlays/actors/ovl_Door_Ana/z_door_ana.c
@@ -5,6 +5,17 @@
*/
#include "z_door_ana.h"
+
+#include "gfx.h"
+#include "gfx_setupdl.h"
+#include "sfx.h"
+#include "sys_matrix.h"
+#include "z_lib.h"
+#include "z64cutscene_flags.h"
+#include "z64play.h"
+#include "z64player.h"
+#include "z64save.h"
+
#include "assets/objects/gameplay_field_keep/gameplay_field_keep.h"
#define FLAGS ACTOR_FLAG_UPDATE_DURING_OCARINA
diff --git a/src/overlays/actors/ovl_Door_Ana/z_door_ana.h b/src/overlays/actors/ovl_Door_Ana/z_door_ana.h
index 51c24b84a..0092bd8f1 100644
--- a/src/overlays/actors/ovl_Door_Ana/z_door_ana.h
+++ b/src/overlays/actors/ovl_Door_Ana/z_door_ana.h
@@ -2,11 +2,11 @@
#define Z_DOOR_ANA_H
#include "ultra64.h"
-#include "global.h"
+#include "z64actor.h"
struct DoorAna;
-typedef void (*DoorAnaActionFunc)(struct DoorAna*, PlayState*);
+typedef void (*DoorAnaActionFunc)(struct DoorAna*, struct PlayState*);
typedef struct DoorAna {
/* 0x0000 */ Actor actor;
diff --git a/src/overlays/actors/ovl_Door_Gerudo/z_door_gerudo.c b/src/overlays/actors/ovl_Door_Gerudo/z_door_gerudo.c
index 360f4aede..2f9f4e118 100644
--- a/src/overlays/actors/ovl_Door_Gerudo/z_door_gerudo.c
+++ b/src/overlays/actors/ovl_Door_Gerudo/z_door_gerudo.c
@@ -5,6 +5,17 @@
*/
#include "z_door_gerudo.h"
+
+#include "gfx.h"
+#include "gfx_setupdl.h"
+#include "ichain.h"
+#include "sfx.h"
+#include "sys_matrix.h"
+#include "z_lib.h"
+#include "z64play.h"
+#include "z64player.h"
+#include "z64save.h"
+
#include "assets/objects/object_door_gerudo/object_door_gerudo.h"
#define FLAGS 0
diff --git a/src/overlays/actors/ovl_Door_Gerudo/z_door_gerudo.h b/src/overlays/actors/ovl_Door_Gerudo/z_door_gerudo.h
index c00a0fa66..efd295976 100644
--- a/src/overlays/actors/ovl_Door_Gerudo/z_door_gerudo.h
+++ b/src/overlays/actors/ovl_Door_Gerudo/z_door_gerudo.h
@@ -2,11 +2,11 @@
#define Z_DOOR_GERUDO_H
#include "ultra64.h"
-#include "global.h"
+#include "z64actor.h"
struct DoorGerudo;
-typedef void (*DoorGerudoActionFunc)(struct DoorGerudo*, PlayState*);
+typedef void (*DoorGerudoActionFunc)(struct DoorGerudo*, struct PlayState*);
typedef struct DoorGerudo {
/* 0x0000 */ SLIDING_DOOR_ACTOR_BASE;
diff --git a/src/overlays/actors/ovl_Door_Killer/z_door_killer.c b/src/overlays/actors/ovl_Door_Killer/z_door_killer.c
index 0f2d3163e..7c00f0118 100644
--- a/src/overlays/actors/ovl_Door_Killer/z_door_killer.c
+++ b/src/overlays/actors/ovl_Door_Killer/z_door_killer.c
@@ -5,6 +5,17 @@
*/
#include "z_door_killer.h"
+
+#include "gfx.h"
+#include "gfx_setupdl.h"
+#include "rand.h"
+#include "segmented_address.h"
+#include "sfx.h"
+#include "z_lib.h"
+#include "z64effect.h"
+#include "z64play.h"
+#include "z64player.h"
+
#include "assets/objects/gameplay_keep/gameplay_keep.h"
#include "assets/objects/object_hidan_objects/object_hidan_objects.h"
#include "assets/objects/object_mizu_objects/object_mizu_objects.h"
@@ -61,7 +72,7 @@ static ColliderCylinderInit sCylinderInit = {
{ 20, 100, 0, { 0, 0, 0 } },
};
-static ColliderJntSphElementInit sJntSphItemsInit[1] = {
+static ColliderJntSphElementInit sJntSphElementsInit[1] = {
{
{
ELEM_MATERIAL_UNK0,
@@ -85,7 +96,7 @@ static ColliderJntSphInit sJntSphInit = {
COLSHAPE_JNTSPH,
},
1,
- sJntSphItemsInit,
+ sJntSphElementsInit,
};
static DoorKillerTextureEntry sDoorTextures[4] = {
@@ -137,7 +148,7 @@ void DoorKiller_Init(Actor* thisx, PlayState* play2) {
Collider_InitCylinder(play, &this->colliderCylinder);
Collider_SetCylinder(play, &this->colliderCylinder, &this->actor, &sCylinderInit);
Collider_InitJntSph(play, &this->colliderJntSph);
- Collider_SetJntSph(play, &this->colliderJntSph, &this->actor, &sJntSphInit, this->colliderJntSphItems);
+ Collider_SetJntSph(play, &this->colliderJntSph, &this->actor, &sJntSphInit, this->colliderJntSphElements);
this->colliderJntSph.elements[0].dim.worldSphere.radius = 80;
this->colliderJntSph.elements[0].dim.worldSphere.center.x = (s16)this->actor.world.pos.x;
this->colliderJntSph.elements[0].dim.worldSphere.center.y = (s16)this->actor.world.pos.y + 50;
diff --git a/src/overlays/actors/ovl_Door_Killer/z_door_killer.h b/src/overlays/actors/ovl_Door_Killer/z_door_killer.h
index 597624df1..32eaaeb01 100644
--- a/src/overlays/actors/ovl_Door_Killer/z_door_killer.h
+++ b/src/overlays/actors/ovl_Door_Killer/z_door_killer.h
@@ -2,7 +2,7 @@
#define Z_DOOR_KILLER_H
#include "ultra64.h"
-#include "global.h"
+#include "z64actor.h"
/*
* Associated switch flag: (params >> 8) & 0x3F
@@ -16,7 +16,7 @@ typedef struct DoorKillerTextureEntry {
struct DoorKiller;
-typedef void (*DoorKillerActionFunc)(struct DoorKiller*, PlayState*);
+typedef void (*DoorKillerActionFunc)(struct DoorKiller*, struct PlayState*);
typedef struct DoorKiller {
/* 0x0000 */ DOOR_ACTOR_BASE;
@@ -28,7 +28,7 @@ typedef struct DoorKiller {
/* 0x021C */ u8 requiredObjectSlot;
/* 0x021D */ u8 textureEntryIndex;
/* 0x0220 */ ColliderJntSph colliderJntSph;
- /* 0x0240 */ ColliderJntSphElement colliderJntSphItems[1];
+ /* 0x0240 */ ColliderJntSphElement colliderJntSphElements[1];
/* 0x0280 */ DoorKillerActionFunc actionFunc;
} DoorKiller; // size = 0x0284
diff --git a/src/overlays/actors/ovl_Door_Shutter/z_door_shutter.c b/src/overlays/actors/ovl_Door_Shutter/z_door_shutter.c
index f25d82df2..1252d7db5 100644
--- a/src/overlays/actors/ovl_Door_Shutter/z_door_shutter.c
+++ b/src/overlays/actors/ovl_Door_Shutter/z_door_shutter.c
@@ -21,8 +21,7 @@
#include "z64audio.h"
#include "z64play.h"
#include "z64player.h"
-
-#include "global.h"
+#include "z64save.h"
#include "assets/objects/gameplay_keep/gameplay_keep.h"
#include "assets/objects/object_gnd/object_gnd.h"
diff --git a/src/overlays/actors/ovl_Door_Toki/z_door_toki.c b/src/overlays/actors/ovl_Door_Toki/z_door_toki.c
index bf423a09b..ceef1f93f 100644
--- a/src/overlays/actors/ovl_Door_Toki/z_door_toki.c
+++ b/src/overlays/actors/ovl_Door_Toki/z_door_toki.c
@@ -5,6 +5,11 @@
*/
#include "z_door_toki.h"
+
+#include "ichain.h"
+#include "z64play.h"
+#include "z64save.h"
+
#include "assets/objects/object_toki_objects/object_toki_objects.h"
#define FLAGS 0
diff --git a/src/overlays/actors/ovl_Door_Toki/z_door_toki.h b/src/overlays/actors/ovl_Door_Toki/z_door_toki.h
index 35d4d4f91..8e276c56b 100644
--- a/src/overlays/actors/ovl_Door_Toki/z_door_toki.h
+++ b/src/overlays/actors/ovl_Door_Toki/z_door_toki.h
@@ -2,7 +2,7 @@
#define Z_DOOR_TOKI_H
#include "ultra64.h"
-#include "global.h"
+#include "z64actor.h"
struct DoorToki;
diff --git a/src/overlays/actors/ovl_Door_Warp1/z_door_warp1.c b/src/overlays/actors/ovl_Door_Warp1/z_door_warp1.c
index 6927a0f16..7c5709434 100644
--- a/src/overlays/actors/ovl_Door_Warp1/z_door_warp1.c
+++ b/src/overlays/actors/ovl_Door_Warp1/z_door_warp1.c
@@ -12,6 +12,7 @@
#include "z64light.h"
#include "z64play.h"
#include "z64player.h"
+#include "z64save.h"
#include "assets/objects/object_warp1/object_warp1.h"
diff --git a/src/overlays/actors/ovl_Efc_Erupc/z_efc_erupc.c b/src/overlays/actors/ovl_Efc_Erupc/z_efc_erupc.c
index ae7c4a807..677458f18 100644
--- a/src/overlays/actors/ovl_Efc_Erupc/z_efc_erupc.c
+++ b/src/overlays/actors/ovl_Efc_Erupc/z_efc_erupc.c
@@ -1,4 +1,16 @@
#include "z_efc_erupc.h"
+
+#include "gfx.h"
+#include "gfx_setupdl.h"
+#include "rand.h"
+#include "sfx.h"
+#include "sequence.h"
+#include "sys_matrix.h"
+#include "z_lib.h"
+#include "z64audio.h"
+#include "z64play.h"
+#include "z64save.h"
+
#include "assets/objects/object_efc_erupc/object_efc_erupc.h"
#define FLAGS (ACTOR_FLAG_UPDATE_CULLING_DISABLED | ACTOR_FLAG_DRAW_CULLING_DISABLED)
diff --git a/src/overlays/actors/ovl_Efc_Erupc/z_efc_erupc.h b/src/overlays/actors/ovl_Efc_Erupc/z_efc_erupc.h
index 6d14c32d7..888d9580e 100644
--- a/src/overlays/actors/ovl_Efc_Erupc/z_efc_erupc.h
+++ b/src/overlays/actors/ovl_Efc_Erupc/z_efc_erupc.h
@@ -2,11 +2,11 @@
#define Z_EFC_ERUPC_H
#include "ultra64.h"
-#include "global.h"
+#include "z64actor.h"
struct EfcErupc;
-typedef void (*EfcErupcActionFunc)(struct EfcErupc*, PlayState*);
+typedef void (*EfcErupcActionFunc)(struct EfcErupc*, struct PlayState*);
#define EFC_ERUPC_EFFECT_COUNT 100
diff --git a/src/overlays/actors/ovl_Eff_Dust/z_eff_dust.c b/src/overlays/actors/ovl_Eff_Dust/z_eff_dust.c
index f23a974a3..e8f9f2684 100644
--- a/src/overlays/actors/ovl_Eff_Dust/z_eff_dust.c
+++ b/src/overlays/actors/ovl_Eff_Dust/z_eff_dust.c
@@ -5,6 +5,18 @@
*/
#include "z_eff_dust.h"
+
+#include "libc64/malloc.h"
+#include "libc64/qrand.h"
+#include "gfx.h"
+#include "gfx_setupdl.h"
+#include "rand.h"
+#include "segmented_address.h"
+#include "sys_matrix.h"
+#include "z_lib.h"
+#include "z64play.h"
+#include "z64player.h"
+
#include "assets/objects/gameplay_keep/gameplay_keep.h"
#define FLAGS (ACTOR_FLAG_UPDATE_CULLING_DISABLED | ACTOR_FLAG_DRAW_CULLING_DISABLED)
diff --git a/src/overlays/actors/ovl_Eff_Dust/z_eff_dust.h b/src/overlays/actors/ovl_Eff_Dust/z_eff_dust.h
index e77a8e022..153b6d4e2 100644
--- a/src/overlays/actors/ovl_Eff_Dust/z_eff_dust.h
+++ b/src/overlays/actors/ovl_Eff_Dust/z_eff_dust.h
@@ -2,12 +2,12 @@
#define Z_EFF_DUST_H
#include "ultra64.h"
-#include "global.h"
+#include "z64actor.h"
struct EffDust;
-typedef void (*EffDustActionFunc)(struct EffDust*, PlayState*);
-typedef void (*EffDustDrawFunc)(Actor*, PlayState*);
+typedef void (*EffDustActionFunc)(struct EffDust*, struct PlayState*);
+typedef void (*EffDustDrawFunc)(Actor*, struct PlayState*);
typedef struct EffDust {
/* 0x0000 */ Actor actor;
diff --git a/src/overlays/actors/ovl_Elf_Msg/z_elf_msg.c b/src/overlays/actors/ovl_Elf_Msg/z_elf_msg.c
index a4ebdfb13..9e9510f2d 100644
--- a/src/overlays/actors/ovl_Elf_Msg/z_elf_msg.c
+++ b/src/overlays/actors/ovl_Elf_Msg/z_elf_msg.c
@@ -5,8 +5,16 @@
*/
#include "z_elf_msg.h"
-#include "global.h"
+
+#include "libu64/debug.h"
+#include "gfx.h"
+#include "gfx_setupdl.h"
+#include "ichain.h"
+#include "regs.h"
#include "terminal.h"
+#include "z64play.h"
+#include "z64player.h"
+
#include "overlays/actors/ovl_En_Elf/z_en_elf.h"
#define FLAGS ACTOR_FLAG_UPDATE_CULLING_DISABLED
diff --git a/src/overlays/actors/ovl_Elf_Msg2/z_elf_msg2.c b/src/overlays/actors/ovl_Elf_Msg2/z_elf_msg2.c
index 0f0edc34e..562eef8a4 100644
--- a/src/overlays/actors/ovl_Elf_Msg2/z_elf_msg2.c
+++ b/src/overlays/actors/ovl_Elf_Msg2/z_elf_msg2.c
@@ -5,7 +5,15 @@
*/
#include "z_elf_msg2.h"
+
+#include "libu64/debug.h"
+#include "gfx.h"
+#include "gfx_setupdl.h"
+#include "ichain.h"
+#include "regs.h"
+#include "sys_matrix.h"
#include "terminal.h"
+#include "z64play.h"
#define FLAGS ACTOR_FLAG_UPDATE_CULLING_DISABLED
diff --git a/src/overlays/actors/ovl_Elf_Msg2/z_elf_msg2.h b/src/overlays/actors/ovl_Elf_Msg2/z_elf_msg2.h
index 802769f2b..5a0a69341 100644
--- a/src/overlays/actors/ovl_Elf_Msg2/z_elf_msg2.h
+++ b/src/overlays/actors/ovl_Elf_Msg2/z_elf_msg2.h
@@ -2,11 +2,11 @@
#define Z_ELF_MSG2_H
#include "ultra64.h"
-#include "global.h"
+#include "z64actor.h"
struct ElfMsg2;
-typedef void (*ElfMsg2ActionFunc)(struct ElfMsg2*, PlayState*);
+typedef void (*ElfMsg2ActionFunc)(struct ElfMsg2*, struct PlayState*);
typedef struct ElfMsg2 {
/* 0x0000 */ Actor actor;
diff --git a/src/overlays/actors/ovl_En_Ani/z_en_ani.c b/src/overlays/actors/ovl_En_Ani/z_en_ani.c
index 242afc095..8bfcc38fa 100644
--- a/src/overlays/actors/ovl_En_Ani/z_en_ani.c
+++ b/src/overlays/actors/ovl_En_Ani/z_en_ani.c
@@ -5,6 +5,18 @@
*/
#include "z_en_ani.h"
+
+#include "gfx.h"
+#include "gfx_setupdl.h"
+#include "ichain.h"
+#include "segmented_address.h"
+#include "sfx.h"
+#include "sys_matrix.h"
+#include "z_lib.h"
+#include "z64face_reaction.h"
+#include "z64play.h"
+#include "z64save.h"
+
#include "assets/objects/object_ani/object_ani.h"
#define FLAGS (ACTOR_FLAG_ATTENTION_ENABLED | ACTOR_FLAG_FRIENDLY)
diff --git a/src/overlays/actors/ovl_En_Ani/z_en_ani.h b/src/overlays/actors/ovl_En_Ani/z_en_ani.h
index 99bad6e1c..454a7bd8d 100644
--- a/src/overlays/actors/ovl_En_Ani/z_en_ani.h
+++ b/src/overlays/actors/ovl_En_Ani/z_en_ani.h
@@ -2,11 +2,11 @@
#define Z_EN_ANI_H
#include "ultra64.h"
-#include "global.h"
+#include "z64actor.h"
struct EnAni;
-typedef void (*EnAniActionFunc)(struct EnAni*, PlayState*);
+typedef void (*EnAniActionFunc)(struct EnAni*, struct PlayState*);
typedef struct EnAni {
/* 0x0000 */ Actor actor;
diff --git a/src/overlays/actors/ovl_En_Anubice_Fire/z_en_anubice_fire.c b/src/overlays/actors/ovl_En_Anubice_Fire/z_en_anubice_fire.c
index 9e408a335..480940dc4 100644
--- a/src/overlays/actors/ovl_En_Anubice_Fire/z_en_anubice_fire.c
+++ b/src/overlays/actors/ovl_En_Anubice_Fire/z_en_anubice_fire.c
@@ -5,6 +5,19 @@
*/
#include "z_en_anubice_fire.h"
+
+#include "libc64/qrand.h"
+#include "gfx.h"
+#include "gfx_setupdl.h"
+#include "rand.h"
+#include "segmented_address.h"
+#include "sfx.h"
+#include "sys_matrix.h"
+#include "z_lib.h"
+#include "z64effect.h"
+#include "z64play.h"
+#include "z64player.h"
+
#include "assets/objects/gameplay_keep/gameplay_keep.h"
#include "assets/objects/object_anubice/object_anubice.h"
@@ -55,8 +68,8 @@ void EnAnubiceFire_Init(Actor* thisx, PlayState* play) {
EnAnubiceFire* this = (EnAnubiceFire*)thisx;
s32 i;
- Collider_InitCylinder(play, &this->cylinder);
- Collider_SetCylinder(play, &this->cylinder, &this->actor, &sCylinderInit);
+ Collider_InitCylinder(play, &this->colliderCylinder);
+ Collider_SetCylinder(play, &this->colliderCylinder, &this->actor, &sCylinderInit);
this->unk_15A = 30;
this->unk_154 = 2.0f;
@@ -73,7 +86,7 @@ void EnAnubiceFire_Init(Actor* thisx, PlayState* play) {
void EnAnubiceFire_Destroy(Actor* thisx, PlayState* play) {
EnAnubiceFire* this = (EnAnubiceFire*)thisx;
- Collider_DestroyCylinder(play, &this->cylinder);
+ Collider_DestroyCylinder(play, &this->colliderCylinder);
}
void func_809B26EC(EnAnubiceFire* this, PlayState* play) {
@@ -108,12 +121,12 @@ void func_809B27D8(EnAnubiceFire* this, PlayState* play) {
Math_ApproachF(&this->scale, this->unk_154, 0.2f, 0.4f);
if ((this->unk_15A == 0) && (this->scale < 0.1f)) {
Actor_Kill(&this->actor);
- } else if ((this->actor.params == 0) && (this->cylinder.base.atFlags & AT_BOUNCED)) {
+ } else if ((this->actor.params == 0) && (this->colliderCylinder.base.atFlags & AT_BOUNCED)) {
if (Player_HasMirrorShieldEquipped(play)) {
Actor_PlaySfx(&this->actor, NA_SE_IT_SHIELD_REFLECT_SW);
- this->cylinder.base.atFlags &= ~(AT_HIT | AT_BOUNCED | AT_TYPE_ENEMY);
- this->cylinder.base.atFlags |= AT_TYPE_PLAYER;
- this->cylinder.elem.atDmgInfo.dmgFlags = DMG_DEKU_STICK;
+ this->colliderCylinder.base.atFlags &= ~(AT_HIT | AT_BOUNCED | AT_TYPE_ENEMY);
+ this->colliderCylinder.base.atFlags |= AT_TYPE_PLAYER;
+ this->colliderCylinder.elem.atDmgInfo.dmgFlags = DMG_DEKU_STICK;
this->unk_15A = 30;
this->actor.params = 1;
this->actor.velocity.x *= -1.0f;
@@ -195,14 +208,14 @@ void EnAnubiceFire_Update(Actor* thisx, PlayState* play) {
UPDBGCHECKINFO_FLAG_0 | UPDBGCHECKINFO_FLAG_2 | UPDBGCHECKINFO_FLAG_3 |
UPDBGCHECKINFO_FLAG_4);
if (!(this->scale < 0.6f || this->actionFunc == func_809B2B48)) {
- this->cylinder.dim.radius = this->scale * 15.0f + 5.0f;
- this->cylinder.dim.height = this->scale * 15.0f + 5.0f;
- this->cylinder.dim.yShift = this->scale * -0.75f + -15.0f;
+ this->colliderCylinder.dim.radius = this->scale * 15.0f + 5.0f;
+ this->colliderCylinder.dim.height = this->scale * 15.0f + 5.0f;
+ this->colliderCylinder.dim.yShift = this->scale * -0.75f + -15.0f;
if (this->unk_15A != 0) {
- Collider_UpdateCylinder(&this->actor, &this->cylinder);
- CollisionCheck_SetAT(play, &play->colChkCtx, &this->cylinder.base);
- CollisionCheck_SetAC(play, &play->colChkCtx, &this->cylinder.base);
+ Collider_UpdateCylinder(&this->actor, &this->colliderCylinder);
+ CollisionCheck_SetAT(play, &play->colChkCtx, &this->colliderCylinder.base);
+ CollisionCheck_SetAC(play, &play->colChkCtx, &this->colliderCylinder.base);
}
if (BgCheck_SphVsFirstPoly(&play->colCtx, &this->actor.world.pos, 30.0f)) {
diff --git a/src/overlays/actors/ovl_En_Anubice_Fire/z_en_anubice_fire.h b/src/overlays/actors/ovl_En_Anubice_Fire/z_en_anubice_fire.h
index 8119efa7a..34072a43b 100644
--- a/src/overlays/actors/ovl_En_Anubice_Fire/z_en_anubice_fire.h
+++ b/src/overlays/actors/ovl_En_Anubice_Fire/z_en_anubice_fire.h
@@ -2,11 +2,11 @@
#define Z_EN_ANUBICE_FIRE_H
#include "ultra64.h"
-#include "global.h"
+#include "z64actor.h"
struct EnAnubiceFire;
-typedef void (*EnAnubiceFireActionFunc)(struct EnAnubiceFire*, PlayState*);
+typedef void (*EnAnubiceFireActionFunc)(struct EnAnubiceFire*, struct PlayState*);
typedef struct EnAnubiceFire {
/* 0x0000 */ Actor actor;
@@ -18,7 +18,7 @@ typedef struct EnAnubiceFire {
/* 0x015C */ s16 unk_15C;
/* 0x015E */ s16 unk_15E;
/* 0x0178 */ Vec3f unk_160[6];
- /* 0x01A8 */ ColliderCylinder cylinder;
+ /* 0x01A8 */ ColliderCylinder colliderCylinder;
} EnAnubiceFire; // size = 0x01F4
#endif
diff --git a/src/overlays/actors/ovl_En_Arow_Trap/z_en_arow_trap.c b/src/overlays/actors/ovl_En_Arow_Trap/z_en_arow_trap.c
index d44d38043..d4de5191e 100644
--- a/src/overlays/actors/ovl_En_Arow_Trap/z_en_arow_trap.c
+++ b/src/overlays/actors/ovl_En_Arow_Trap/z_en_arow_trap.c
@@ -6,6 +6,9 @@
#include "z_en_arow_trap.h"
#include "overlays/actors/ovl_En_Arrow/z_en_arrow.h"
+
+#include "z64play.h"
+
#define FLAGS ACTOR_FLAG_UPDATE_CULLING_DISABLED
void EnArowTrap_Init(Actor* thisx, PlayState* play);
diff --git a/src/overlays/actors/ovl_En_Arow_Trap/z_en_arow_trap.h b/src/overlays/actors/ovl_En_Arow_Trap/z_en_arow_trap.h
index e29f84d2b..ba9150508 100644
--- a/src/overlays/actors/ovl_En_Arow_Trap/z_en_arow_trap.h
+++ b/src/overlays/actors/ovl_En_Arow_Trap/z_en_arow_trap.h
@@ -2,8 +2,7 @@
#define Z_EN_AROW_TRAP_H
#include "ultra64.h"
-#include "global.h"
-#include "z64.h"
+#include "z64actor.h"
struct EnArowTrap;
diff --git a/src/overlays/actors/ovl_En_Arrow/z_en_arrow.c b/src/overlays/actors/ovl_En_Arrow/z_en_arrow.c
index 669e5ed1f..9000417a2 100644
--- a/src/overlays/actors/ovl_En_Arrow/z_en_arrow.c
+++ b/src/overlays/actors/ovl_En_Arrow/z_en_arrow.c
@@ -5,7 +5,21 @@
*/
#include "z_en_arrow.h"
-#include "global.h"
+
+#include "libc64/qrand.h"
+#include "libu64/debug.h"
+#include "gfx.h"
+#include "gfx_setupdl.h"
+#include "ichain.h"
+#include "regs.h"
+#include "sfx.h"
+#include "sys_math.h"
+#include "sys_math3d.h"
+#include "sys_matrix.h"
+#include "z_lib.h"
+#include "z64effect.h"
+#include "z64play.h"
+
#include "assets/objects/gameplay_keep/gameplay_keep.h"
#define FLAGS (ACTOR_FLAG_UPDATE_CULLING_DISABLED | ACTOR_FLAG_DRAW_CULLING_DISABLED)
diff --git a/src/overlays/actors/ovl_En_Attack_Niw/z_en_attack_niw.c b/src/overlays/actors/ovl_En_Attack_Niw/z_en_attack_niw.c
index f20feeefe..4a3a32663 100644
--- a/src/overlays/actors/ovl_En_Attack_Niw/z_en_attack_niw.c
+++ b/src/overlays/actors/ovl_En_Attack_Niw/z_en_attack_niw.c
@@ -19,8 +19,6 @@
#include "z64play.h"
#include "z64player.h"
-#include "z64.h"
-
#include "assets/objects/object_niw/object_niw.h"
#define FLAGS ACTOR_FLAG_UPDATE_CULLING_DISABLED
diff --git a/src/overlays/actors/ovl_En_Ba/z_en_ba.c b/src/overlays/actors/ovl_En_Ba/z_en_ba.c
index 829fe5b34..a149d3c63 100644
--- a/src/overlays/actors/ovl_En_Ba/z_en_ba.c
+++ b/src/overlays/actors/ovl_En_Ba/z_en_ba.c
@@ -5,6 +5,20 @@
*/
#include "z_en_ba.h"
+
+#include "gfx.h"
+#include "gfx_setupdl.h"
+#include "ichain.h"
+#include "rand.h"
+#include "segmented_address.h"
+#include "sfx.h"
+#include "sys_math.h"
+#include "sys_matrix.h"
+#include "z_lib.h"
+#include "z64effect.h"
+#include "z64play.h"
+#include "z64player.h"
+
#include "assets/objects/object_bxa/object_bxa.h"
#define FLAGS (ACTOR_FLAG_ATTENTION_ENABLED | ACTOR_FLAG_HOSTILE | ACTOR_FLAG_UPDATE_CULLING_DISABLED)
@@ -37,7 +51,7 @@ ActorProfile En_Ba_Profile = {
static Vec3f D_809B8080 = { 0.0f, 0.0f, 32.0f };
-static ColliderJntSphElementInit sJntSphElementInit[2] = {
+static ColliderJntSphElementInit sJntSphElementsInit[2] = {
{
{
ELEM_MATERIAL_UNK0,
@@ -72,7 +86,7 @@ static ColliderJntSphInit sJntSphInit = {
COLSHAPE_JNTSPH,
},
2,
- sJntSphElementInit,
+ sJntSphElementsInit,
};
void EnBa_SetupAction(EnBa* this, EnBaActionFunc actionFunc) {
diff --git a/src/overlays/actors/ovl_En_Ba/z_en_ba.h b/src/overlays/actors/ovl_En_Ba/z_en_ba.h
index 35f383726..dc3b8cb3f 100644
--- a/src/overlays/actors/ovl_En_Ba/z_en_ba.h
+++ b/src/overlays/actors/ovl_En_Ba/z_en_ba.h
@@ -2,11 +2,11 @@
#define Z_EN_BA_H
#include "ultra64.h"
-#include "global.h"
+#include "z64actor.h"
struct EnBa;
-typedef void (*EnBaActionFunc)(struct EnBa*, PlayState*);
+typedef void (*EnBaActionFunc)(struct EnBa*, struct PlayState*);
typedef enum EnBaType {
/* 0x00 */ EN_BA_TENTACLE_RED,
diff --git a/src/overlays/actors/ovl_En_Bb/z_en_bb.c b/src/overlays/actors/ovl_En_Bb/z_en_bb.c
index 4076b77fd..18dad8151 100644
--- a/src/overlays/actors/ovl_En_Bb/z_en_bb.c
+++ b/src/overlays/actors/ovl_En_Bb/z_en_bb.c
@@ -225,7 +225,7 @@ ActorProfile En_Bb_Profile = {
/**/ EnBb_Draw,
};
-static ColliderJntSphElementInit sJntSphElementInit[1] = {
+static ColliderJntSphElementInit sJntSphElementsInit[1] = {
{
{
ELEM_MATERIAL_UNK0,
@@ -249,7 +249,7 @@ static ColliderJntSphInit sJntSphInit = {
COLSHAPE_JNTSPH,
},
1,
- sJntSphElementInit,
+ sJntSphElementsInit,
};
static InitChainEntry sInitChain[] = {
diff --git a/src/overlays/actors/ovl_En_Bdfire/z_en_bdfire.c b/src/overlays/actors/ovl_En_Bdfire/z_en_bdfire.c
index 930eff285..d4811fb7d 100644
--- a/src/overlays/actors/ovl_En_Bdfire/z_en_bdfire.c
+++ b/src/overlays/actors/ovl_En_Bdfire/z_en_bdfire.c
@@ -5,6 +5,19 @@
*/
#include "z_en_bdfire.h"
+#include "overlays/actors/ovl_Boss_Dodongo/z_boss_dodongo.h"
+
+#include "libc64/qrand.h"
+#include "gfx.h"
+#include "gfx_setupdl.h"
+#include "segmented_address.h"
+#include "sfx.h"
+#include "sys_matrix.h"
+#include "z_lib.h"
+#include "z64light.h"
+#include "z64play.h"
+#include "z64player.h"
+
#include "assets/objects/object_kingdodongo/object_kingdodongo.h"
#define FLAGS (ACTOR_FLAG_UPDATE_CULLING_DISABLED | ACTOR_FLAG_DRAW_CULLING_DISABLED)
diff --git a/src/overlays/actors/ovl_En_Bdfire/z_en_bdfire.h b/src/overlays/actors/ovl_En_Bdfire/z_en_bdfire.h
index 93b37e3b1..876a790d7 100644
--- a/src/overlays/actors/ovl_En_Bdfire/z_en_bdfire.h
+++ b/src/overlays/actors/ovl_En_Bdfire/z_en_bdfire.h
@@ -2,13 +2,13 @@
#define Z_EN_BDFIRE_H
#include "ultra64.h"
-#include "global.h"
-#include "overlays/actors/ovl_Boss_Dodongo/z_boss_dodongo.h"
+#include "z64actor.h"
+#include "z64light.h"
struct EnBdfire;
-typedef void (*EnBdfireActionFunc)(struct EnBdfire*, PlayState*);
-typedef void (*EnBdfireDrawFunc)(struct EnBdfire*, PlayState*);
+typedef void (*EnBdfireActionFunc)(struct EnBdfire*, struct PlayState*);
+typedef void (*EnBdfireDrawFunc)(struct EnBdfire*, struct PlayState*);
typedef struct EnBdfire {
/* 0x0000 */ Actor actor;
diff --git a/src/overlays/actors/ovl_En_Bigokuta/z_en_bigokuta.c b/src/overlays/actors/ovl_En_Bigokuta/z_en_bigokuta.c
index f25ea1290..a321a43a0 100644
--- a/src/overlays/actors/ovl_En_Bigokuta/z_en_bigokuta.c
+++ b/src/overlays/actors/ovl_En_Bigokuta/z_en_bigokuta.c
@@ -16,8 +16,6 @@
#include "z64play.h"
#include "z64player.h"
-#include "global.h"
-
#include "assets/objects/object_bigokuta/object_bigokuta.h"
#define FLAGS \
@@ -63,7 +61,7 @@ ActorProfile En_Bigokuta_Profile = {
/**/ EnBigokuta_Draw,
};
-static ColliderJntSphElementInit sJntSphElementInit[1] = {
+static ColliderJntSphElementInit sJntSphElementsInit[1] = {
{
{
ELEM_MATERIAL_UNK1,
@@ -86,8 +84,8 @@ static ColliderJntSphInit sJntSphInit = {
OC2_TYPE_1,
COLSHAPE_JNTSPH,
},
- ARRAY_COUNT(sJntSphElementInit),
- sJntSphElementInit,
+ ARRAY_COUNT(sJntSphElementsInit),
+ sJntSphElementsInit,
};
static ColliderCylinderInit sCylinderInit[] = {
@@ -184,13 +182,13 @@ void EnBigokuta_Init(Actor* thisx, PlayState* play) {
this->jointTable, this->morphTable, 20);
Collider_InitJntSph(play, &this->collider);
- Collider_SetJntSph(play, &this->collider, &this->actor, &sJntSphInit, &this->element);
+ Collider_SetJntSph(play, &this->collider, &this->actor, &sJntSphInit, this->colliderElements);
this->collider.elements[0].dim.worldSphere.radius = this->collider.elements[0].dim.modelSphere.radius;
for (i = 0; i < ARRAY_COUNT(sCylinderInit); i++) {
- Collider_InitCylinder(play, &this->cylinder[i]);
- Collider_SetCylinder(play, &this->cylinder[i], &this->actor, &sCylinderInit[i]);
+ Collider_InitCylinder(play, &this->colliderCylinders[i]);
+ Collider_SetCylinder(play, &this->colliderCylinders[i], &this->actor, &sCylinderInit[i]);
}
CollisionCheck_SetInfo(&this->actor.colChkInfo, &sDamageTable, sColChkInfoInit);
@@ -213,8 +211,8 @@ void EnBigokuta_Destroy(Actor* thisx, PlayState* play) {
s32 i;
Collider_DestroyJntSph(play, &this->collider);
- for (i = 0; i < ARRAY_COUNT(this->cylinder); i++) {
- Collider_DestroyCylinder(play, &this->cylinder[i]);
+ for (i = 0; i < ARRAY_COUNT(this->colliderCylinders); i++) {
+ Collider_DestroyCylinder(play, &this->colliderCylinders[i]);
}
}
@@ -326,7 +324,7 @@ void func_809BD3F8(EnBigokuta* this) {
this->unk_198 = 80;
this->unk_19A = this->unk_194 * -0x200;
func_809BCE3C(this);
- this->cylinder[0].base.atFlags |= AT_ON;
+ this->colliderCylinders[0].base.atFlags |= AT_ON;
this->collider.base.acFlags |= AC_ON;
this->actionFunc = func_809BDC08;
}
@@ -344,7 +342,7 @@ void func_809BD4A4(EnBigokuta* this) {
this->actor.world.rot.x = this->actor.shape.rot.y + 0x8000;
this->unk_19A = this->unk_194 * 0x200;
this->collider.base.acFlags &= ~AC_ON;
- this->cylinder[0].base.atFlags |= AT_ON;
+ this->colliderCylinders[0].base.atFlags |= AT_ON;
this->actionFunc = func_809BDFC8;
}
@@ -352,7 +350,7 @@ void func_809BD524(EnBigokuta* this) {
Animation_MorphToPlayOnce(&this->skelAnime, &object_bigokuta_Anim_000D1C, -5.0f);
this->unk_196 = 80;
this->unk_19A = 0;
- this->cylinder[0].base.atFlags |= AT_ON;
+ this->colliderCylinders[0].base.atFlags |= AT_ON;
Actor_PlaySfx(&this->actor, NA_SE_EN_DAIOCTA_MAHI);
if (this->collider.elements[0].base.acHitElem->atDmgInfo.dmgFlags & DMG_DEKU_NUT) {
this->unk_195 = true;
@@ -369,7 +367,7 @@ void func_809BD5E0(EnBigokuta* this) {
Animation_MorphToPlayOnce(&this->skelAnime, &object_bigokuta_Anim_000444, -5.0f);
this->unk_196 = 24;
this->unk_19A = 0;
- this->cylinder[0].base.atFlags &= ~AT_ON;
+ this->colliderCylinders[0].base.atFlags &= ~AT_ON;
Actor_SetColorFilter(&this->actor, COLORFILTER_COLORFLAG_RED, 255, COLORFILTER_BUFFLAG_OPA, 24);
this->actionFunc = func_809BE180;
}
@@ -405,7 +403,7 @@ void func_809BD768(EnBigokuta* this) {
this->unk_194 = Rand_ZeroOne() < 0.5f ? -1 : 1;
this->unk_19A = 0;
this->actor.flags &= ~ACTOR_FLAG_ATTENTION_ENABLED;
- this->cylinder[0].base.atFlags &= ~AT_ON;
+ this->colliderCylinders[0].base.atFlags &= ~AT_ON;
Actor_PlaySfx(&this->actor, NA_SE_EN_DAIOCTA_SINK);
this->actionFunc = func_809BE4A4;
}
@@ -601,12 +599,12 @@ void func_809BE058(EnBigokuta* this, PlayState* play) {
SkelAnime_Update(&this->skelAnime);
- if ((this->collider.base.ocFlags1 & OC1_HIT) || (this->cylinder[0].base.ocFlags1 & OC1_HIT) ||
- (this->cylinder[1].base.ocFlags1 & OC1_HIT)) {
+ if ((this->collider.base.ocFlags1 & OC1_HIT) || (this->colliderCylinders[0].base.ocFlags1 & OC1_HIT) ||
+ (this->colliderCylinders[1].base.ocFlags1 & OC1_HIT)) {
speedXZ = CLAMP_MIN(player->actor.speed, 1.0f);
if (!(this->collider.base.ocFlags1 & OC1_HIT)) {
- this->cylinder[0].base.ocFlags1 &= ~OC1_HIT;
- this->cylinder[1].base.ocFlags1 &= ~OC1_HIT;
+ this->colliderCylinders[0].base.ocFlags1 &= ~OC1_HIT;
+ this->colliderCylinders[1].base.ocFlags1 &= ~OC1_HIT;
speedXZ *= -1.0f;
}
player->actor.world.pos.x -= speedXZ * Math_SinS(this->actor.shape.rot.y);
@@ -724,12 +722,12 @@ void func_809BE568(EnBigokuta* this) {
this->collider.elements[0].dim.worldSphere.center.y =
this->actor.world.pos.y + this->collider.elements[0].dim.modelSphere.center.y;
- for (i = 0; i < ARRAY_COUNT(this->cylinder); i++) {
- this->cylinder[i].dim.pos.x =
+ for (i = 0; i < ARRAY_COUNT(this->colliderCylinders); i++) {
+ this->colliderCylinders[i].dim.pos.x =
this->actor.world.pos.x + sCylinderInit[i].dim.pos.z * sin + sCylinderInit[i].dim.pos.x * cos;
- this->cylinder[i].dim.pos.z =
+ this->colliderCylinders[i].dim.pos.z =
this->actor.world.pos.z + sCylinderInit[i].dim.pos.z * cos - sCylinderInit[i].dim.pos.x * sin;
- this->cylinder[i].dim.pos.y = this->actor.world.pos.y;
+ this->colliderCylinders[i].dim.pos.y = this->actor.world.pos.y;
}
}
@@ -737,10 +735,10 @@ void func_809BE798(EnBigokuta* this, PlayState* play) {
s16 effectRot;
s16 yawDiff;
- if ((this->cylinder[0].base.atFlags & AT_HIT) || (this->cylinder[1].base.atFlags & AT_HIT) ||
+ if ((this->colliderCylinders[0].base.atFlags & AT_HIT) || (this->colliderCylinders[1].base.atFlags & AT_HIT) ||
(this->collider.base.atFlags & AT_HIT)) {
- this->cylinder[0].base.atFlags &= ~AT_HIT;
- this->cylinder[1].base.atFlags &= ~AT_HIT;
+ this->colliderCylinders[0].base.atFlags &= ~AT_HIT;
+ this->colliderCylinders[1].base.atFlags &= ~AT_HIT;
this->collider.base.atFlags &= ~AT_HIT;
yawDiff = this->actor.yawTowardsPlayer - this->actor.world.rot.y;
if (yawDiff > 0x4000) {
@@ -801,19 +799,19 @@ void EnBigokuta_Update(Actor* thisx, PlayState* play2) {
Camera_RequestSetting(play->cameraPtrs[CAM_ID_MAIN], CAM_SET_BIG_OCTO);
Camera_UnsetStateFlag(play->cameraPtrs[CAM_ID_MAIN], CAM_STATE_CHECK_BG);
- if (this->cylinder[0].base.atFlags & AT_ON) {
+ if (this->colliderCylinders[0].base.atFlags & AT_ON) {
if (this->actionFunc != func_809BE058) {
- for (i = 0; i < ARRAY_COUNT(this->cylinder); i++) {
- CollisionCheck_SetAT(play, &play->colChkCtx, &this->cylinder[i].base);
+ for (i = 0; i < ARRAY_COUNT(this->colliderCylinders); i++) {
+ CollisionCheck_SetAT(play, &play->colChkCtx, &this->colliderCylinders[i].base);
}
this->actor.flags |= ACTOR_FLAG_SFX_FOR_PLAYER_BODY_HIT;
} else {
- for (i = 0; i < ARRAY_COUNT(this->cylinder); i++) {
- CollisionCheck_SetOC(play, &play->colChkCtx, &this->cylinder[i].base);
+ for (i = 0; i < ARRAY_COUNT(this->colliderCylinders); i++) {
+ CollisionCheck_SetOC(play, &play->colChkCtx, &this->colliderCylinders[i].base);
}
}
- for (i = 0; i < ARRAY_COUNT(this->cylinder); i++) {
- CollisionCheck_SetAC(play, &play->colChkCtx, &this->cylinder[i].base);
+ for (i = 0; i < ARRAY_COUNT(this->colliderCylinders); i++) {
+ CollisionCheck_SetAC(play, &play->colChkCtx, &this->colliderCylinders[i].base);
}
if (this->collider.base.acFlags & AC_ON) {
CollisionCheck_SetAC(play, &play->colChkCtx, &this->collider.base);
diff --git a/src/overlays/actors/ovl_En_Bigokuta/z_en_bigokuta.h b/src/overlays/actors/ovl_En_Bigokuta/z_en_bigokuta.h
index 1380afeed..c04da49c8 100644
--- a/src/overlays/actors/ovl_En_Bigokuta/z_en_bigokuta.h
+++ b/src/overlays/actors/ovl_En_Bigokuta/z_en_bigokuta.h
@@ -20,8 +20,8 @@ typedef struct EnBigokuta {
/* 0x019C */ Vec3s jointTable[20];
/* 0x0214 */ Vec3s morphTable[20];
/* 0x028C */ ColliderJntSph collider;
- /* 0x02AC */ ColliderJntSphElement element;
- /* 0x02EC */ ColliderCylinder cylinder[2];
+ /* 0x02AC */ ColliderJntSphElement colliderElements[1];
+ /* 0x02EC */ ColliderCylinder colliderCylinders[2];
} EnBigokuta; // size = 0x0384
#endif
diff --git a/src/overlays/actors/ovl_En_Bird/z_en_bird.c b/src/overlays/actors/ovl_En_Bird/z_en_bird.c
index 6ca50edee..c93d682ee 100644
--- a/src/overlays/actors/ovl_En_Bird/z_en_bird.c
+++ b/src/overlays/actors/ovl_En_Bird/z_en_bird.c
@@ -5,6 +5,11 @@
*/
#include "z_en_bird.h"
+
+#include "ichain.h"
+#include "z_lib.h"
+#include "z64play.h"
+
#include "assets/objects/object_bird/object_bird.h"
#define FLAGS 0
diff --git a/src/overlays/actors/ovl_En_Bird/z_en_bird.h b/src/overlays/actors/ovl_En_Bird/z_en_bird.h
index 1cc9858b1..beaf60a3d 100644
--- a/src/overlays/actors/ovl_En_Bird/z_en_bird.h
+++ b/src/overlays/actors/ovl_En_Bird/z_en_bird.h
@@ -2,11 +2,11 @@
#define Z_EN_BIRD_H
#include "ultra64.h"
-#include "global.h"
+#include "z64actor.h"
struct EnBird;
-typedef void (*EnBirdActionFunc)(struct EnBird*, PlayState*);
+typedef void (*EnBirdActionFunc)(struct EnBird*, struct PlayState*);
typedef struct EnBird {
/* 0x0000 */ Actor actor;
diff --git a/src/overlays/actors/ovl_En_Blkobj/z_en_blkobj.c b/src/overlays/actors/ovl_En_Blkobj/z_en_blkobj.c
index 2e1141ffe..1d8d606cf 100644
--- a/src/overlays/actors/ovl_En_Blkobj/z_en_blkobj.c
+++ b/src/overlays/actors/ovl_En_Blkobj/z_en_blkobj.c
@@ -5,6 +5,14 @@
*/
#include "z_en_blkobj.h"
+
+#include "gfx.h"
+#include "gfx_setupdl.h"
+#include "ichain.h"
+#include "sys_matrix.h"
+#include "z64play.h"
+#include "z64player.h"
+
#include "assets/objects/object_blkobj/object_blkobj.h"
#define FLAGS (ACTOR_FLAG_UPDATE_CULLING_DISABLED | ACTOR_FLAG_DRAW_CULLING_DISABLED)
diff --git a/src/overlays/actors/ovl_En_Blkobj/z_en_blkobj.h b/src/overlays/actors/ovl_En_Blkobj/z_en_blkobj.h
index 4218c6466..babddb4e5 100644
--- a/src/overlays/actors/ovl_En_Blkobj/z_en_blkobj.h
+++ b/src/overlays/actors/ovl_En_Blkobj/z_en_blkobj.h
@@ -2,11 +2,11 @@
#define Z_EN_BLKOBJ_H
#include "ultra64.h"
-#include "global.h"
+#include "z64actor.h"
struct EnBlkobj;
-typedef void (*EnBlkobjActionFunc)(struct EnBlkobj*, PlayState*);
+typedef void (*EnBlkobjActionFunc)(struct EnBlkobj*, struct PlayState*);
typedef struct EnBlkobj {
/* 0x0000 */ DynaPolyActor dyna;
diff --git a/src/overlays/actors/ovl_En_Bom/z_en_bom.c b/src/overlays/actors/ovl_En_Bom/z_en_bom.c
index 7fefe0324..31acad8ce 100644
--- a/src/overlays/actors/ovl_En_Bom/z_en_bom.c
+++ b/src/overlays/actors/ovl_En_Bom/z_en_bom.c
@@ -112,8 +112,8 @@ void EnBom_Init(Actor* thisx, PlayState* play) {
Collider_InitCylinder(play, &this->bombCollider);
Collider_InitJntSph(play, &this->explosionCollider);
Collider_SetCylinder(play, &this->bombCollider, thisx, &sCylinderInit);
- Collider_SetJntSph(play, &this->explosionCollider, thisx, &sJntSphInit, &this->explosionColliderItems[0]);
- this->explosionColliderItems[0].base.atDmgInfo.damage += (thisx->shape.rot.z & 0xFF00) >> 8;
+ Collider_SetJntSph(play, &this->explosionCollider, thisx, &sJntSphInit, &this->explosionColliderElements[0]);
+ this->explosionColliderElements[0].base.atDmgInfo.damage += (thisx->shape.rot.z & 0xFF00) >> 8;
thisx->shape.rot.z &= 0xFF;
if (thisx->shape.rot.z & 0x80) {
diff --git a/src/overlays/actors/ovl_En_Bom/z_en_bom.h b/src/overlays/actors/ovl_En_Bom/z_en_bom.h
index 9fcb0fe02..88c8feef5 100644
--- a/src/overlays/actors/ovl_En_Bom/z_en_bom.h
+++ b/src/overlays/actors/ovl_En_Bom/z_en_bom.h
@@ -12,7 +12,7 @@ typedef struct EnBom {
/* 0x0000 */ Actor actor;
/* 0x014C */ ColliderCylinder bombCollider;
/* 0x0198 */ ColliderJntSph explosionCollider;
- /* 0x01B8 */ ColliderJntSphElement explosionColliderItems[1];
+ /* 0x01B8 */ ColliderJntSphElement explosionColliderElements[1];
/* 0x01F8 */ s16 timer;
/* 0x01FA */ s16 flashSpeedScale;
/* 0x01FC */ f32 flashIntensity;
diff --git a/src/overlays/actors/ovl_En_Bom_Bowl_Man/z_en_bom_bowl_man.c b/src/overlays/actors/ovl_En_Bom_Bowl_Man/z_en_bom_bowl_man.c
index 2935faa45..8edeca7cf 100644
--- a/src/overlays/actors/ovl_En_Bom_Bowl_Man/z_en_bom_bowl_man.c
+++ b/src/overlays/actors/ovl_En_Bom_Bowl_Man/z_en_bom_bowl_man.c
@@ -12,6 +12,7 @@
#include "z64effect.h"
#include "z64play.h"
#include "z64player.h"
+#include "z64save.h"
#include "assets/objects/object_bg/object_bg.h"
diff --git a/src/overlays/actors/ovl_En_Bom_Bowl_Pit/z_en_bom_bowl_pit.c b/src/overlays/actors/ovl_En_Bom_Bowl_Pit/z_en_bom_bowl_pit.c
index 81442e856..20ea5fb0d 100644
--- a/src/overlays/actors/ovl_En_Bom_Bowl_Pit/z_en_bom_bowl_pit.c
+++ b/src/overlays/actors/ovl_En_Bom_Bowl_Pit/z_en_bom_bowl_pit.c
@@ -7,6 +7,7 @@
#include "z_lib.h"
#include "z64play.h"
#include "z64player.h"
+#include "z64save.h"
#define FLAGS ACTOR_FLAG_UPDATE_CULLING_DISABLED
diff --git a/src/overlays/actors/ovl_En_Bom_Chu/z_en_bom_chu.c b/src/overlays/actors/ovl_En_Bom_Chu/z_en_bom_chu.c
index 8d1df99a4..3af6e87ec 100644
--- a/src/overlays/actors/ovl_En_Bom_Chu/z_en_bom_chu.c
+++ b/src/overlays/actors/ovl_En_Bom_Chu/z_en_bom_chu.c
@@ -41,7 +41,7 @@ ActorProfile En_Bom_Chu_Profile = {
/**/ EnBomChu_Draw,
};
-static ColliderJntSphElementInit sJntSphElemInit[] = {
+static ColliderJntSphElementInit sJntSphElementsInit[] = {
{
{
ELEM_MATERIAL_UNK0,
@@ -64,8 +64,8 @@ static ColliderJntSphInit sJntSphInit = {
OC2_TYPE_2,
COLSHAPE_JNTSPH,
},
- ARRAY_COUNT(sJntSphElemInit),
- sJntSphElemInit,
+ ARRAY_COUNT(sJntSphElementsInit),
+ sJntSphElementsInit,
};
static InitChainEntry sInitChain[] = {
diff --git a/src/overlays/actors/ovl_En_Bombf/z_en_bombf.c b/src/overlays/actors/ovl_En_Bombf/z_en_bombf.c
index 7148ebe49..ed1d7eed7 100644
--- a/src/overlays/actors/ovl_En_Bombf/z_en_bombf.c
+++ b/src/overlays/actors/ovl_En_Bombf/z_en_bombf.c
@@ -107,7 +107,7 @@ void EnBombf_Init(Actor* thisx, PlayState* play) {
Collider_InitCylinder(play, &this->bombCollider);
Collider_InitJntSph(play, &this->explosionCollider);
Collider_SetCylinder(play, &this->bombCollider, thisx, &sCylinderInit);
- Collider_SetJntSph(play, &this->explosionCollider, thisx, &sJntSphInit, &this->explosionColliderItems[0]);
+ Collider_SetJntSph(play, &this->explosionCollider, thisx, &sJntSphInit, &this->explosionColliderElements[0]);
if (thisx->params == BOMBFLOWER_BODY) {
shapeUnk10 = 1000.0f;
diff --git a/src/overlays/actors/ovl_En_Bombf/z_en_bombf.h b/src/overlays/actors/ovl_En_Bombf/z_en_bombf.h
index 2c1cd88af..840da79c1 100644
--- a/src/overlays/actors/ovl_En_Bombf/z_en_bombf.h
+++ b/src/overlays/actors/ovl_En_Bombf/z_en_bombf.h
@@ -12,7 +12,7 @@ typedef struct EnBombf {
/* 0x0000 */ Actor actor;
/* 0x014C */ ColliderCylinder bombCollider;
/* 0x0198 */ ColliderJntSph explosionCollider;
- /* 0x01B8 */ ColliderJntSphElement explosionColliderItems[1];
+ /* 0x01B8 */ ColliderJntSphElement explosionColliderElements[1];
/* 0x01F8 */ s16 timer;
/* 0x01FC */ EnBombfActionFunc actionFunc;
/* 0x0200 */ s32 isFuseEnabled; // enables the ability to ignite and tick down to explode
diff --git a/src/overlays/actors/ovl_En_Boom/z_en_boom.c b/src/overlays/actors/ovl_En_Boom/z_en_boom.c
index 982df71a0..b9dcbacb7 100644
--- a/src/overlays/actors/ovl_En_Boom/z_en_boom.c
+++ b/src/overlays/actors/ovl_En_Boom/z_en_boom.c
@@ -5,7 +5,16 @@
*/
#include "z_en_boom.h"
-#include "global.h"
+
+#include "gfx.h"
+#include "gfx_setupdl.h"
+#include "ichain.h"
+#include "sfx.h"
+#include "sys_matrix.h"
+#include "z_lib.h"
+#include "z64effect.h"
+#include "z64play.h"
+
#include "assets/objects/gameplay_keep/gameplay_keep.h"
#define FLAGS (ACTOR_FLAG_UPDATE_CULLING_DISABLED | ACTOR_FLAG_DRAW_CULLING_DISABLED)
diff --git a/src/overlays/actors/ovl_En_Box/z_en_box.c b/src/overlays/actors/ovl_En_Box/z_en_box.c
index 2d7c748b4..ac30a23d5 100644
--- a/src/overlays/actors/ovl_En_Box/z_en_box.c
+++ b/src/overlays/actors/ovl_En_Box/z_en_box.c
@@ -1,6 +1,24 @@
#include "z_en_box.h"
-#include "global.h"
#include "overlays/actors/ovl_Demo_Kankyo/z_demo_kankyo.h"
+
+#include "libc64/qrand.h"
+#include "gfx.h"
+#include "gfx_setupdl.h"
+#include "ichain.h"
+#include "one_point_cutscene.h"
+#include "sequence.h"
+#include "sfx.h"
+#include "sys_math3d.h"
+#include "sys_matrix.h"
+#include "z_lib.h"
+#include "z64audio.h"
+#include "z64curve.h"
+#include "z64effect.h"
+#include "z64ocarina.h"
+#include "z64play.h"
+#include "z64player.h"
+#include "z64save.h"
+
#include "assets/objects/object_box/object_box.h"
#define FLAGS 0
@@ -171,7 +189,9 @@ void EnBox_Init(Actor* thisx, PlayState* play2) {
this->dyna.actor.world.rot.y += 0x8000;
this->dyna.actor.home.rot.z = this->dyna.actor.world.rot.z = this->dyna.actor.shape.rot.z = 0;
- SkelAnime_Init(play, &this->skelanime, &gTreasureChestSkel, anim, this->jointTable, this->morphTable, 5);
+ //! @bug Flex skeleton is used as normal skeleton
+ SkelAnime_Init(play, &this->skelanime, (SkeletonHeader*)&gTreasureChestSkel, anim, this->jointTable,
+ this->morphTable, 5);
Animation_Change(&this->skelanime, anim, 1.5f, animFrameStart, endFrame, ANIMMODE_ONCE, 0.0f);
switch (this->type) {
diff --git a/src/overlays/actors/ovl_En_Brob/z_en_brob.c b/src/overlays/actors/ovl_En_Brob/z_en_brob.c
index 89edf9c5f..436f4740c 100644
--- a/src/overlays/actors/ovl_En_Brob/z_en_brob.c
+++ b/src/overlays/actors/ovl_En_Brob/z_en_brob.c
@@ -5,6 +5,15 @@
*/
#include "z_en_brob.h"
+
+#include "libc64/qrand.h"
+#include "gfx.h"
+#include "gfx_setupdl.h"
+#include "sfx.h"
+#include "sys_matrix.h"
+#include "z64effect.h"
+#include "z64play.h"
+
#include "assets/objects/object_brob/object_brob.h"
#define FLAGS (ACTOR_FLAG_ATTENTION_ENABLED | ACTOR_FLAG_HOSTILE)
diff --git a/src/overlays/actors/ovl_En_Brob/z_en_brob.h b/src/overlays/actors/ovl_En_Brob/z_en_brob.h
index a3dd0c8f8..02516f4e9 100644
--- a/src/overlays/actors/ovl_En_Brob/z_en_brob.h
+++ b/src/overlays/actors/ovl_En_Brob/z_en_brob.h
@@ -2,11 +2,11 @@
#define Z_EN_BROB_H
#include "ultra64.h"
-#include "global.h"
+#include "z64actor.h"
struct EnBrob;
-typedef void (*EnBrobActionFunc)(struct EnBrob* this, PlayState* play);
+typedef void (*EnBrobActionFunc)(struct EnBrob* this, struct PlayState* play);
typedef struct EnBrob {
/* 0x0000 */ DynaPolyActor dyna;
diff --git a/src/overlays/actors/ovl_En_Bubble/z_en_bubble.c b/src/overlays/actors/ovl_En_Bubble/z_en_bubble.c
index dae945bb8..79860d7f7 100644
--- a/src/overlays/actors/ovl_En_Bubble/z_en_bubble.c
+++ b/src/overlays/actors/ovl_En_Bubble/z_en_bubble.c
@@ -107,7 +107,7 @@ void EnBubble_SetDimensions(EnBubble* this, f32 dim) {
}
u32 func_809CBCBC(EnBubble* this) {
- ColliderElement* elem = &this->colliderSphere.elements[0].base;
+ ColliderElement* elem = &this->colliderJntSph.elements[0].base;
elem->atDmgInfo.dmgFlags = DMG_EXPLOSIVE;
elem->atDmgInfo.effect = 0;
@@ -124,7 +124,7 @@ u32 func_809CBCEC(EnBubble* this) {
}
void EnBubble_DamagePlayer(EnBubble* this, PlayState* play) {
- s32 damage = -this->colliderSphere.elements[0].base.atDmgInfo.damage;
+ s32 damage = -this->colliderJntSph.elements[0].base.atDmgInfo.damage;
play->damagePlayer(play, damage);
Actor_SetPlayerKnockbackSmallNoDamage(play, &this->actor, 6.0f, this->actor.yawTowardsPlayer, 6.0f);
@@ -218,8 +218,8 @@ void EnBubble_Fly(EnBubble* this, PlayState* play) {
s32 bgId;
u8 bounceCount;
- if (this->colliderSphere.elements[1].base.acElemFlags & ACELEM_HIT) {
- attackerActor = this->colliderSphere.base.ac;
+ if (this->colliderJntSph.elements[1].base.acElemFlags & ACELEM_HIT) {
+ attackerActor = this->colliderJntSph.base.ac;
this->normalizedAttackerVelocity = attackerActor->velocity;
EnBubble_Vec3fNormalize(&this->normalizedAttackerVelocity);
this->velocityFromAttack.x += (this->normalizedAttackerVelocity.x * 3.0f);
@@ -292,14 +292,14 @@ void EnBubble_Fly(EnBubble* this, PlayState* play) {
}
u32 func_809CC648(EnBubble* this) {
- if (((this->colliderSphere.base.acFlags & AC_HIT) != 0) == false) {
+ if (((this->colliderJntSph.base.acFlags & AC_HIT) != 0) == false) {
return false;
}
- this->colliderSphere.base.acFlags &= ~AC_HIT;
- if (this->colliderSphere.elements[1].base.acElemFlags & ACELEM_HIT) {
- this->unk_1F0.x = this->colliderSphere.base.ac->velocity.x / 10.0f;
- this->unk_1F0.y = this->colliderSphere.base.ac->velocity.y / 10.0f;
- this->unk_1F0.z = this->colliderSphere.base.ac->velocity.z / 10.0f;
+ this->colliderJntSph.base.acFlags &= ~AC_HIT;
+ if (this->colliderJntSph.elements[1].base.acElemFlags & ACELEM_HIT) {
+ this->unk_1F0.x = this->colliderJntSph.base.ac->velocity.x / 10.0f;
+ this->unk_1F0.y = this->colliderJntSph.base.ac->velocity.y / 10.0f;
+ this->unk_1F0.z = this->colliderJntSph.base.ac->velocity.z / 10.0f;
this->graphicRotSpeed = 128.0f;
this->graphicEccentricity = 0.48f;
return false;
@@ -312,8 +312,8 @@ u32 EnBubble_DetectPop(EnBubble* this, PlayState* play) {
if (DECR(this->unk_208) != 0 || this->actionFunc == EnBubble_Pop) {
return false;
}
- if (this->colliderSphere.base.ocFlags2 & OC2_HIT_PLAYER) {
- this->colliderSphere.base.ocFlags2 &= ~OC2_HIT_PLAYER;
+ if (this->colliderJntSph.base.ocFlags2 & OC2_HIT_PLAYER) {
+ this->colliderJntSph.base.ocFlags2 &= ~OC2_HIT_PLAYER;
EnBubble_DamagePlayer(this, play);
this->unk_208 = 8;
return true;
@@ -326,7 +326,7 @@ void func_809CC774(EnBubble* this) {
Vec3f src;
Vec3f dest;
- dim = &this->colliderSphere.elements[0].dim;
+ dim = &this->colliderJntSph.elements[0].dim;
src.x = dim->modelSphere.center.x;
src.y = dim->modelSphere.center.y;
src.z = dim->modelSphere.center.z;
@@ -336,7 +336,7 @@ void func_809CC774(EnBubble* this) {
dim->worldSphere.center.y = dest.y;
dim->worldSphere.center.z = dest.z;
dim->worldSphere.radius = dim->modelSphere.radius * (1.0f + this->expansionWidth);
- this->colliderSphere.elements[1].dim = *dim;
+ this->colliderJntSph.elements[1].dim = *dim;
}
void EnBubble_Init(Actor* thisx, PlayState* play) {
@@ -344,8 +344,8 @@ void EnBubble_Init(Actor* thisx, PlayState* play) {
u32 pad;
ActorShape_Init(&this->actor.shape, 16.0f, ActorShadow_DrawCircle, 0.2f);
- Collider_InitJntSph(play, &this->colliderSphere);
- Collider_SetJntSph(play, &this->colliderSphere, &this->actor, &sJntSphInit, this->colliderSphereItems);
+ Collider_InitJntSph(play, &this->colliderJntSph);
+ Collider_SetJntSph(play, &this->colliderJntSph, &this->actor, &sJntSphInit, this->colliderJntSphElements);
CollisionCheck_SetInfo2(&this->actor.colChkInfo, DamageTable_Get(9), &sColChkInfoInit2);
this->actor.naviEnemyId = NAVI_ENEMY_SHABOM;
this->bounceDirection.x = Rand_ZeroOne();
@@ -362,7 +362,7 @@ void EnBubble_Init(Actor* thisx, PlayState* play) {
void EnBubble_Destroy(Actor* thisx, PlayState* play) {
EnBubble* this = (EnBubble*)thisx;
- Collider_DestroyJntSph(play, &this->colliderSphere);
+ Collider_DestroyJntSph(play, &this->colliderJntSph);
}
void EnBubble_Wait(EnBubble* this, PlayState* play) {
@@ -372,8 +372,8 @@ void EnBubble_Wait(EnBubble* this, PlayState* play) {
} else {
EnBubble_Fly(this, play);
this->actor.shape.yOffset = ((this->expansionHeight + 1.0f) * 16.0f);
- CollisionCheck_SetAC(play, &play->colChkCtx, &this->colliderSphere.base);
- CollisionCheck_SetOC(play, &play->colChkCtx, &this->colliderSphere.base);
+ CollisionCheck_SetAC(play, &play->colChkCtx, &this->colliderJntSph.base);
+ CollisionCheck_SetOC(play, &play->colChkCtx, &this->colliderJntSph.base);
}
}
@@ -401,8 +401,8 @@ void EnBubble_Regrow(EnBubble* this, PlayState* play) {
if (func_809CC020(this)) {
this->actionFunc = EnBubble_Wait;
}
- CollisionCheck_SetAC(play, &play->colChkCtx, &this->colliderSphere.base);
- CollisionCheck_SetOC(play, &play->colChkCtx, &this->colliderSphere.base);
+ CollisionCheck_SetAC(play, &play->colChkCtx, &this->colliderJntSph.base);
+ CollisionCheck_SetOC(play, &play->colChkCtx, &this->colliderJntSph.base);
}
void EnBubble_Update(Actor* thisx, PlayState* play) {
diff --git a/src/overlays/actors/ovl_En_Bubble/z_en_bubble.h b/src/overlays/actors/ovl_En_Bubble/z_en_bubble.h
index 6c7e01d84..9b183ae2b 100644
--- a/src/overlays/actors/ovl_En_Bubble/z_en_bubble.h
+++ b/src/overlays/actors/ovl_En_Bubble/z_en_bubble.h
@@ -11,8 +11,8 @@ typedef void (*EnBubbleActionFunc)(struct EnBubble*, struct PlayState*);
typedef struct EnBubble {
/* 0x0000 */ Actor actor;
/* 0x014C */ EnBubbleActionFunc actionFunc;
- /* 0x0150 */ ColliderJntSph colliderSphere;
- /* 0x0170 */ ColliderJntSphElement colliderSphereItems[2];
+ /* 0x0150 */ ColliderJntSph colliderJntSph;
+ /* 0x0170 */ ColliderJntSphElement colliderJntSphElements[2];
/* 0x01F0 */ Vec3f unk_1F0; // set but never used
/* 0x01FC */ Vec3f unk_1FC; // randomly generated, set but never used
/* 0x0208 */ s16 unk_208; // set to 8 when about to pop
diff --git a/src/overlays/actors/ovl_En_Butte/z_en_butte.c b/src/overlays/actors/ovl_En_Butte/z_en_butte.c
index 3d721c28f..cd9776b98 100644
--- a/src/overlays/actors/ovl_En_Butte/z_en_butte.c
+++ b/src/overlays/actors/ovl_En_Butte/z_en_butte.c
@@ -6,6 +6,19 @@
#include "z_en_butte.h"
#include "overlays/actors/ovl_En_Elf/z_en_elf.h"
+
+#include "libc64/qrand.h"
+#include "gfx.h"
+#include "gfx_setupdl.h"
+#include "ichain.h"
+#include "segmented_address.h"
+#include "sfx.h"
+#include "sys_math3d.h"
+#include "sys_matrix.h"
+#include "z_lib.h"
+#include "z64play.h"
+#include "z64player.h"
+
#include "assets/objects/gameplay_keep/gameplay_keep.h"
#include "assets/objects/gameplay_field_keep/gameplay_field_keep.h"
diff --git a/src/overlays/actors/ovl_En_Butte/z_en_butte.h b/src/overlays/actors/ovl_En_Butte/z_en_butte.h
index 345a41dc1..1a1764520 100644
--- a/src/overlays/actors/ovl_En_Butte/z_en_butte.h
+++ b/src/overlays/actors/ovl_En_Butte/z_en_butte.h
@@ -2,11 +2,11 @@
#define Z_EN_BUTTE_H
#include "ultra64.h"
-#include "global.h"
+#include "z64actor.h"
struct EnButte;
-typedef void (*EnButteActionFunc)(struct EnButte*, PlayState*);
+typedef void (*EnButteActionFunc)(struct EnButte*, struct PlayState*);
typedef struct EnButte {
/* 0x0000 */ Actor actor;
diff --git a/src/overlays/actors/ovl_En_Bw/z_en_bw.c b/src/overlays/actors/ovl_En_Bw/z_en_bw.c
index 61d7cc36d..0aad9ccca 100644
--- a/src/overlays/actors/ovl_En_Bw/z_en_bw.c
+++ b/src/overlays/actors/ovl_En_Bw/z_en_bw.c
@@ -23,8 +23,6 @@
#include "z64play.h"
#include "z64player.h"
-#include "global.h"
-
#include "assets/objects/gameplay_keep/gameplay_keep.h"
#include "assets/objects/object_bw/object_bw.h"
diff --git a/src/overlays/actors/ovl_En_Bx/z_en_bx.c b/src/overlays/actors/ovl_En_Bx/z_en_bx.c
index efc4d4f5c..51896cbb7 100644
--- a/src/overlays/actors/ovl_En_Bx/z_en_bx.c
+++ b/src/overlays/actors/ovl_En_Bx/z_en_bx.c
@@ -5,6 +5,19 @@
*/
#include "z_en_bx.h"
+
+#include "gfx.h"
+#include "gfx_setupdl.h"
+#include "ichain.h"
+#include "rand.h"
+#include "segmented_address.h"
+#include "sfx.h"
+#include "sys_matrix.h"
+#include "z_lib.h"
+#include "z64effect.h"
+#include "z64play.h"
+#include "z64player.h"
+
#include "assets/objects/object_bxa/object_bxa.h"
#define FLAGS ACTOR_FLAG_UPDATE_CULLING_DISABLED
diff --git a/src/overlays/actors/ovl_En_Bx/z_en_bx.h b/src/overlays/actors/ovl_En_Bx/z_en_bx.h
index 189349a0f..077def413 100644
--- a/src/overlays/actors/ovl_En_Bx/z_en_bx.h
+++ b/src/overlays/actors/ovl_En_Bx/z_en_bx.h
@@ -2,7 +2,7 @@
#define Z_EN_BX_H
#include "ultra64.h"
-#include "global.h"
+#include "z64actor.h"
struct EnBx;
diff --git a/src/overlays/actors/ovl_En_Changer/z_en_changer.c b/src/overlays/actors/ovl_En_Changer/z_en_changer.c
index 32f975850..a4b49f3b5 100644
--- a/src/overlays/actors/ovl_En_Changer/z_en_changer.c
+++ b/src/overlays/actors/ovl_En_Changer/z_en_changer.c
@@ -14,6 +14,7 @@
#include "terminal.h"
#include "z64debug_display.h"
#include "z64play.h"
+#include "z64save.h"
#define FLAGS 0
diff --git a/src/overlays/actors/ovl_En_Clear_Tag/z_en_clear_tag.c b/src/overlays/actors/ovl_En_Clear_Tag/z_en_clear_tag.c
index c6cf2c7ad..619630cf7 100644
--- a/src/overlays/actors/ovl_En_Clear_Tag/z_en_clear_tag.c
+++ b/src/overlays/actors/ovl_En_Clear_Tag/z_en_clear_tag.c
@@ -1,5 +1,17 @@
#include "z_en_clear_tag.h"
+#include "libc64/math64.h"
+#include "libc64/qrand.h"
+#include "attributes.h"
+#include "gfx.h"
+#include "gfx_setupdl.h"
+#include "rand.h"
+#include "sfx.h"
+#include "sys_matrix.h"
+#include "z_lib.h"
+#include "z64play.h"
+#include "z64player.h"
+
#define FLAGS \
(ACTOR_FLAG_ATTENTION_ENABLED | ACTOR_FLAG_HOSTILE | ACTOR_FLAG_UPDATE_CULLING_DISABLED | \
ACTOR_FLAG_DRAW_CULLING_DISABLED)
diff --git a/src/overlays/actors/ovl_En_Clear_Tag/z_en_clear_tag.h b/src/overlays/actors/ovl_En_Clear_Tag/z_en_clear_tag.h
index 945a5462d..697894186 100644
--- a/src/overlays/actors/ovl_En_Clear_Tag/z_en_clear_tag.h
+++ b/src/overlays/actors/ovl_En_Clear_Tag/z_en_clear_tag.h
@@ -2,7 +2,7 @@
#define Z_EN_CLEAR_TAG_H
#include "ultra64.h"
-#include "global.h"
+#include "z64actor.h"
struct EnClearTag;
diff --git a/src/overlays/actors/ovl_En_Cow/z_en_cow.c b/src/overlays/actors/ovl_En_Cow/z_en_cow.c
index 30d16077f..d459c93f6 100644
--- a/src/overlays/actors/ovl_En_Cow/z_en_cow.c
+++ b/src/overlays/actors/ovl_En_Cow/z_en_cow.c
@@ -6,6 +6,18 @@
#include "z_en_cow.h"
+#include "gfx.h"
+#include "gfx_setupdl.h"
+#include "rand.h"
+#include "regs.h"
+#include "sfx.h"
+#include "sys_matrix.h"
+#include "z_lib.h"
+#include "z64ocarina.h"
+#include "z64play.h"
+#include "z64player.h"
+#include "z64save.h"
+
#define FLAGS (ACTOR_FLAG_ATTENTION_ENABLED | ACTOR_FLAG_FRIENDLY)
void EnCow_Init(Actor* thisx, PlayState* play);
diff --git a/src/overlays/actors/ovl_En_Cow/z_en_cow.h b/src/overlays/actors/ovl_En_Cow/z_en_cow.h
index cdec79fca..e5602967e 100644
--- a/src/overlays/actors/ovl_En_Cow/z_en_cow.h
+++ b/src/overlays/actors/ovl_En_Cow/z_en_cow.h
@@ -2,7 +2,7 @@
#define Z_EN_COW_H
#include "ultra64.h"
-#include "global.h"
+#include "z64actor.h"
#include "assets/objects/object_cow/object_cow.h"
#define COW_FLAG_PLAYER_NEARBY (1 << 1)
@@ -23,7 +23,7 @@ typedef enum CowCollider {
struct EnCow;
-typedef void (*EnCowActionFunc)(struct EnCow*, PlayState*);
+typedef void (*EnCowActionFunc)(struct EnCow*, struct PlayState*);
typedef struct EnCow {
/* 0x0000 */ Actor actor;
diff --git a/src/overlays/actors/ovl_En_Cs/z_en_cs.c b/src/overlays/actors/ovl_En_Cs/z_en_cs.c
index 807abac5e..8b74a6063 100644
--- a/src/overlays/actors/ovl_En_Cs/z_en_cs.c
+++ b/src/overlays/actors/ovl_En_Cs/z_en_cs.c
@@ -1,4 +1,18 @@
#include "z_en_cs.h"
+
+#include "libc64/math64.h"
+#include "libc64/qrand.h"
+#include "gfx.h"
+#include "gfx_setupdl.h"
+#include "segmented_address.h"
+#include "sfx.h"
+#include "sys_matrix.h"
+#include "z_lib.h"
+#include "z64face_reaction.h"
+#include "z64play.h"
+#include "z64player.h"
+#include "z64save.h"
+
#include "assets/objects/object_cs/object_cs.h"
#include "assets/objects/object_link_child/object_link_child.h"
diff --git a/src/overlays/actors/ovl_En_Cs/z_en_cs.h b/src/overlays/actors/ovl_En_Cs/z_en_cs.h
index 843c8ad51..8e1d665f5 100644
--- a/src/overlays/actors/ovl_En_Cs/z_en_cs.h
+++ b/src/overlays/actors/ovl_En_Cs/z_en_cs.h
@@ -2,11 +2,11 @@
#define Z_EN_CS_H
#include "ultra64.h"
-#include "global.h"
+#include "z64actor.h"
struct EnCs;
-typedef void (*EnCsActionFunc)(struct EnCs*, PlayState*);
+typedef void (*EnCsActionFunc)(struct EnCs*, struct PlayState*);
typedef struct EnCs {
/* 0x0000 */ Actor actor;
diff --git a/src/overlays/actors/ovl_En_Daiku/z_en_daiku.c b/src/overlays/actors/ovl_En_Daiku/z_en_daiku.c
index 9cd69ab64..98a09bb25 100644
--- a/src/overlays/actors/ovl_En_Daiku/z_en_daiku.c
+++ b/src/overlays/actors/ovl_En_Daiku/z_en_daiku.c
@@ -1,5 +1,20 @@
#include "z_en_daiku.h"
#include "overlays/actors/ovl_En_GeldB/z_en_geldb.h"
+
+#include "libc64/math64.h"
+#include "libc64/qrand.h"
+#include "gfx.h"
+#include "gfx_setupdl.h"
+#include "segmented_address.h"
+#include "sequence.h"
+#include "sfx.h"
+#include "sys_matrix.h"
+#include "z_lib.h"
+#include "z64audio.h"
+#include "z64play.h"
+#include "z64player.h"
+#include "z64save.h"
+
#include "assets/objects/object_daiku/object_daiku.h"
#define FLAGS (ACTOR_FLAG_ATTENTION_ENABLED | ACTOR_FLAG_FRIENDLY | ACTOR_FLAG_UPDATE_CULLING_DISABLED)
diff --git a/src/overlays/actors/ovl_En_Daiku/z_en_daiku.h b/src/overlays/actors/ovl_En_Daiku/z_en_daiku.h
index 69136f6a9..b191c1d79 100644
--- a/src/overlays/actors/ovl_En_Daiku/z_en_daiku.h
+++ b/src/overlays/actors/ovl_En_Daiku/z_en_daiku.h
@@ -2,11 +2,11 @@
#define Z_EN_DAIKU_H
#include "ultra64.h"
-#include "global.h"
+#include "z64actor.h"
struct EnDaiku;
-typedef void (*EnDaikuActionFunc)(struct EnDaiku*, PlayState*);
+typedef void (*EnDaikuActionFunc)(struct EnDaiku*, struct PlayState*);
typedef enum EnDaikuType {
ENDAIKU_TYPE0,
diff --git a/src/overlays/actors/ovl_En_Daiku_Kakariko/z_en_daiku_kakariko.c b/src/overlays/actors/ovl_En_Daiku_Kakariko/z_en_daiku_kakariko.c
index 982de2b69..c5eb8ff56 100644
--- a/src/overlays/actors/ovl_En_Daiku_Kakariko/z_en_daiku_kakariko.c
+++ b/src/overlays/actors/ovl_En_Daiku_Kakariko/z_en_daiku_kakariko.c
@@ -5,6 +5,20 @@
*/
#include "z_en_daiku_kakariko.h"
+
+#include "libc64/math64.h"
+#include "libc64/qrand.h"
+#include "gfx.h"
+#include "gfx_setupdl.h"
+#include "segmented_address.h"
+#include "sfx.h"
+#include "sys_matrix.h"
+#include "z_lib.h"
+#include "z64face_reaction.h"
+#include "z64play.h"
+#include "z64player.h"
+#include "z64save.h"
+
#include "assets/objects/object_daiku/object_daiku.h"
#define FLAGS (ACTOR_FLAG_ATTENTION_ENABLED | ACTOR_FLAG_FRIENDLY | ACTOR_FLAG_UPDATE_CULLING_DISABLED)
diff --git a/src/overlays/actors/ovl_En_Daiku_Kakariko/z_en_daiku_kakariko.h b/src/overlays/actors/ovl_En_Daiku_Kakariko/z_en_daiku_kakariko.h
index 5d3596d58..1395b6e25 100644
--- a/src/overlays/actors/ovl_En_Daiku_Kakariko/z_en_daiku_kakariko.h
+++ b/src/overlays/actors/ovl_En_Daiku_Kakariko/z_en_daiku_kakariko.h
@@ -2,11 +2,11 @@
#define Z_EN_DAIKU_KAKARIKO_H
#include "ultra64.h"
-#include "global.h"
+#include "z64actor.h"
struct EnDaikuKakariko;
-typedef void (*EnDaikuKakarikoActionFunc)(struct EnDaikuKakariko*, PlayState*);
+typedef void (*EnDaikuKakarikoActionFunc)(struct EnDaikuKakariko*, struct PlayState*);
typedef struct EnDaikuKakariko {
/* 0x0000 */ Actor actor;
diff --git a/src/overlays/actors/ovl_En_Dekubaba/z_en_dekubaba.c b/src/overlays/actors/ovl_En_Dekubaba/z_en_dekubaba.c
index 46a15d4d2..ab7b8e428 100644
--- a/src/overlays/actors/ovl_En_Dekubaba/z_en_dekubaba.c
+++ b/src/overlays/actors/ovl_En_Dekubaba/z_en_dekubaba.c
@@ -11,6 +11,7 @@
#include "z64effect.h"
#include "z64play.h"
#include "z64player.h"
+#include "z64save.h"
#include "assets/objects/gameplay_keep/gameplay_keep.h"
#include "assets/objects/object_dekubaba/object_dekubaba.h"
diff --git a/src/overlays/actors/ovl_En_Dh/z_en_dh.c b/src/overlays/actors/ovl_En_Dh/z_en_dh.c
index a97808faa..34acb2d98 100644
--- a/src/overlays/actors/ovl_En_Dh/z_en_dh.c
+++ b/src/overlays/actors/ovl_En_Dh/z_en_dh.c
@@ -22,8 +22,7 @@
#include "z64effect.h"
#include "z64play.h"
#include "z64player.h"
-
-#include "global.h"
+#include "z64save.h"
#include "assets/objects/object_dh/object_dh.h"
@@ -179,8 +178,8 @@ void EnDh_Init(Actor* thisx, PlayState* play) {
this->actor.flags &= ~ACTOR_FLAG_ATTENTION_ENABLED;
Collider_InitCylinder(play, &this->collider1);
Collider_SetCylinder(play, &this->collider1, &this->actor, &sCylinderInit);
- Collider_InitJntSph(play, &this->collider2);
- Collider_SetJntSph(play, &this->collider2, &this->actor, &sJntSphInit, this->elements);
+ Collider_InitJntSph(play, &this->colliderJntSph);
+ Collider_SetJntSph(play, &this->colliderJntSph, &this->actor, &sJntSphInit, this->colliderJntSphElements);
EnDh_SetupWait(this);
}
@@ -190,7 +189,7 @@ void EnDh_Destroy(Actor* thisx, PlayState* play) {
func_800F5B58();
Collider_DestroyCylinder(play, &this->collider1);
- Collider_DestroyJntSph(play, &this->collider2);
+ Collider_DestroyJntSph(play, &this->colliderJntSph);
}
void EnDh_SpawnDebris(PlayState* play, EnDh* this, Vec3f* spawnPos, f32 spread, s32 arg4, f32 accelXZ, f32 scale) {
@@ -330,8 +329,10 @@ void EnDh_Attack(EnDh* this, PlayState* play) {
Animation_Change(&this->skelAnime, &object_dh_Anim_004658, -1.0f, this->skelAnime.curFrame, 0.0f, ANIMMODE_ONCE,
-4.0f);
this->actionState = 4;
- this->collider2.base.atFlags = this->collider2.elements[0].base.atElemFlags = AT_NONE; // also ATELEM_NONE
- this->collider2.elements[0].base.atDmgInfo.dmgFlags = this->collider2.elements[0].base.atDmgInfo.damage = 0;
+ this->colliderJntSph.base.atFlags = this->colliderJntSph.elements[0].base.atElemFlags =
+ AT_NONE; // also ATELEM_NONE
+ this->colliderJntSph.elements[0].base.atDmgInfo.dmgFlags =
+ this->colliderJntSph.elements[0].base.atDmgInfo.damage = 0;
}
switch (this->actionState) {
case 1:
@@ -344,20 +345,20 @@ void EnDh_Attack(EnDh* this, PlayState* play) {
break;
case 2:
if (this->skelAnime.curFrame >= 4.0f) {
- this->collider2.base.atFlags = this->collider2.elements[0].base.atElemFlags =
+ this->colliderJntSph.base.atFlags = this->colliderJntSph.elements[0].base.atElemFlags =
AT_ON | AT_TYPE_ENEMY; // also ATELEM_ON | ATELEM_SFX_WOOD
- this->collider2.elements[0].base.atDmgInfo.dmgFlags = DMG_DEFAULT;
- this->collider2.elements[0].base.atDmgInfo.damage = 8;
+ this->colliderJntSph.elements[0].base.atDmgInfo.dmgFlags = DMG_DEFAULT;
+ this->colliderJntSph.elements[0].base.atDmgInfo.damage = 8;
}
- if (this->collider2.base.atFlags & AT_BOUNCED) {
- this->collider2.base.atFlags &= ~(AT_HIT | AT_BOUNCED);
- this->collider2.base.atFlags = this->collider2.elements[0].base.atElemFlags =
+ if (this->colliderJntSph.base.atFlags & AT_BOUNCED) {
+ this->colliderJntSph.base.atFlags &= ~(AT_HIT | AT_BOUNCED);
+ this->colliderJntSph.base.atFlags = this->colliderJntSph.elements[0].base.atElemFlags =
AT_NONE; // also ATELEM_NONE
- this->collider2.elements[0].base.atDmgInfo.dmgFlags =
- this->collider2.elements[0].base.atDmgInfo.damage = 0;
+ this->colliderJntSph.elements[0].base.atDmgInfo.dmgFlags =
+ this->colliderJntSph.elements[0].base.atDmgInfo.damage = 0;
this->actionState++;
- } else if (this->collider2.base.atFlags & AT_HIT) {
- this->collider2.base.atFlags &= ~AT_HIT;
+ } else if (this->colliderJntSph.base.atFlags & AT_HIT) {
+ this->colliderJntSph.base.atFlags &= ~AT_HIT;
Actor_SetPlayerKnockbackLargeNoDamage(play, &this->actor, 8.0f, this->actor.shape.rot.y, 8.0f);
}
break;
@@ -372,10 +373,10 @@ void EnDh_Attack(EnDh* this, PlayState* play) {
Animation_Change(&this->skelAnime, &object_dh_Anim_004658, -1.0f,
Animation_GetLastFrame(&object_dh_Anim_004658), 0.0f, ANIMMODE_ONCE, -4.0f);
this->actionState++;
- this->collider2.base.atFlags = this->collider2.elements[0].base.atElemFlags =
+ this->colliderJntSph.base.atFlags = this->colliderJntSph.elements[0].base.atElemFlags =
AT_NONE; // also ATELEM_NONE
- this->collider2.elements[0].base.atDmgInfo.dmgFlags =
- this->collider2.elements[0].base.atDmgInfo.damage = 0;
+ this->colliderJntSph.elements[0].base.atDmgInfo.dmgFlags =
+ this->colliderJntSph.elements[0].base.atDmgInfo.damage = 0;
}
break;
case 5:
@@ -504,11 +505,13 @@ void EnDh_CollisionCheck(EnDh* this, PlayState* play) {
Player* player = GET_PLAYER(play);
s32 lastHealth;
- if ((this->collider2.base.acFlags & AC_HIT) && !this->retreat) {
- this->collider2.base.acFlags &= ~AC_HIT;
+ if ((this->colliderJntSph.base.acFlags & AC_HIT) && !this->retreat) {
+ this->colliderJntSph.base.acFlags &= ~AC_HIT;
if ((this->actor.colChkInfo.damageEffect != 0) && (this->actor.colChkInfo.damageEffect != 6)) {
- this->collider2.base.atFlags = this->collider2.elements[0].base.atElemFlags = AT_NONE; // also ATELEM_NONE
- this->collider2.elements[0].base.atDmgInfo.dmgFlags = this->collider2.elements[0].base.atDmgInfo.damage = 0;
+ this->colliderJntSph.base.atFlags = this->colliderJntSph.elements[0].base.atElemFlags =
+ AT_NONE; // also ATELEM_NONE
+ this->colliderJntSph.elements[0].base.atDmgInfo.dmgFlags =
+ this->colliderJntSph.elements[0].base.atDmgInfo.damage = 0;
if (player->unk_844 != 0) {
this->unk_258 = player->unk_845;
}
@@ -553,13 +556,13 @@ void EnDh_Update(Actor* thisx, PlayState* play) {
if (((this->curAction != DH_DAMAGE) && (this->actor.shape.yOffset == 0.0f)) ||
((player->unk_844 != 0) && (player->unk_845 != this->unk_258))) {
- CollisionCheck_SetAC(play, &play->colChkCtx, &this->collider2.base);
- CollisionCheck_SetAT(play, &play->colChkCtx, &this->collider2.base);
+ CollisionCheck_SetAC(play, &play->colChkCtx, &this->colliderJntSph.base);
+ CollisionCheck_SetAT(play, &play->colChkCtx, &this->colliderJntSph.base);
CollisionCheck_SetAT(play, &play->colChkCtx, &this->collider1.base);
}
} else {
CollisionCheck_SetOC(play, &play->colChkCtx, &this->collider1.base);
- CollisionCheck_SetOC(play, &play->colChkCtx, &this->collider2.base);
+ CollisionCheck_SetOC(play, &play->colChkCtx, &this->colliderJntSph.base);
}
}
@@ -571,7 +574,7 @@ void EnDh_PostLimbDraw(PlayState* play, s32 limbIndex, Gfx** dList, Vec3s* rot,
Matrix_MultVec3f(&headOffset, &this->headPos);
Matrix_Push();
Matrix_Translate(headOffset.x, headOffset.y, headOffset.z, MTXMODE_APPLY);
- Collider_UpdateSpheres(1, &this->collider2);
+ Collider_UpdateSpheres(1, &this->colliderJntSph);
Matrix_Pop();
}
}
diff --git a/src/overlays/actors/ovl_En_Dh/z_en_dh.h b/src/overlays/actors/ovl_En_Dh/z_en_dh.h
index a7b356e9f..0feb3069b 100644
--- a/src/overlays/actors/ovl_En_Dh/z_en_dh.h
+++ b/src/overlays/actors/ovl_En_Dh/z_en_dh.h
@@ -24,8 +24,8 @@ typedef struct EnDh {
/* 0x025C */ s16 timer;
/* 0x025E */ s16 dirtWavePhase;
/* 0x0260 */ ColliderCylinder collider1;
- /* 0x02AC */ ColliderJntSph collider2;
- /* 0x02CC */ ColliderJntSphElement elements[1];
+ /* 0x02AC */ ColliderJntSph colliderJntSph;
+ /* 0x02CC */ ColliderJntSphElement colliderJntSphElements[1];
/* 0x030C */ Vec3f headPos;
/* 0x0318 */ f32 dirtWaveSpread;
/* 0x031C */ f32 dirtWaveHeight;
diff --git a/src/overlays/actors/ovl_En_Dha/z_en_dha.c b/src/overlays/actors/ovl_En_Dha/z_en_dha.c
index 599c17569..5754d8ae1 100644
--- a/src/overlays/actors/ovl_En_Dha/z_en_dha.c
+++ b/src/overlays/actors/ovl_En_Dha/z_en_dha.c
@@ -18,6 +18,7 @@
#include "z_lib.h"
#include "z64play.h"
#include "z64player.h"
+#include "z64save.h"
#include "assets/objects/object_dh/object_dh.h"
diff --git a/src/overlays/actors/ovl_En_Diving_Game/z_en_diving_game.c b/src/overlays/actors/ovl_En_Diving_Game/z_en_diving_game.c
index 98ae6c9af..6de666602 100644
--- a/src/overlays/actors/ovl_En_Diving_Game/z_en_diving_game.c
+++ b/src/overlays/actors/ovl_En_Diving_Game/z_en_diving_game.c
@@ -19,10 +19,10 @@
#include "z_lib.h"
#include "z64audio.h"
#include "z64effect.h"
+#include "z64face_reaction.h"
#include "z64play.h"
#include "z64player.h"
-
-#include "global.h"
+#include "z64save.h"
#include "assets/objects/object_zo/object_zo.h"
diff --git a/src/overlays/actors/ovl_En_Dns/z_en_dns.c b/src/overlays/actors/ovl_En_Dns/z_en_dns.c
index f6c459897..cc823ecdc 100644
--- a/src/overlays/actors/ovl_En_Dns/z_en_dns.c
+++ b/src/overlays/actors/ovl_En_Dns/z_en_dns.c
@@ -16,6 +16,7 @@
#include "z64effect.h"
#include "z64play.h"
#include "z64player.h"
+#include "z64save.h"
#include "assets/objects/object_shopnuts/object_shopnuts.h"
diff --git a/src/overlays/actors/ovl_En_Dnt_Demo/z_en_dnt_demo.c b/src/overlays/actors/ovl_En_Dnt_Demo/z_en_dnt_demo.c
index e3d2426e0..539daf8ba 100644
--- a/src/overlays/actors/ovl_En_Dnt_Demo/z_en_dnt_demo.c
+++ b/src/overlays/actors/ovl_En_Dnt_Demo/z_en_dnt_demo.c
@@ -21,6 +21,7 @@
#include "z64debug_display.h"
#include "z64play.h"
#include "z64player.h"
+#include "z64save.h"
#define FLAGS 0
diff --git a/src/overlays/actors/ovl_En_Dnt_Jiji/z_en_dnt_jiji.c b/src/overlays/actors/ovl_En_Dnt_Jiji/z_en_dnt_jiji.c
index afe3b8485..376a90c36 100644
--- a/src/overlays/actors/ovl_En_Dnt_Jiji/z_en_dnt_jiji.c
+++ b/src/overlays/actors/ovl_En_Dnt_Jiji/z_en_dnt_jiji.c
@@ -24,6 +24,7 @@
#include "z64effect.h"
#include "z64play.h"
#include "z64player.h"
+#include "z64save.h"
#include "assets/objects/object_dns/object_dns.h"
diff --git a/src/overlays/actors/ovl_En_Dnt_Nomal/z_en_dnt_nomal.c b/src/overlays/actors/ovl_En_Dnt_Nomal/z_en_dnt_nomal.c
index 6228b1c2f..bcf097843 100644
--- a/src/overlays/actors/ovl_En_Dnt_Nomal/z_en_dnt_nomal.c
+++ b/src/overlays/actors/ovl_En_Dnt_Nomal/z_en_dnt_nomal.c
@@ -25,6 +25,7 @@
#include "z64effect.h"
#include "z64play.h"
#include "z64player.h"
+#include "z64save.h"
#include "assets/objects/object_dnk/object_dnk.h"
#include "assets/objects/object_hintnuts/object_hintnuts.h"
@@ -149,16 +150,16 @@ void EnDntNomal_Init(Actor* thisx, PlayState* play) {
PRINTF("\n\n");
// "Deku Scrub target"
PRINTF(VT_FGCOL(GREEN) "☆☆☆☆☆ デグナッツ的当て ☆☆☆☆☆ \n" VT_RST);
- Collider_InitQuad(play, &this->targetQuad);
- Collider_SetQuad(play, &this->targetQuad, &this->actor, &sTargetQuadInit);
+ Collider_InitQuad(play, &this->targetColliderQuad);
+ Collider_SetQuad(play, &this->targetColliderQuad, &this->actor, &sTargetQuadInit);
this->actor.world.rot.y = this->actor.shape.rot.y = this->actor.yawTowardsPlayer;
this->objectId = OBJECT_HINTNUTS;
} else {
PRINTF("\n\n");
// "Deku Scrub mask show audience"
PRINTF(VT_FGCOL(GREEN) "☆☆☆☆☆ デグナッツお面品評会一般人 ☆☆☆☆☆ \n" VT_RST);
- Collider_InitCylinder(play, &this->bodyCyl);
- Collider_SetCylinder(play, &this->bodyCyl, &this->actor, &sBodyCylinderInit);
+ Collider_InitCylinder(play, &this->bodyColliderCylinder);
+ Collider_SetCylinder(play, &this->bodyColliderCylinder, &this->actor, &sBodyCylinderInit);
this->objectId = OBJECT_DNK;
}
if (this->objectId >= 0) {
@@ -182,9 +183,9 @@ void EnDntNomal_Destroy(Actor* thisx, PlayState* play) {
EnDntNomal* this = (EnDntNomal*)thisx;
if (this->type == ENDNTNOMAL_TARGET) {
- Collider_DestroyQuad(play, &this->targetQuad);
+ Collider_DestroyQuad(play, &this->targetColliderQuad);
} else {
- Collider_DestroyCylinder(play, &this->bodyCyl);
+ Collider_DestroyCylinder(play, &this->bodyColliderCylinder);
}
}
@@ -196,8 +197,9 @@ void EnDntNomal_WaitForObject(EnDntNomal* this, PlayState* play) {
this->actor.gravity = -2.0f;
Actor_SetScale(&this->actor, 0.01f);
if (this->type == ENDNTNOMAL_TARGET) {
- SkelAnime_Init(play, &this->skelAnime, &gHintNutsSkel, &gHintNutsBurrowAnim, this->jointTable,
- this->morphTable, 10);
+ //! @bug Flex skeleton is used as normal skeleton
+ SkelAnime_Init(play, &this->skelAnime, (SkeletonHeader*)&gHintNutsSkel, &gHintNutsBurrowAnim,
+ this->jointTable, this->morphTable, 10);
this->actor.draw = EnDntNomal_DrawTargetScrub;
} else {
SkelAnime_Init(play, &this->skelAnime, &gDntStageSkel, &gDntStageHideAnim, this->jointTable,
@@ -256,16 +258,16 @@ void EnDntNomal_TargetWait(EnDntNomal* this, PlayState* play) {
SkelAnime_Update(&this->skelAnime);
#if OOT_VERSION < PAL_1_0
- if (this->targetQuad.base.acFlags & AC_HIT)
+ if (this->targetColliderQuad.base.acFlags & AC_HIT)
#else
- if ((this->targetQuad.base.acFlags & AC_HIT) || BREG(0))
+ if ((this->targetColliderQuad.base.acFlags & AC_HIT) || BREG(0))
#endif
{
- this->targetQuad.base.acFlags &= ~AC_HIT;
+ this->targetColliderQuad.base.acFlags &= ~AC_HIT;
- dx = fabsf(targetX - this->targetQuad.elem.acDmgInfo.hitPos.x);
- dy = fabsf(targetY - this->targetQuad.elem.acDmgInfo.hitPos.y);
- dz = fabsf(targetZ - this->targetQuad.elem.acDmgInfo.hitPos.z);
+ dx = fabsf(targetX - this->targetColliderQuad.elem.acDmgInfo.hitPos.x);
+ dy = fabsf(targetY - this->targetColliderQuad.elem.acDmgInfo.hitPos.y);
+ dz = fabsf(targetZ - this->targetColliderQuad.elem.acDmgInfo.hitPos.z);
scoreVel.y = 5.0f;
@@ -854,13 +856,13 @@ void EnDntNomal_Update(Actor* thisx, PlayState* play) {
UPDBGCHECKINFO_FLAG_0 | UPDBGCHECKINFO_FLAG_2 | UPDBGCHECKINFO_FLAG_3 |
UPDBGCHECKINFO_FLAG_4);
if (this->type == ENDNTNOMAL_TARGET) {
- Collider_SetQuadVertices(&this->targetQuad, &this->targetVtx[0], &this->targetVtx[1], &this->targetVtx[2],
- &this->targetVtx[3]);
- CollisionCheck_SetAC(play, &play->colChkCtx, &this->targetQuad.base);
+ Collider_SetQuadVertices(&this->targetColliderQuad, &this->targetVtx[0], &this->targetVtx[1],
+ &this->targetVtx[2], &this->targetVtx[3]);
+ CollisionCheck_SetAC(play, &play->colChkCtx, &this->targetColliderQuad.base);
} else {
- Collider_UpdateCylinder(&this->actor, &this->bodyCyl);
+ Collider_UpdateCylinder(&this->actor, &this->bodyColliderCylinder);
if (this->isSolid) {
- CollisionCheck_SetOC(play, &play->colChkCtx, &this->bodyCyl.base);
+ CollisionCheck_SetOC(play, &play->colChkCtx, &this->bodyColliderCylinder.base);
}
}
}
diff --git a/src/overlays/actors/ovl_En_Dnt_Nomal/z_en_dnt_nomal.h b/src/overlays/actors/ovl_En_Dnt_Nomal/z_en_dnt_nomal.h
index f0bcab6ed..21f77798a 100644
--- a/src/overlays/actors/ovl_En_Dnt_Nomal/z_en_dnt_nomal.h
+++ b/src/overlays/actors/ovl_En_Dnt_Nomal/z_en_dnt_nomal.h
@@ -38,8 +38,8 @@ typedef struct EnDntNomal {
/* 0x0279 */ s8 requiredObjectSlot;
/* 0x027C */ Vec3f mouthPos;
/* 0x0288 */ Vec3f targetPos;
- /* 0x0294 */ ColliderQuad targetQuad;
- /* 0x0314 */ ColliderCylinder bodyCyl;
+ /* 0x0294 */ ColliderQuad targetColliderQuad;
+ /* 0x0314 */ ColliderCylinder bodyColliderCylinder;
} EnDntNomal; // size = 0x0360
#define ENDNTNOMAL_TARGET 0
diff --git a/src/overlays/actors/ovl_En_Dodongo/z_en_dodongo.c b/src/overlays/actors/ovl_En_Dodongo/z_en_dodongo.c
index c29dd7219..5d013911e 100644
--- a/src/overlays/actors/ovl_En_Dodongo/z_en_dodongo.c
+++ b/src/overlays/actors/ovl_En_Dodongo/z_en_dodongo.c
@@ -337,10 +337,10 @@ void EnDodongo_Init(Actor* thisx, PlayState* play) {
this->actor.colChkInfo.damageTable = &sDamageTable;
Collider_InitQuad(play, &this->colliderAT);
Collider_InitTris(play, &this->colliderHard);
- Collider_InitJntSph(play, &this->colliderBody);
+ Collider_InitJntSph(play, &this->bodyCollider);
Collider_SetQuad(play, &this->colliderAT, &this->actor, &sAttackQuadInit);
Collider_SetTris(play, &this->colliderHard, &this->actor, &sHardTrisInit, this->trisElements);
- Collider_SetJntSph(play, &this->colliderBody, &this->actor, &sBodyJntSphInit, this->sphElements);
+ Collider_SetJntSph(play, &this->bodyCollider, &this->actor, &sBodyJntSphInit, this->bodyColliderElements);
blureInit.p1StartColor[0] = blureInit.p1StartColor[1] = blureInit.p1StartColor[2] = blureInit.p1StartColor[3] =
blureInit.p2StartColor[0] = blureInit.p2StartColor[1] = blureInit.p2StartColor[2] = blureInit.p1EndColor[0] =
@@ -366,7 +366,7 @@ void EnDodongo_Destroy(Actor* thisx, PlayState* play) {
Effect_Delete(play, this->blureIdx);
Collider_DestroyTris(play, &this->colliderHard);
- Collider_DestroyJntSph(play, &this->colliderBody);
+ Collider_DestroyJntSph(play, &this->bodyCollider);
Collider_DestroyQuad(play, &this->colliderAT);
}
@@ -505,9 +505,9 @@ void EnDodongo_SwallowBomb(EnDodongo* this, PlayState* play) {
deathFireAccel.x = deathFireVel.x * -0.1f;
deathFireAccel.y = deathFireVel.y * -0.1f;
deathFireAccel.z = deathFireVel.z * -0.1f;
- pos.x = this->sphElements[0].dim.worldSphere.center.x + deathFireVel.x;
- pos.y = this->sphElements[0].dim.worldSphere.center.y + deathFireVel.y;
- pos.z = this->sphElements[0].dim.worldSphere.center.z + deathFireVel.z;
+ pos.x = this->bodyColliderElements[0].dim.worldSphere.center.x + deathFireVel.x;
+ pos.y = this->bodyColliderElements[0].dim.worldSphere.center.y + deathFireVel.y;
+ pos.z = this->bodyColliderElements[0].dim.worldSphere.center.z + deathFireVel.z;
func_8002836C(play, &pos, &deathFireVel, &deathFireAccel, &this->bombSmokePrimColor,
&this->bombSmokeEnvColor, 400, 10, 10);
}
@@ -620,13 +620,13 @@ void EnDodongo_SweepTail(EnDodongo* this, PlayState* play) {
if (SkelAnime_Update(&this->skelAnime)) {
if ((this->timer != 0) || (ABS(yawDiff1) < 0x4000)) {
- this->sphElements[2].base.atElemFlags = ATELEM_NONE;
- this->sphElements[1].base.atElemFlags = ATELEM_NONE;
- this->colliderBody.base.atFlags = AT_NONE;
- this->sphElements[2].base.atDmgInfo.dmgFlags = 0;
- this->sphElements[1].base.atDmgInfo.dmgFlags = 0;
- this->sphElements[2].base.atDmgInfo.damage = 0;
- this->sphElements[1].base.atDmgInfo.damage = 0;
+ this->bodyColliderElements[2].base.atElemFlags = ATELEM_NONE;
+ this->bodyColliderElements[1].base.atElemFlags = ATELEM_NONE;
+ this->bodyCollider.base.atFlags = AT_NONE;
+ this->bodyColliderElements[2].base.atDmgInfo.dmgFlags = 0;
+ this->bodyColliderElements[1].base.atDmgInfo.dmgFlags = 0;
+ this->bodyColliderElements[2].base.atDmgInfo.damage = 0;
+ this->bodyColliderElements[1].base.atDmgInfo.damage = 0;
EnDodongo_SetupBreatheFire(this);
this->timer = Rand_S16Offset(5, 10);
} else {
@@ -643,33 +643,36 @@ void EnDodongo_SweepTail(EnDodongo* this, PlayState* play) {
Actor_PlaySfx(&this->actor, NA_SE_EN_DODO_J_TAIL);
Animation_PlayOnceSetSpeed(&this->skelAnime, animation, 2.0f);
this->timer = 18;
- this->colliderBody.base.atFlags = this->sphElements[1].base.atElemFlags =
- this->sphElements[2].base.atElemFlags = AT_ON | AT_TYPE_ENEMY; // also ATELEM_ON | ATELEM_SFX_WOOD
- this->sphElements[1].base.atDmgInfo.dmgFlags = this->sphElements[2].base.atDmgInfo.dmgFlags = DMG_DEFAULT;
- this->sphElements[1].base.atDmgInfo.damage = this->sphElements[2].base.atDmgInfo.damage = 8;
+ this->bodyCollider.base.atFlags = this->bodyColliderElements[1].base.atElemFlags =
+ this->bodyColliderElements[2].base.atElemFlags =
+ AT_ON | AT_TYPE_ENEMY; // also ATELEM_ON | ATELEM_SFX_WOOD
+ this->bodyColliderElements[1].base.atDmgInfo.dmgFlags =
+ this->bodyColliderElements[2].base.atDmgInfo.dmgFlags = DMG_DEFAULT;
+ this->bodyColliderElements[1].base.atDmgInfo.damage = this->bodyColliderElements[2].base.atDmgInfo.damage =
+ 8;
}
} else if (this->timer > 1) {
Vec3f tailPos;
this->timer--;
this->actor.shape.rot.y = this->actor.world.rot.y += this->tailSwipeSpeed;
- tailPos.x = this->sphElements[1].dim.worldSphere.center.x;
- tailPos.y = this->sphElements[1].dim.worldSphere.center.y;
- tailPos.z = this->sphElements[1].dim.worldSphere.center.z;
+ tailPos.x = this->bodyColliderElements[1].dim.worldSphere.center.x;
+ tailPos.y = this->bodyColliderElements[1].dim.worldSphere.center.y;
+ tailPos.z = this->bodyColliderElements[1].dim.worldSphere.center.z;
Actor_SpawnFloorDustRing(play, &this->actor, &tailPos, 5.0f, 2, 2.0f, 100, 15, false);
- tailPos.x = this->sphElements[2].dim.worldSphere.center.x;
- tailPos.y = this->sphElements[2].dim.worldSphere.center.y;
- tailPos.z = this->sphElements[2].dim.worldSphere.center.z;
+ tailPos.x = this->bodyColliderElements[2].dim.worldSphere.center.x;
+ tailPos.y = this->bodyColliderElements[2].dim.worldSphere.center.y;
+ tailPos.z = this->bodyColliderElements[2].dim.worldSphere.center.z;
Actor_SpawnFloorDustRing(play, &this->actor, &tailPos, 5.0f, 2, 2.0f, 100, 15, false);
- if (this->colliderBody.base.atFlags & AT_HIT) {
+ if (this->bodyCollider.base.atFlags & AT_HIT) {
Player* player = GET_PLAYER(play);
- if (this->colliderBody.base.at == &player->actor) {
+ if (this->bodyCollider.base.at == &player->actor) {
Actor_PlaySfx(&player->actor, NA_SE_PL_BODY_HIT);
}
}
- CollisionCheck_SetAT(play, &play->colChkCtx, &this->colliderBody.base);
+ CollisionCheck_SetAT(play, &play->colChkCtx, &this->bodyCollider.base);
}
}
@@ -726,10 +729,10 @@ void EnDodongo_Stunned(EnDodongo* this, PlayState* play) {
void EnDodongo_CollisionCheck(EnDodongo* this, PlayState* play) {
if (this->colliderHard.base.acFlags & AC_BOUNCED) {
this->colliderHard.base.acFlags &= ~AC_BOUNCED;
- this->colliderBody.base.acFlags &= ~AC_HIT;
- } else if ((this->colliderBody.base.acFlags & AC_HIT) && (this->actionState > DODONGO_DEATH)) {
- this->colliderBody.base.acFlags &= ~AC_HIT;
- Actor_SetDropFlagJntSph(&this->actor, &this->colliderBody, false);
+ this->bodyCollider.base.acFlags &= ~AC_HIT;
+ } else if ((this->bodyCollider.base.acFlags & AC_HIT) && (this->actionState > DODONGO_DEATH)) {
+ this->bodyCollider.base.acFlags &= ~AC_HIT;
+ Actor_SetDropFlagJntSph(&this->actor, &this->bodyCollider, false);
if (this->actor.colChkInfo.damageEffect != 0xE) {
this->damageEffect = this->actor.colChkInfo.damageEffect;
if ((this->actor.colChkInfo.damageEffect == 1) || (this->actor.colChkInfo.damageEffect == 0xF)) {
@@ -790,12 +793,12 @@ void EnDodongo_Update(Actor* thisx, PlayState* play) {
Actor_PlaySfx(&this->actor, NA_SE_EN_RIZA_DOWN);
}
}
- CollisionCheck_SetOC(play, &play->colChkCtx, &this->colliderBody.base);
+ CollisionCheck_SetOC(play, &play->colChkCtx, &this->bodyCollider.base);
if (this->actionState != DODONGO_DEATH) {
CollisionCheck_SetAC(play, &play->colChkCtx, &this->colliderHard.base);
}
if (this->actionState > DODONGO_DEATH) {
- CollisionCheck_SetAC(play, &play->colChkCtx, &this->colliderBody.base);
+ CollisionCheck_SetAC(play, &play->colChkCtx, &this->bodyCollider.base);
}
if ((this->actionState >= DODONGO_IDLE) && EnDodongo_AteBomb(this, play)) {
EnDodongo_SetupSwallowBomb(this);
@@ -852,7 +855,7 @@ void EnDodongo_PostLimbDraw(PlayState* play, s32 limbIndex, Gfx** dList, Vec3s*
Vec3f mouthOffset = { 1800.0f, 1200.0f, 0.0f };
Vec3f headOffset = { 1500.0f, 300.0f, 0.0f };
- Collider_UpdateSpheres(limbIndex, &this->colliderBody);
+ Collider_UpdateSpheres(limbIndex, &this->bodyCollider);
switch (limbIndex) {
case 2:
diff --git a/src/overlays/actors/ovl_En_Dodongo/z_en_dodongo.h b/src/overlays/actors/ovl_En_Dodongo/z_en_dodongo.h
index 14bb2a524..7785030d4 100644
--- a/src/overlays/actors/ovl_En_Dodongo/z_en_dodongo.h
+++ b/src/overlays/actors/ovl_En_Dodongo/z_en_dodongo.h
@@ -35,8 +35,8 @@ typedef struct EnDodongo {
/* 0x03D4 */ ColliderQuad colliderAT;
/* 0x0454 */ ColliderTris colliderHard;
/* 0x0474 */ ColliderTrisElement trisElements[3];
- /* 0x0588 */ ColliderJntSph colliderBody;
- /* 0x05A8 */ ColliderJntSphElement sphElements[6];
+ /* 0x0588 */ ColliderJntSph bodyCollider;
+ /* 0x05A8 */ ColliderJntSphElement bodyColliderElements[6];
} EnDodongo; // size = 0x0728
typedef enum EnDodongoParam {
diff --git a/src/overlays/actors/ovl_En_Dog/z_en_dog.c b/src/overlays/actors/ovl_En_Dog/z_en_dog.c
index 49b8c83ba..0255b0162 100644
--- a/src/overlays/actors/ovl_En_Dog/z_en_dog.c
+++ b/src/overlays/actors/ovl_En_Dog/z_en_dog.c
@@ -5,6 +5,14 @@
*/
#include "z_en_dog.h"
+
+#include "gfx.h"
+#include "gfx_setupdl.h"
+#include "sfx.h"
+#include "z_lib.h"
+#include "z64play.h"
+#include "z64save.h"
+
#include "assets/objects/object_dog/object_dog.h"
#define FLAGS 0
diff --git a/src/overlays/actors/ovl_En_Dog/z_en_dog.h b/src/overlays/actors/ovl_En_Dog/z_en_dog.h
index dec2b5c18..c3cdfd913 100644
--- a/src/overlays/actors/ovl_En_Dog/z_en_dog.h
+++ b/src/overlays/actors/ovl_En_Dog/z_en_dog.h
@@ -2,18 +2,18 @@
#define Z_EN_DOG_H
#include "ultra64.h"
-#include "global.h"
+#include "z64actor.h"
struct EnDog;
-typedef void (*EnDogActionFunc)(struct EnDog*, PlayState*);
+typedef void (*EnDogActionFunc)(struct EnDog*, struct PlayState*);
typedef struct EnDog {
/* 0x0000 */ Actor actor;
/* 0x014C */ SkelAnime skelAnime;
/* 0x0190 */ EnDogActionFunc actionFunc;
/* 0x0194 */ ColliderCylinder collider;
- /* 0x01E0 */ Path* path;
+ /* 0x01E0 */ struct Path* path;
/* 0x01E4 */ u8 reverse;
/* 0x01E6 */ s16 waypoint;
/* 0x01E8 */ s16 unusedAngle;
diff --git a/src/overlays/actors/ovl_En_Door/z_en_door.c b/src/overlays/actors/ovl_En_Door/z_en_door.c
index 4d650f0a1..b3f71481d 100644
--- a/src/overlays/actors/ovl_En_Door/z_en_door.c
+++ b/src/overlays/actors/ovl_En_Door/z_en_door.c
@@ -5,7 +5,18 @@
*/
#include "z_en_door.h"
-#include "global.h"
+
+#include "libc64/qrand.h"
+#include "gfx.h"
+#include "gfx_setupdl.h"
+#include "ichain.h"
+#include "sfx.h"
+#include "z_lib.h"
+#include "z64effect.h"
+#include "z64play.h"
+#include "z64player.h"
+#include "z64save.h"
+
#include "assets/objects/gameplay_keep/gameplay_keep.h"
#include "assets/objects/gameplay_field_keep/gameplay_field_keep.h"
#include "assets/objects/object_hidan_objects/object_hidan_objects.h"
diff --git a/src/overlays/actors/ovl_En_Ds/z_en_ds.c b/src/overlays/actors/ovl_En_Ds/z_en_ds.c
index c76713a75..3c879ee1a 100644
--- a/src/overlays/actors/ovl_En_Ds/z_en_ds.c
+++ b/src/overlays/actors/ovl_En_Ds/z_en_ds.c
@@ -5,6 +5,16 @@
*/
#include "z_en_ds.h"
+
+#include "gfx.h"
+#include "gfx_setupdl.h"
+#include "sfx.h"
+#include "sys_matrix.h"
+#include "z_lib.h"
+#include "z64play.h"
+#include "z64player.h"
+#include "z64save.h"
+
#include "assets/objects/object_ds/object_ds.h"
#define FLAGS (ACTOR_FLAG_ATTENTION_ENABLED | ACTOR_FLAG_FRIENDLY)
diff --git a/src/overlays/actors/ovl_En_Ds/z_en_ds.h b/src/overlays/actors/ovl_En_Ds/z_en_ds.h
index 8f10ce828..9c7df969c 100644
--- a/src/overlays/actors/ovl_En_Ds/z_en_ds.h
+++ b/src/overlays/actors/ovl_En_Ds/z_en_ds.h
@@ -2,11 +2,11 @@
#define Z_EN_DS_H
#include "ultra64.h"
-#include "global.h"
+#include "z64actor.h"
struct EnDs;
-typedef void (*EnDsActionFunc)(struct EnDs*, PlayState*);
+typedef void (*EnDsActionFunc)(struct EnDs*, struct PlayState*);
typedef struct EnDs {
/* 0x0000 */ Actor actor;
diff --git a/src/overlays/actors/ovl_En_Du/z_en_du.c b/src/overlays/actors/ovl_En_Du/z_en_du.c
index f77bec5a8..1f716b977 100644
--- a/src/overlays/actors/ovl_En_Du/z_en_du.c
+++ b/src/overlays/actors/ovl_En_Du/z_en_du.c
@@ -1,4 +1,19 @@
#include "z_en_du.h"
+
+#include "gfx.h"
+#include "one_point_cutscene.h"
+#include "segmented_address.h"
+#include "sequence.h"
+#include "sfx.h"
+#include "sys_matrix.h"
+#include "z_lib.h"
+#include "z64audio.h"
+#include "z64face_reaction.h"
+#include "z64ocarina.h"
+#include "z64play.h"
+#include "z64player.h"
+#include "z64save.h"
+
#include "assets/objects/object_du/object_du.h"
#include "assets/scenes/overworld/spot18/spot18_scene.h"
diff --git a/src/overlays/actors/ovl_En_Du/z_en_du.h b/src/overlays/actors/ovl_En_Du/z_en_du.h
index 541b4368e..9e3ecb880 100644
--- a/src/overlays/actors/ovl_En_Du/z_en_du.h
+++ b/src/overlays/actors/ovl_En_Du/z_en_du.h
@@ -2,11 +2,11 @@
#define Z_EN_DU_H
#include "ultra64.h"
-#include "global.h"
+#include "z64actor.h"
struct EnDu;
-typedef void (*EnDuActionFunc)(struct EnDu*, PlayState*);
+typedef void (*EnDuActionFunc)(struct EnDu*, struct PlayState*);
typedef struct EnDu {
/* 0x0000 */ Actor actor;
diff --git a/src/overlays/actors/ovl_En_Eg/z_en_eg.c b/src/overlays/actors/ovl_En_Eg/z_en_eg.c
index c646cdf24..9023f99ea 100644
--- a/src/overlays/actors/ovl_En_Eg/z_en_eg.c
+++ b/src/overlays/actors/ovl_En_Eg/z_en_eg.c
@@ -5,7 +5,15 @@
*/
#include "z_en_eg.h"
+
+#include "regs.h"
+#include "seqcmd.h"
+#include "sequence.h"
+#include "sfx.h"
#include "terminal.h"
+#include "z_lib.h"
+#include "z64play.h"
+#include "z64save.h"
#define FLAGS ACTOR_FLAG_UPDATE_CULLING_DISABLED
diff --git a/src/overlays/actors/ovl_En_Eg/z_en_eg.h b/src/overlays/actors/ovl_En_Eg/z_en_eg.h
index ad02d8a6b..c42994f61 100644
--- a/src/overlays/actors/ovl_En_Eg/z_en_eg.h
+++ b/src/overlays/actors/ovl_En_Eg/z_en_eg.h
@@ -2,11 +2,11 @@
#define Z_EN_EG_H
#include "ultra64.h"
-#include "global.h"
+#include "z64actor.h"
struct EnEg;
-typedef void (*EnEgActionFunc)(struct EnEg*, PlayState*);
+typedef void (*EnEgActionFunc)(struct EnEg*, struct PlayState*);
typedef struct EnEg {
/* 0x0000 */ Actor actor;
diff --git a/src/overlays/actors/ovl_En_Eiyer/z_en_eiyer.c b/src/overlays/actors/ovl_En_Eiyer/z_en_eiyer.c
index d80432689..d60d91c22 100644
--- a/src/overlays/actors/ovl_En_Eiyer/z_en_eiyer.c
+++ b/src/overlays/actors/ovl_En_Eiyer/z_en_eiyer.c
@@ -11,8 +11,6 @@
#include "z64play.h"
#include "z64player.h"
-#include "global.h"
-
#include "assets/objects/object_ei/object_ei.h"
#define FLAGS (ACTOR_FLAG_ATTENTION_ENABLED | ACTOR_FLAG_HOSTILE)
diff --git a/src/overlays/actors/ovl_En_Elf/z_en_elf.c b/src/overlays/actors/ovl_En_Elf/z_en_elf.c
index a5fd62af6..58cd30f3f 100644
--- a/src/overlays/actors/ovl_En_Elf/z_en_elf.c
+++ b/src/overlays/actors/ovl_En_Elf/z_en_elf.c
@@ -24,8 +24,8 @@
#include "z64light.h"
#include "z64play.h"
#include "z64player.h"
-
-#include "global.h"
+#include "z64quest_hint.h"
+#include "z64save.h"
#include "assets/objects/gameplay_keep/gameplay_keep.h"
diff --git a/src/overlays/actors/ovl_En_Encount1/z_en_encount1.c b/src/overlays/actors/ovl_En_Encount1/z_en_encount1.c
index 6411ced01..034cba397 100644
--- a/src/overlays/actors/ovl_En_Encount1/z_en_encount1.c
+++ b/src/overlays/actors/ovl_En_Encount1/z_en_encount1.c
@@ -9,6 +9,7 @@
#include "z64debug_display.h"
#include "z64play.h"
#include "z64player.h"
+#include "z64save.h"
#define FLAGS (ACTOR_FLAG_UPDATE_CULLING_DISABLED | ACTOR_FLAG_LOCK_ON_DISABLED)
diff --git a/src/overlays/actors/ovl_En_Encount2/z_en_encount2.c b/src/overlays/actors/ovl_En_Encount2/z_en_encount2.c
index 6ff21c428..0fd64079e 100644
--- a/src/overlays/actors/ovl_En_Encount2/z_en_encount2.c
+++ b/src/overlays/actors/ovl_En_Encount2/z_en_encount2.c
@@ -12,6 +12,7 @@
#include "z_lib.h"
#include "z64play.h"
#include "z64player.h"
+#include "z64save.h"
#include "assets/objects/object_efc_star_field/object_efc_star_field.h"
diff --git a/src/overlays/actors/ovl_En_Ex_Item/z_en_ex_item.c b/src/overlays/actors/ovl_En_Ex_Item/z_en_ex_item.c
index 40f0b99eb..b7232a5c4 100644
--- a/src/overlays/actors/ovl_En_Ex_Item/z_en_ex_item.c
+++ b/src/overlays/actors/ovl_En_Ex_Item/z_en_ex_item.c
@@ -18,6 +18,7 @@
#include "z64draw.h"
#include "z64play.h"
#include "z64player.h"
+#include "z64save.h"
#include "assets/objects/gameplay_keep/gameplay_keep.h"
diff --git a/src/overlays/actors/ovl_En_Ex_Ruppy/z_en_ex_ruppy.c b/src/overlays/actors/ovl_En_Ex_Ruppy/z_en_ex_ruppy.c
index 730880dfa..a8dc2eb5d 100644
--- a/src/overlays/actors/ovl_En_Ex_Ruppy/z_en_ex_ruppy.c
+++ b/src/overlays/actors/ovl_En_Ex_Ruppy/z_en_ex_ruppy.c
@@ -13,6 +13,7 @@
#include "z_lib.h"
#include "z64effect.h"
#include "z64play.h"
+#include "z64save.h"
#include "assets/objects/gameplay_keep/gameplay_keep.h"
diff --git a/src/overlays/actors/ovl_En_Fd/z_en_fd.c b/src/overlays/actors/ovl_En_Fd/z_en_fd.c
index 0a08c2554..57a31b62e 100644
--- a/src/overlays/actors/ovl_En_Fd/z_en_fd.c
+++ b/src/overlays/actors/ovl_En_Fd/z_en_fd.c
@@ -5,7 +5,21 @@
*/
#include "z_en_fd.h"
+
+#include "libc64/math64.h"
+#include "libc64/qrand.h"
+#include "gfx.h"
+#include "gfx_setupdl.h"
+#include "segmented_address.h"
+#include "sequence.h"
+#include "sfx.h"
+#include "sys_matrix.h"
#include "versions.h"
+#include "z_lib.h"
+#include "z64audio.h"
+#include "z64play.h"
+#include "z64player.h"
+
#include "assets/objects/gameplay_keep/gameplay_keep.h"
#include "assets/objects/object_fw/object_fw.h"
diff --git a/src/overlays/actors/ovl_En_Fd/z_en_fd.h b/src/overlays/actors/ovl_En_Fd/z_en_fd.h
index e68ac8788..3fc40a54c 100644
--- a/src/overlays/actors/ovl_En_Fd/z_en_fd.h
+++ b/src/overlays/actors/ovl_En_Fd/z_en_fd.h
@@ -2,11 +2,11 @@
#define Z_EN_FD_H
#include "ultra64.h"
-#include "global.h"
+#include "z64actor.h"
struct EnFd;
-typedef void (*EnFdActionFunc)(struct EnFd* this, PlayState* play);
+typedef void (*EnFdActionFunc)(struct EnFd* this, struct PlayState* play);
typedef enum FDEffectType {
FD_EFFECT_NONE,
diff --git a/src/overlays/actors/ovl_En_Fd_Fire/z_en_fd_fire.c b/src/overlays/actors/ovl_En_Fd_Fire/z_en_fd_fire.c
index d408b7b9a..815d8c654 100644
--- a/src/overlays/actors/ovl_En_Fd_Fire/z_en_fd_fire.c
+++ b/src/overlays/actors/ovl_En_Fd_Fire/z_en_fd_fire.c
@@ -1,4 +1,13 @@
#include "z_en_fd_fire.h"
+
+#include "gfx.h"
+#include "gfx_setupdl.h"
+#include "rand.h"
+#include "sys_matrix.h"
+#include "z_lib.h"
+#include "z64play.h"
+#include "z64player.h"
+
#include "assets/objects/gameplay_keep/gameplay_keep.h"
#define FLAGS (ACTOR_FLAG_ATTENTION_ENABLED | ACTOR_FLAG_HOSTILE | ACTOR_FLAG_UPDATE_CULLING_DISABLED)
diff --git a/src/overlays/actors/ovl_En_Fd_Fire/z_en_fd_fire.h b/src/overlays/actors/ovl_En_Fd_Fire/z_en_fd_fire.h
index 414fdf997..d027a0797 100644
--- a/src/overlays/actors/ovl_En_Fd_Fire/z_en_fd_fire.h
+++ b/src/overlays/actors/ovl_En_Fd_Fire/z_en_fd_fire.h
@@ -2,11 +2,11 @@
#define Z_EN_FD_FIRE_H
#include "ultra64.h"
-#include "global.h"
+#include "z64actor.h"
struct EnFdFire;
-typedef void (*EnFdFireActionFunc)(struct EnFdFire* this, PlayState* play);
+typedef void (*EnFdFireActionFunc)(struct EnFdFire* this, struct PlayState* play);
typedef struct EnFdFire {
/* 0x0000 */ Actor actor;
diff --git a/src/overlays/actors/ovl_En_Fhg_Fire/z_en_fhg_fire.c b/src/overlays/actors/ovl_En_Fhg_Fire/z_en_fhg_fire.c
index aa3f190ce..308c9f513 100644
--- a/src/overlays/actors/ovl_En_Fhg_Fire/z_en_fhg_fire.c
+++ b/src/overlays/actors/ovl_En_Fhg_Fire/z_en_fhg_fire.c
@@ -5,12 +5,28 @@
*/
#include "z_en_fhg_fire.h"
-#include "assets/objects/object_fhg/object_fhg.h"
-#include "assets/objects/gameplay_keep/gameplay_keep.h"
#include "overlays/actors/ovl_Boss_Ganondrof/z_boss_ganondrof.h"
#include "overlays/actors/ovl_En_fHG/z_en_fhg.h"
#include "overlays/effects/ovl_Effect_Ss_Fhg_Flash/z_eff_ss_fhg_flash.h"
+#include "libc64/math64.h"
+#include "libc64/qrand.h"
+#include "attributes.h"
+#include "gfx.h"
+#include "gfx_setupdl.h"
+#include "rand.h"
+#include "rumble.h"
+#include "segmented_address.h"
+#include "sfx.h"
+#include "sys_matrix.h"
+#include "z_lib.h"
+#include "z64effect.h"
+#include "z64play.h"
+#include "z64player.h"
+
+#include "assets/objects/gameplay_keep/gameplay_keep.h"
+#include "assets/objects/object_fhg/object_fhg.h"
+
#define FLAGS (ACTOR_FLAG_UPDATE_CULLING_DISABLED | ACTOR_FLAG_DRAW_CULLING_DISABLED)
typedef enum StrikeMode {
diff --git a/src/overlays/actors/ovl_En_Fhg_Fire/z_en_fhg_fire.h b/src/overlays/actors/ovl_En_Fhg_Fire/z_en_fhg_fire.h
index ac2682aaf..59136f7df 100644
--- a/src/overlays/actors/ovl_En_Fhg_Fire/z_en_fhg_fire.h
+++ b/src/overlays/actors/ovl_En_Fhg_Fire/z_en_fhg_fire.h
@@ -2,11 +2,12 @@
#define Z_EN_FHG_FIRE_H
#include "ultra64.h"
-#include "global.h"
+#include "z64actor.h"
+#include "z64light.h"
struct EnFhgFire;
-typedef void (*EnFhgFireUpdateFunc)(struct EnFhgFire*, PlayState*);
+typedef void (*EnFhgFireUpdateFunc)(struct EnFhgFire*, struct PlayState*);
typedef enum FhgFireParam {
/* 1 */ FHGFIRE_LIGHTNING_STRIKE = 1,
diff --git a/src/overlays/actors/ovl_En_Fish/z_en_fish.c b/src/overlays/actors/ovl_En_Fish/z_en_fish.c
index f2f9185a7..6634d2cf2 100644
--- a/src/overlays/actors/ovl_En_Fish/z_en_fish.c
+++ b/src/overlays/actors/ovl_En_Fish/z_en_fish.c
@@ -5,9 +5,19 @@
*/
#include "z_en_fish.h"
-#include "global.h"
-#include "assets/objects/gameplay_keep/gameplay_keep.h"
+
+#include "libc64/qrand.h"
+#include "gfx.h"
+#include "gfx_setupdl.h"
+#include "ichain.h"
+#include "sfx.h"
#include "terminal.h"
+#include "z_lib.h"
+#include "z64item.h"
+#include "z64play.h"
+#include "z64player.h"
+
+#include "assets/objects/gameplay_keep/gameplay_keep.h"
#define FLAGS 0
diff --git a/src/overlays/actors/ovl_En_Floormas/z_en_floormas.c b/src/overlays/actors/ovl_En_Floormas/z_en_floormas.c
index 4e31c7b77..d365822f5 100644
--- a/src/overlays/actors/ovl_En_Floormas/z_en_floormas.c
+++ b/src/overlays/actors/ovl_En_Floormas/z_en_floormas.c
@@ -16,6 +16,7 @@
#include "z64effect.h"
#include "z64play.h"
#include "z64player.h"
+#include "z64save.h"
#include "assets/objects/object_wallmaster/object_wallmaster.h"
diff --git a/src/overlays/actors/ovl_En_Fr/z_en_fr.c b/src/overlays/actors/ovl_En_Fr/z_en_fr.c
index f6e1f00c5..a05e54d0b 100644
--- a/src/overlays/actors/ovl_En_Fr/z_en_fr.c
+++ b/src/overlays/actors/ovl_En_Fr/z_en_fr.c
@@ -19,6 +19,7 @@
#include "z64ocarina.h"
#include "z64play.h"
#include "z64player.h"
+#include "z64save.h"
#include "global.h"
diff --git a/src/overlays/actors/ovl_En_Fu/z_en_fu.c b/src/overlays/actors/ovl_En_Fu/z_en_fu.c
index 8069e6cb2..24818477d 100644
--- a/src/overlays/actors/ovl_En_Fu/z_en_fu.c
+++ b/src/overlays/actors/ovl_En_Fu/z_en_fu.c
@@ -5,6 +5,19 @@
*/
#include "z_en_fu.h"
+
+#include "gfx.h"
+#include "gfx_setupdl.h"
+#include "segmented_address.h"
+#include "sfx.h"
+#include "sys_matrix.h"
+#include "z_lib.h"
+#include "z64face_reaction.h"
+#include "z64ocarina.h"
+#include "z64play.h"
+#include "z64player.h"
+#include "z64save.h"
+
#include "assets/objects/object_fu/object_fu.h"
#include "assets/scenes/indoors/hakasitarelay/hakasitarelay_scene.h"
diff --git a/src/overlays/actors/ovl_En_Fu/z_en_fu.h b/src/overlays/actors/ovl_En_Fu/z_en_fu.h
index dbbcacfc5..af90b2cf0 100644
--- a/src/overlays/actors/ovl_En_Fu/z_en_fu.h
+++ b/src/overlays/actors/ovl_En_Fu/z_en_fu.h
@@ -2,11 +2,11 @@
#define Z_EN_FU_H
#include "ultra64.h"
-#include "global.h"
+#include "z64actor.h"
struct EnFu;
-typedef void (*EnFuActionFunc)(struct EnFu*, PlayState*);
+typedef void (*EnFuActionFunc)(struct EnFu*, struct PlayState*);
typedef enum EnFuLimb {
/* 0x00 */ FU_LIMB_ROOT,
diff --git a/src/overlays/actors/ovl_En_G_Switch/z_en_g_switch.c b/src/overlays/actors/ovl_En_G_Switch/z_en_g_switch.c
index 08bd88238..4476e6e0c 100644
--- a/src/overlays/actors/ovl_En_G_Switch/z_en_g_switch.c
+++ b/src/overlays/actors/ovl_En_G_Switch/z_en_g_switch.c
@@ -25,6 +25,7 @@
#include "z64effect.h"
#include "z64play.h"
#include "z64player.h"
+#include "z64save.h"
#include "assets/objects/gameplay_keep/gameplay_keep.h"
#include "assets/objects/object_tsubo/object_tsubo.h"
diff --git a/src/overlays/actors/ovl_En_Ganon_Organ/z_en_ganon_organ.c b/src/overlays/actors/ovl_En_Ganon_Organ/z_en_ganon_organ.c
index d64111fb9..30f18393a 100644
--- a/src/overlays/actors/ovl_En_Ganon_Organ/z_en_ganon_organ.c
+++ b/src/overlays/actors/ovl_En_Ganon_Organ/z_en_ganon_organ.c
@@ -5,6 +5,12 @@
*/
#include "z_en_ganon_organ.h"
+
+#include "gfx.h"
+#include "gfx_setupdl.h"
+#include "sys_matrix.h"
+#include "z64play.h"
+
#include "overlays/actors/ovl_Boss_Ganon/z_boss_ganon.h"
#define FLAGS (ACTOR_FLAG_UPDATE_CULLING_DISABLED | ACTOR_FLAG_DRAW_CULLING_DISABLED)
diff --git a/src/overlays/actors/ovl_En_Ganon_Organ/z_en_ganon_organ.h b/src/overlays/actors/ovl_En_Ganon_Organ/z_en_ganon_organ.h
index 0c301bddc..8d20bee4d 100644
--- a/src/overlays/actors/ovl_En_Ganon_Organ/z_en_ganon_organ.h
+++ b/src/overlays/actors/ovl_En_Ganon_Organ/z_en_ganon_organ.h
@@ -2,7 +2,7 @@
#define Z_EN_GANON_ORGAN_H
#include "ultra64.h"
-#include "global.h"
+#include "z64actor.h"
struct EnGanonOrgan;
diff --git a/src/overlays/actors/ovl_En_Gb/z_en_gb.c b/src/overlays/actors/ovl_En_Gb/z_en_gb.c
index e37400ce5..de443fe30 100644
--- a/src/overlays/actors/ovl_En_Gb/z_en_gb.c
+++ b/src/overlays/actors/ovl_En_Gb/z_en_gb.c
@@ -5,6 +5,21 @@
*/
#include "z_en_gb.h"
+
+#include "libc64/qrand.h"
+#include "gfx.h"
+#include "gfx_setupdl.h"
+#include "ichain.h"
+#include "rand.h"
+#include "segmented_address.h"
+#include "sfx.h"
+#include "sys_matrix.h"
+#include "z_lib.h"
+#include "z64light.h"
+#include "z64play.h"
+#include "z64player.h"
+#include "z64save.h"
+
#include "assets/objects/object_ps/object_ps.h"
#define FLAGS (ACTOR_FLAG_ATTENTION_ENABLED | ACTOR_FLAG_FRIENDLY)
diff --git a/src/overlays/actors/ovl_En_Gb/z_en_gb.h b/src/overlays/actors/ovl_En_Gb/z_en_gb.h
index 4005075c4..24b7d3056 100644
--- a/src/overlays/actors/ovl_En_Gb/z_en_gb.h
+++ b/src/overlays/actors/ovl_En_Gb/z_en_gb.h
@@ -2,11 +2,12 @@
#define Z_EN_GB_H
#include "ultra64.h"
-#include "global.h"
+#include "z64actor.h"
+#include "z64light.h"
struct EnGb;
-typedef void (*EnGbActionFunc)(struct EnGb*, PlayState*);
+typedef void (*EnGbActionFunc)(struct EnGb*, struct PlayState*);
typedef struct EnGbCagedSoulInfo {
/* 0x00 */ Color_RGBA8 prim;
diff --git a/src/overlays/actors/ovl_En_Ge1/z_en_ge1.c b/src/overlays/actors/ovl_En_Ge1/z_en_ge1.c
index 8082c7d87..745fa4a49 100644
--- a/src/overlays/actors/ovl_En_Ge1/z_en_ge1.c
+++ b/src/overlays/actors/ovl_En_Ge1/z_en_ge1.c
@@ -5,8 +5,21 @@
*/
#include "z_en_ge1.h"
-#include "z64horse.h"
+
+#include "libu64/debug.h"
+#include "gfx.h"
+#include "gfx_setupdl.h"
+#include "segmented_address.h"
+#include "sfx.h"
+#include "sys_matrix.h"
#include "terminal.h"
+#include "z_lib.h"
+#include "z64face_reaction.h"
+#include "z64horse.h"
+#include "z64play.h"
+#include "z64player.h"
+#include "z64save.h"
+
#include "assets/objects/object_ge1/object_ge1.h"
#define FLAGS (ACTOR_FLAG_ATTENTION_ENABLED | ACTOR_FLAG_FRIENDLY)
diff --git a/src/overlays/actors/ovl_En_Ge1/z_en_ge1.h b/src/overlays/actors/ovl_En_Ge1/z_en_ge1.h
index 7fb1692f6..6aaaf2ab3 100644
--- a/src/overlays/actors/ovl_En_Ge1/z_en_ge1.h
+++ b/src/overlays/actors/ovl_En_Ge1/z_en_ge1.h
@@ -2,12 +2,12 @@
#define Z_EN_GE1_H
#include "ultra64.h"
-#include "global.h"
+#include "z64actor.h"
struct EnGe1;
typedef void (*EnGe1AnimFunc)(struct EnGe1*);
-typedef void (*EnGe1ActionFunc)(struct EnGe1*, PlayState*);
+typedef void (*EnGe1ActionFunc)(struct EnGe1*, struct PlayState*);
typedef enum EnGe1Type {
/* 0x00 */ GE1_TYPE_GATE_GUARD,
diff --git a/src/overlays/actors/ovl_En_Ge2/z_en_ge2.c b/src/overlays/actors/ovl_En_Ge2/z_en_ge2.c
index 0df133fe4..2ff3ec7b5 100644
--- a/src/overlays/actors/ovl_En_Ge2/z_en_ge2.c
+++ b/src/overlays/actors/ovl_En_Ge2/z_en_ge2.c
@@ -5,8 +5,20 @@
*/
#include "z_en_ge2.h"
-#include "z64horse.h"
+
+#include "gfx.h"
+#include "gfx_setupdl.h"
+#include "segmented_address.h"
+#include "sfx.h"
+#include "sys_matrix.h"
#include "terminal.h"
+#include "z_lib.h"
+#include "z64effect.h"
+#include "z64horse.h"
+#include "z64play.h"
+#include "z64player.h"
+#include "z64save.h"
+
#include "assets/objects/object_gla/object_gla.h"
#define FLAGS (ACTOR_FLAG_ATTENTION_ENABLED | ACTOR_FLAG_FRIENDLY | ACTOR_FLAG_UPDATE_CULLING_DISABLED)
diff --git a/src/overlays/actors/ovl_En_Ge2/z_en_ge2.h b/src/overlays/actors/ovl_En_Ge2/z_en_ge2.h
index 7c78ad91a..b45353104 100644
--- a/src/overlays/actors/ovl_En_Ge2/z_en_ge2.h
+++ b/src/overlays/actors/ovl_En_Ge2/z_en_ge2.h
@@ -2,11 +2,11 @@
#define Z_EN_GE2_H
#include "ultra64.h"
-#include "global.h"
+#include "z64actor.h"
struct EnGe2;
-typedef void (*EnGe2ActionFunc)(struct EnGe2*, PlayState*);
+typedef void (*EnGe2ActionFunc)(struct EnGe2*, struct PlayState*);
typedef struct EnGe2 {
/* 0x0000 */ Actor actor;
diff --git a/src/overlays/actors/ovl_En_Ge3/z_en_ge3.c b/src/overlays/actors/ovl_En_Ge3/z_en_ge3.c
index 614936d3b..5e0783bc3 100644
--- a/src/overlays/actors/ovl_En_Ge3/z_en_ge3.c
+++ b/src/overlays/actors/ovl_En_Ge3/z_en_ge3.c
@@ -5,8 +5,19 @@
*/
#include "z_en_ge3.h"
-#include "assets/objects/object_geldb/object_geldb.h"
+
+#include "attributes.h"
+#include "gfx.h"
+#include "gfx_setupdl.h"
+#include "segmented_address.h"
+#include "sys_matrix.h"
#include "versions.h"
+#include "z_lib.h"
+#include "z64item.h"
+#include "z64play.h"
+#include "z64player.h"
+
+#include "assets/objects/object_geldb/object_geldb.h"
#define FLAGS (ACTOR_FLAG_ATTENTION_ENABLED | ACTOR_FLAG_FRIENDLY | ACTOR_FLAG_UPDATE_CULLING_DISABLED)
diff --git a/src/overlays/actors/ovl_En_Ge3/z_en_ge3.h b/src/overlays/actors/ovl_En_Ge3/z_en_ge3.h
index 4bb5c7b3f..d767ba6d9 100644
--- a/src/overlays/actors/ovl_En_Ge3/z_en_ge3.h
+++ b/src/overlays/actors/ovl_En_Ge3/z_en_ge3.h
@@ -2,12 +2,12 @@
#define Z_EN_GE3_H
#include "ultra64.h"
-#include "global.h"
+#include "z64actor.h"
#include "overlays/actors/ovl_En_GeldB/z_en_geldb.h"
struct EnGe3;
-typedef void (*EnGe3ActionFunc)(struct EnGe3*, PlayState*);
+typedef void (*EnGe3ActionFunc)(struct EnGe3*, struct PlayState*);
typedef struct EnGe3 {
/* 0x0000 */ Actor actor;
diff --git a/src/overlays/actors/ovl_En_GeldB/z_en_geldb.c b/src/overlays/actors/ovl_En_GeldB/z_en_geldb.c
index c36cbeb5d..33b53f4dc 100644
--- a/src/overlays/actors/ovl_En_GeldB/z_en_geldb.c
+++ b/src/overlays/actors/ovl_En_GeldB/z_en_geldb.c
@@ -21,6 +21,7 @@
#include "z64effect.h"
#include "z64play.h"
#include "z64player.h"
+#include "z64save.h"
#include "assets/objects/object_geldb/object_geldb.h"
diff --git a/src/overlays/actors/ovl_En_GirlA/z_en_girla.c b/src/overlays/actors/ovl_En_GirlA/z_en_girla.c
index 22b37cbab..08c47da26 100644
--- a/src/overlays/actors/ovl_En_GirlA/z_en_girla.c
+++ b/src/overlays/actors/ovl_En_GirlA/z_en_girla.c
@@ -12,6 +12,7 @@
#include "z_lib.h"
#include "z64draw.h"
#include "z64play.h"
+#include "z64save.h"
#define FLAGS (ACTOR_FLAG_ATTENTION_ENABLED | ACTOR_FLAG_FRIENDLY | ACTOR_FLAG_UPDATE_CULLING_DISABLED)
diff --git a/src/overlays/actors/ovl_En_Gm/z_en_gm.c b/src/overlays/actors/ovl_En_Gm/z_en_gm.c
index 3ed42e511..75bf9b435 100644
--- a/src/overlays/actors/ovl_En_Gm/z_en_gm.c
+++ b/src/overlays/actors/ovl_En_Gm/z_en_gm.c
@@ -5,9 +5,21 @@
*/
#include "z_en_gm.h"
+
+#include "attributes.h"
+#include "gfx.h"
+#include "gfx_setupdl.h"
+#include "ichain.h"
+#include "rand.h"
+#include "segmented_address.h"
+#include "sys_matrix.h"
+#include "terminal.h"
+#include "z64play.h"
+#include "z64player.h"
+#include "z64save.h"
+
#include "assets/objects/object_oF1d_map/object_oF1d_map.h"
#include "assets/objects/object_gm/object_gm.h"
-#include "terminal.h"
#define FLAGS (ACTOR_FLAG_ATTENTION_ENABLED | ACTOR_FLAG_FRIENDLY | ACTOR_FLAG_UPDATE_CULLING_DISABLED)
diff --git a/src/overlays/actors/ovl_En_Gm/z_en_gm.h b/src/overlays/actors/ovl_En_Gm/z_en_gm.h
index 3cfedca01..d5234bde1 100644
--- a/src/overlays/actors/ovl_En_Gm/z_en_gm.h
+++ b/src/overlays/actors/ovl_En_Gm/z_en_gm.h
@@ -2,12 +2,12 @@
#define Z_EN_GM_H
#include "ultra64.h"
-#include "global.h"
+#include "z64actor.h"
struct EnGm;
-typedef void (*EnGmUpdateFunc)(struct EnGm*, PlayState*);
-typedef void (*EnGmActionFunc)(struct EnGm*, PlayState*);
+typedef void (*EnGmUpdateFunc)(struct EnGm*, struct PlayState*);
+typedef void (*EnGmActionFunc)(struct EnGm*, struct PlayState*);
typedef struct EnGm {
/* 0x0000 */ Actor actor;
diff --git a/src/overlays/actors/ovl_En_Go/z_en_go.c b/src/overlays/actors/ovl_En_Go/z_en_go.c
index 265d806fe..66a9ba1b4 100644
--- a/src/overlays/actors/ovl_En_Go/z_en_go.c
+++ b/src/overlays/actors/ovl_En_Go/z_en_go.c
@@ -1,5 +1,20 @@
#include "z_en_go.h"
#include "overlays/actors/ovl_En_Bom/z_en_bom.h"
+
+#include "libc64/math64.h"
+#include "libc64/qrand.h"
+#include "attributes.h"
+#include "gfx.h"
+#include "gfx_setupdl.h"
+#include "one_point_cutscene.h"
+#include "segmented_address.h"
+#include "sfx.h"
+#include "sys_matrix.h"
+#include "z_lib.h"
+#include "z64play.h"
+#include "z64player.h"
+#include "z64save.h"
+
#include "assets/objects/gameplay_keep/gameplay_keep.h"
#include "assets/objects/object_oF1d_map/object_oF1d_map.h"
diff --git a/src/overlays/actors/ovl_En_Go/z_en_go.h b/src/overlays/actors/ovl_En_Go/z_en_go.h
index bd673c952..691472aef 100644
--- a/src/overlays/actors/ovl_En_Go/z_en_go.h
+++ b/src/overlays/actors/ovl_En_Go/z_en_go.h
@@ -2,13 +2,13 @@
#define Z_EN_GO_H
#include "ultra64.h"
-#include "global.h"
+#include "z64actor.h"
struct EnGo;
-typedef void (*EnGoActionFunc)(struct EnGo*, PlayState*);
-typedef u16 (*callback1_80A3ED24)(PlayState*, struct EnGo*);
-typedef s16 (*callback2_80A3ED24)(PlayState*, struct EnGo*);
+typedef void (*EnGoActionFunc)(struct EnGo*, struct PlayState*);
+typedef u16 (*callback1_80A3ED24)(struct PlayState*, struct EnGo*);
+typedef s16 (*callback2_80A3ED24)(struct PlayState*, struct EnGo*);
// WIP type docs
// /* 0x00 */ GORON1_CITY_LINK,
diff --git a/src/overlays/actors/ovl_En_Go2/z_en_go2.c b/src/overlays/actors/ovl_En_Go2/z_en_go2.c
index af0c4e451..3b2d458e1 100644
--- a/src/overlays/actors/ovl_En_Go2/z_en_go2.c
+++ b/src/overlays/actors/ovl_En_Go2/z_en_go2.c
@@ -1,9 +1,26 @@
#include "z_en_go2.h"
#include "overlays/actors/ovl_En_Bom/z_en_bom.h"
+
+#include "libc64/qrand.h"
+#include "attributes.h"
+#include "gfx.h"
+#include "gfx_setupdl.h"
+#include "one_point_cutscene.h"
+#include "quake.h"
+#include "segmented_address.h"
+#include "sequence.h"
+#include "sfx.h"
+#include "sys_matrix.h"
+#include "versions.h"
+#include "z_lib.h"
+#include "z64audio.h"
+#include "z64face_reaction.h"
+#include "z64play.h"
+#include "z64player.h"
+#include "z64save.h"
+
#include "assets/objects/gameplay_keep/gameplay_keep.h"
#include "assets/objects/object_oF1d_map/object_oF1d_map.h"
-#include "quake.h"
-#include "versions.h"
#define FLAGS \
(ACTOR_FLAG_ATTENTION_ENABLED | ACTOR_FLAG_FRIENDLY | ACTOR_FLAG_UPDATE_CULLING_DISABLED | \
diff --git a/src/overlays/actors/ovl_En_Go2/z_en_go2.h b/src/overlays/actors/ovl_En_Go2/z_en_go2.h
index 6fb622935..0c49a3036 100644
--- a/src/overlays/actors/ovl_En_Go2/z_en_go2.h
+++ b/src/overlays/actors/ovl_En_Go2/z_en_go2.h
@@ -2,12 +2,12 @@
#define Z_EN_GO2_H
#include "ultra64.h"
-#include "global.h"
+#include "z64actor.h"
#include "overlays/actors/ovl_En_Go/z_en_go.h"
struct EnGo2;
-typedef void (*EnGo2ActionFunc)(struct EnGo2*, PlayState*);
+typedef void (*EnGo2ActionFunc)(struct EnGo2*, struct PlayState*);
typedef enum GoronType {
/* 0x00 */ GORON_CITY_ROLLING_BIG,
@@ -73,7 +73,7 @@ typedef struct EnGo2 {
/* 0x0190 */ EnGo2ActionFunc actionFunc;
/* 0x0194 */ NpcInteractInfo interactInfo;
/* 0x01BC */ ColliderCylinder collider;
- /* 0x0208 */ Path* path;
+ /* 0x0208 */ struct Path* path;
/* 0x020C */ u8 unk_20C; // counter for GORON_CITY_LINK animation
/* 0x020D */ u8 dialogState;
/* 0x020E */ u8 reverse;
diff --git a/src/overlays/actors/ovl_En_Goma/z_en_goma.c b/src/overlays/actors/ovl_En_Goma/z_en_goma.c
index f2e02c709..82175795b 100644
--- a/src/overlays/actors/ovl_En_Goma/z_en_goma.c
+++ b/src/overlays/actors/ovl_En_Goma/z_en_goma.c
@@ -185,10 +185,10 @@ void EnGoma_Init(Actor* thisx, PlayState* play) {
this->eggScale = 1.0f;
this->eggSquishAngle = Rand_ZeroOne() * 1000.0f;
this->actionTimer = 50;
- Collider_InitCylinder(play, &this->colCyl1);
- Collider_SetCylinder(play, &this->colCyl1, &this->actor, &D_80A4B7A0);
- Collider_InitCylinder(play, &this->colCyl2);
- Collider_SetCylinder(play, &this->colCyl2, &this->actor, &D_80A4B7CC);
+ Collider_InitCylinder(play, &this->colliderCylinder1);
+ Collider_SetCylinder(play, &this->colliderCylinder1, &this->actor, &D_80A4B7A0);
+ Collider_InitCylinder(play, &this->colliderCylinder2);
+ Collider_SetCylinder(play, &this->colliderCylinder2, &this->actor, &D_80A4B7CC);
}
}
@@ -196,8 +196,8 @@ void EnGoma_Destroy(Actor* thisx, PlayState* play) {
EnGoma* this = (EnGoma*)thisx;
if (this->actor.params < 10) {
- Collider_DestroyCylinder(play, &this->colCyl1);
- Collider_DestroyCylinder(play, &this->colCyl2);
+ Collider_DestroyCylinder(play, &this->colliderCylinder1);
+ Collider_DestroyCylinder(play, &this->colliderCylinder2);
}
}
@@ -635,15 +635,15 @@ void EnGoma_UpdateHit(EnGoma* this, PlayState* play) {
ColliderElement* acHitElem;
u8 swordDamage;
- if ((this->colCyl1.base.atFlags & AT_HIT) && this->actionFunc == EnGoma_Jump) {
+ if ((this->colliderCylinder1.base.atFlags & AT_HIT) && this->actionFunc == EnGoma_Jump) {
EnGoma_SetupLand(this);
this->actor.speed = 0.0f;
this->actor.velocity.y = 0.0f;
}
- if ((this->colCyl2.base.acFlags & AC_HIT) && (s8)this->actor.colChkInfo.health > 0) {
- acHitElem = this->colCyl2.elem.acHitElem;
- this->colCyl2.base.acFlags &= ~AC_HIT;
+ if ((this->colliderCylinder2.base.acFlags & AC_HIT) && (s8)this->actor.colChkInfo.health > 0) {
+ acHitElem = this->colliderCylinder2.elem.acHitElem;
+ this->colliderCylinder2.base.acFlags &= ~AC_HIT;
if (this->gomaType == ENGOMA_NORMAL) {
u32 dmgFlags = acHitElem->atDmgInfo.dmgFlags;
@@ -753,20 +753,20 @@ void EnGoma_Update(Actor* thisx, PlayState* play) {
EnGoma_UpdateEyeEnvColor(this);
this->visualState = 1;
if (player->meleeWeaponState != 0) {
- this->colCyl2.dim.radius = 35;
- this->colCyl2.dim.height = 35;
- this->colCyl2.dim.yShift = 0;
+ this->colliderCylinder2.dim.radius = 35;
+ this->colliderCylinder2.dim.height = 35;
+ this->colliderCylinder2.dim.yShift = 0;
} else {
- this->colCyl2.dim.radius = 15;
- this->colCyl2.dim.height = 30;
- this->colCyl2.dim.yShift = 10;
+ this->colliderCylinder2.dim.radius = 15;
+ this->colliderCylinder2.dim.height = 30;
+ this->colliderCylinder2.dim.yShift = 10;
}
if (this->invincibilityTimer == 0) {
- Collider_UpdateCylinder(&this->actor, &this->colCyl1);
- Collider_UpdateCylinder(&this->actor, &this->colCyl2);
- CollisionCheck_SetOC(play, &play->colChkCtx, &this->colCyl1.base);
- CollisionCheck_SetAC(play, &play->colChkCtx, &this->colCyl2.base);
- CollisionCheck_SetAT(play, &play->colChkCtx, &this->colCyl1.base);
+ Collider_UpdateCylinder(&this->actor, &this->colliderCylinder1);
+ Collider_UpdateCylinder(&this->actor, &this->colliderCylinder2);
+ CollisionCheck_SetOC(play, &play->colChkCtx, &this->colliderCylinder1.base);
+ CollisionCheck_SetAC(play, &play->colChkCtx, &this->colliderCylinder2.base);
+ CollisionCheck_SetAT(play, &play->colChkCtx, &this->colliderCylinder1.base);
}
}
}
diff --git a/src/overlays/actors/ovl_En_Goma/z_en_goma.h b/src/overlays/actors/ovl_En_Goma/z_en_goma.h
index c901cc937..6b2f7cf30 100644
--- a/src/overlays/actors/ovl_En_Goma/z_en_goma.h
+++ b/src/overlays/actors/ovl_En_Goma/z_en_goma.h
@@ -73,8 +73,8 @@ typedef struct EnGoma {
/* 0x2F8 */ s16 stunTimer;
/* 0x2FC */ Vec3f shieldKnockbackVel;
/* 0x308 */ Gfx* bossLimbDL; // set by z_boss_goma
- /* 0x30C */ ColliderCylinder colCyl1;
- /* 0x358 */ ColliderCylinder colCyl2;
+ /* 0x30C */ ColliderCylinder colliderCylinder1;
+ /* 0x358 */ ColliderCylinder colliderCylinder2;
} EnGoma; // size = 0x03A4
#endif
diff --git a/src/overlays/actors/ovl_En_Goroiwa/z_en_goroiwa.c b/src/overlays/actors/ovl_En_Goroiwa/z_en_goroiwa.c
index 944add853..bf25b3bc5 100644
--- a/src/overlays/actors/ovl_En_Goroiwa/z_en_goroiwa.c
+++ b/src/overlays/actors/ovl_En_Goroiwa/z_en_goroiwa.c
@@ -6,10 +6,23 @@
#include "z_en_goroiwa.h"
#include "overlays/effects/ovl_Effect_Ss_Kakera/z_eff_ss_kakera.h"
+
+#include "libc64/qrand.h"
+#include "ichain.h"
+#include "quake.h"
+#include "regs.h"
+#include "segmented_address.h"
+#include "sfx.h"
+#include "sys_math3d.h"
+#include "sys_matrix.h"
+#include "terminal.h"
+#include "z_lib.h"
+#include "z64effect.h"
+#include "z64play.h"
+#include "z64player.h"
+
#include "assets/objects/gameplay_keep/gameplay_keep.h"
#include "assets/objects/object_goroiwa/object_goroiwa.h"
-#include "quake.h"
-#include "terminal.h"
#define FLAGS ACTOR_FLAG_UPDATE_CULLING_DISABLED
diff --git a/src/overlays/actors/ovl_En_Goroiwa/z_en_goroiwa.h b/src/overlays/actors/ovl_En_Goroiwa/z_en_goroiwa.h
index 311ee5f94..26a5810a2 100644
--- a/src/overlays/actors/ovl_En_Goroiwa/z_en_goroiwa.h
+++ b/src/overlays/actors/ovl_En_Goroiwa/z_en_goroiwa.h
@@ -2,11 +2,11 @@
#define Z_EN_GOROIWA_H
#include "ultra64.h"
-#include "global.h"
+#include "z64actor.h"
struct EnGoroiwa;
-typedef void (*EnGoroiwaActionFunc)(struct EnGoroiwa*, PlayState*);
+typedef void (*EnGoroiwaActionFunc)(struct EnGoroiwa*, struct PlayState*);
typedef struct EnGoroiwa {
/* 0x0000 */ Actor actor;
diff --git a/src/overlays/actors/ovl_En_Gs/z_en_gs.c b/src/overlays/actors/ovl_En_Gs/z_en_gs.c
index 46d470c33..4e590217f 100644
--- a/src/overlays/actors/ovl_En_Gs/z_en_gs.c
+++ b/src/overlays/actors/ovl_En_Gs/z_en_gs.c
@@ -5,9 +5,23 @@
*/
#include "z_en_gs.h"
-#include "assets/objects/object_gs/object_gs.h"
#include "overlays/actors/ovl_En_Elf/z_en_elf.h"
+
+#include "gfx.h"
+#include "gfx_setupdl.h"
+#include "ichain.h"
+#include "rand.h"
+#include "regs.h"
+#include "sfx.h"
+#include "sys_matrix.h"
+#include "z_lib.h"
+#include "z64effect.h"
+#include "z64ocarina.h"
+#include "z64play.h"
+#include "z64player.h"
+
#include "assets/objects/gameplay_keep/gameplay_keep.h"
+#include "assets/objects/object_gs/object_gs.h"
#define FLAGS (ACTOR_FLAG_ATTENTION_ENABLED | ACTOR_FLAG_FRIENDLY | ACTOR_FLAG_UPDATE_DURING_OCARINA)
diff --git a/src/overlays/actors/ovl_En_Gs/z_en_gs.h b/src/overlays/actors/ovl_En_Gs/z_en_gs.h
index 47edd278d..d7abdc676 100644
--- a/src/overlays/actors/ovl_En_Gs/z_en_gs.h
+++ b/src/overlays/actors/ovl_En_Gs/z_en_gs.h
@@ -2,11 +2,11 @@
#define Z_EN_GS_H
#include "ultra64.h"
-#include "global.h"
+#include "z64actor.h"
struct EnGs;
-typedef void (*EnGsActionFunc)(struct EnGs*, PlayState*);
+typedef void (*EnGsActionFunc)(struct EnGs*, struct PlayState*);
typedef struct EnGs {
/* 0x0000 */ Actor actor;
diff --git a/src/overlays/actors/ovl_En_Guest/z_en_guest.c b/src/overlays/actors/ovl_En_Guest/z_en_guest.c
index 5c0a14f9d..117f891c1 100644
--- a/src/overlays/actors/ovl_En_Guest/z_en_guest.c
+++ b/src/overlays/actors/ovl_En_Guest/z_en_guest.c
@@ -5,9 +5,21 @@
*/
#include "z_en_guest.h"
+
+#include "gfx.h"
+#include "gfx_setupdl.h"
+#include "ichain.h"
+#include "rand.h"
+#include "segmented_address.h"
+#include "sys_matrix.h"
+#include "terminal.h"
+#include "z_lib.h"
+#include "z64play.h"
+#include "z64player.h"
+#include "z64save.h"
+
#include "assets/objects/object_os_anime/object_os_anime.h"
#include "assets/objects/object_boj/object_boj.h"
-#include "terminal.h"
#define FLAGS (ACTOR_FLAG_ATTENTION_ENABLED | ACTOR_FLAG_FRIENDLY | ACTOR_FLAG_UPDATE_CULLING_DISABLED)
diff --git a/src/overlays/actors/ovl_En_Guest/z_en_guest.h b/src/overlays/actors/ovl_En_Guest/z_en_guest.h
index 2130ebc74..92dbc72d5 100644
--- a/src/overlays/actors/ovl_En_Guest/z_en_guest.h
+++ b/src/overlays/actors/ovl_En_Guest/z_en_guest.h
@@ -2,11 +2,11 @@
#define Z_EN_GUEST_H
#include "ultra64.h"
-#include "global.h"
+#include "z64actor.h"
struct EnGuest;
-typedef void (*EnGuestActionFunc)(struct EnGuest* this, PlayState* play);
+typedef void (*EnGuestActionFunc)(struct EnGuest* this, struct PlayState* play);
typedef struct EnGuest {
/* 0x0000 */ Actor actor;
diff --git a/src/overlays/actors/ovl_En_Hata/z_en_hata.c b/src/overlays/actors/ovl_En_Hata/z_en_hata.c
index 6cdb51f59..27cd1341c 100644
--- a/src/overlays/actors/ovl_En_Hata/z_en_hata.c
+++ b/src/overlays/actors/ovl_En_Hata/z_en_hata.c
@@ -5,6 +5,15 @@
*/
#include "z_en_hata.h"
+
+#include "libc64/qrand.h"
+#include "gfx.h"
+#include "gfx_setupdl.h"
+#include "rand.h"
+#include "sys_matrix.h"
+#include "z_lib.h"
+#include "z64play.h"
+
#include "assets/objects/object_hata/object_hata.h"
#define FLAGS 0
diff --git a/src/overlays/actors/ovl_En_Hata/z_en_hata.h b/src/overlays/actors/ovl_En_Hata/z_en_hata.h
index e098bcaab..82f6ba1a8 100644
--- a/src/overlays/actors/ovl_En_Hata/z_en_hata.h
+++ b/src/overlays/actors/ovl_En_Hata/z_en_hata.h
@@ -2,7 +2,7 @@
#define Z_EN_HATA_H
#include "ultra64.h"
-#include "global.h"
+#include "z64actor.h"
typedef enum EnHataLimb {
diff --git a/src/overlays/actors/ovl_En_Heishi1/z_en_heishi1.c b/src/overlays/actors/ovl_En_Heishi1/z_en_heishi1.c
index 2202904dc..a598068b5 100644
--- a/src/overlays/actors/ovl_En_Heishi1/z_en_heishi1.c
+++ b/src/overlays/actors/ovl_En_Heishi1/z_en_heishi1.c
@@ -20,6 +20,7 @@
#include "z64effect.h"
#include "z64play.h"
#include "z64player.h"
+#include "z64save.h"
#include "assets/objects/object_sd/object_sd.h"
diff --git a/src/overlays/actors/ovl_En_Heishi2/z_en_heishi2.c b/src/overlays/actors/ovl_En_Heishi2/z_en_heishi2.c
index b31974f3b..d9428562f 100644
--- a/src/overlays/actors/ovl_En_Heishi2/z_en_heishi2.c
+++ b/src/overlays/actors/ovl_En_Heishi2/z_en_heishi2.c
@@ -4,13 +4,25 @@
* Description: Hyrulian Guards
*/
-#include "terminal.h"
#include "z_en_heishi2.h"
+#include "overlays/actors/ovl_Bg_Gate_Shutter/z_bg_gate_shutter.h"
+#include "overlays/actors/ovl_Bg_Spot15_Saku/z_bg_spot15_saku.h"
+#include "overlays/actors/ovl_En_Bom/z_en_bom.h"
+
+#include "gfx.h"
+#include "gfx_setupdl.h"
+#include "rand.h"
+#include "sfx.h"
+#include "sys_matrix.h"
+#include "terminal.h"
+#include "z_lib.h"
+#include "z64face_reaction.h"
+#include "z64play.h"
+#include "z64player.h"
+#include "z64save.h"
+
#include "assets/objects/object_sd/object_sd.h"
#include "assets/objects/object_link_child/object_link_child.h"
-#include "overlays/actors/ovl_Bg_Gate_Shutter/z_bg_gate_shutter.h"
-#include "overlays/actors/ovl_En_Bom/z_en_bom.h"
-#include "overlays/actors/ovl_Bg_Spot15_Saku/z_bg_spot15_saku.h"
#define FLAGS (ACTOR_FLAG_ATTENTION_ENABLED | ACTOR_FLAG_FRIENDLY)
diff --git a/src/overlays/actors/ovl_En_Heishi2/z_en_heishi2.h b/src/overlays/actors/ovl_En_Heishi2/z_en_heishi2.h
index b4f6ea5e7..3753012be 100644
--- a/src/overlays/actors/ovl_En_Heishi2/z_en_heishi2.h
+++ b/src/overlays/actors/ovl_En_Heishi2/z_en_heishi2.h
@@ -2,12 +2,12 @@
#define Z_EN_HEISHI2_H
#include "ultra64.h"
-#include "global.h"
+#include "z64actor.h"
struct EnHeishi2;
-typedef void (*EnHeishi2ActionFunc)(struct EnHeishi2*, PlayState*);
+typedef void (*EnHeishi2ActionFunc)(struct EnHeishi2*, struct PlayState*);
typedef struct EnHeishi2 {
/* 0x0000 */ Actor actor;
diff --git a/src/overlays/actors/ovl_En_Heishi3/z_en_heishi3.c b/src/overlays/actors/ovl_En_Heishi3/z_en_heishi3.c
index 8a10e8f96..91ccd4d51 100644
--- a/src/overlays/actors/ovl_En_Heishi3/z_en_heishi3.c
+++ b/src/overlays/actors/ovl_En_Heishi3/z_en_heishi3.c
@@ -5,9 +5,18 @@
*/
#include "z_en_heishi3.h"
-#include "assets/objects/object_sd/object_sd.h"
+
+#include "gfx.h"
+#include "gfx_setupdl.h"
+#include "sfx.h"
#include "terminal.h"
#include "versions.h"
+#include "z_lib.h"
+#include "z64play.h"
+#include "z64player.h"
+#include "z64save.h"
+
+#include "assets/objects/object_sd/object_sd.h"
#define FLAGS 0
diff --git a/src/overlays/actors/ovl_En_Heishi3/z_en_heishi3.h b/src/overlays/actors/ovl_En_Heishi3/z_en_heishi3.h
index 63b431139..57eb11c61 100644
--- a/src/overlays/actors/ovl_En_Heishi3/z_en_heishi3.h
+++ b/src/overlays/actors/ovl_En_Heishi3/z_en_heishi3.h
@@ -2,11 +2,11 @@
#define Z_EN_HEISHI3_H
#include "ultra64.h"
-#include "global.h"
+#include "z64actor.h"
struct EnHeishi3;
-typedef void (*EnHeishi3ActionFunc)(struct EnHeishi3*, PlayState*);
+typedef void (*EnHeishi3ActionFunc)(struct EnHeishi3*, struct PlayState*);
typedef struct EnHeishi3 {
/* 0x0000 */ Actor actor;
diff --git a/src/overlays/actors/ovl_En_Heishi4/z_en_heishi4.c b/src/overlays/actors/ovl_En_Heishi4/z_en_heishi4.c
index 51588714c..b139288ba 100644
--- a/src/overlays/actors/ovl_En_Heishi4/z_en_heishi4.c
+++ b/src/overlays/actors/ovl_En_Heishi4/z_en_heishi4.c
@@ -1,6 +1,14 @@
#include "z_en_heishi4.h"
-#include "assets/objects/object_sd/object_sd.h"
+
+#include "gfx.h"
+#include "gfx_setupdl.h"
#include "terminal.h"
+#include "z64face_reaction.h"
+#include "z64play.h"
+#include "z64player.h"
+#include "z64save.h"
+
+#include "assets/objects/object_sd/object_sd.h"
#define FLAGS (ACTOR_FLAG_ATTENTION_ENABLED | ACTOR_FLAG_FRIENDLY)
diff --git a/src/overlays/actors/ovl_En_Heishi4/z_en_heishi4.h b/src/overlays/actors/ovl_En_Heishi4/z_en_heishi4.h
index 48e09ca45..9ab928fe3 100644
--- a/src/overlays/actors/ovl_En_Heishi4/z_en_heishi4.h
+++ b/src/overlays/actors/ovl_En_Heishi4/z_en_heishi4.h
@@ -2,7 +2,7 @@
#define Z_EN_HEISHI4_H
#include "ultra64.h"
-#include "global.h"
+#include "z64actor.h"
typedef enum Heishi4Type {
/* 0x00 */ HEISHI4_AT_KAKARIKO_ENTRANCE,
@@ -13,7 +13,7 @@ typedef enum Heishi4Type {
struct EnHeishi4;
-typedef void (*EnHeishi4ActionFunc)(struct EnHeishi4*, PlayState*);
+typedef void (*EnHeishi4ActionFunc)(struct EnHeishi4*, struct PlayState*);
typedef struct EnHeishi4 {
/* 0x0000 */ Actor actor;
diff --git a/src/overlays/actors/ovl_En_Hintnuts/z_en_hintnuts.c b/src/overlays/actors/ovl_En_Hintnuts/z_en_hintnuts.c
index 541e8b851..454f83c2d 100644
--- a/src/overlays/actors/ovl_En_Hintnuts/z_en_hintnuts.c
+++ b/src/overlays/actors/ovl_En_Hintnuts/z_en_hintnuts.c
@@ -5,6 +5,13 @@
*/
#include "z_en_hintnuts.h"
+
+#include "ichain.h"
+#include "sfx.h"
+#include "sys_matrix.h"
+#include "z_lib.h"
+#include "z64play.h"
+
#include "assets/objects/object_hintnuts/object_hintnuts.h"
#define FLAGS (ACTOR_FLAG_ATTENTION_ENABLED | ACTOR_FLAG_HOSTILE)
@@ -78,8 +85,9 @@ void EnHintnuts_Init(Actor* thisx, PlayState* play) {
this->actor.flags &= ~(ACTOR_FLAG_ATTENTION_ENABLED | ACTOR_FLAG_HOSTILE);
} else {
ActorShape_Init(&this->actor.shape, 0x0, ActorShadow_DrawCircle, 35.0f);
- SkelAnime_Init(play, &this->skelAnime, &gHintNutsSkel, &gHintNutsStandAnim, this->jointTable, this->morphTable,
- 10);
+ //! @bug Flex skeleton is used as normal skeleton
+ SkelAnime_Init(play, &this->skelAnime, (SkeletonHeader*)&gHintNutsSkel, &gHintNutsStandAnim, this->jointTable,
+ this->morphTable, 10);
Collider_InitCylinder(play, &this->collider);
Collider_SetCylinder(play, &this->collider, &this->actor, &sCylinderInit);
CollisionCheck_SetInfo(&this->actor.colChkInfo, NULL, &sColChkInfoInit);
diff --git a/src/overlays/actors/ovl_En_Hintnuts/z_en_hintnuts.h b/src/overlays/actors/ovl_En_Hintnuts/z_en_hintnuts.h
index fcc020165..a24b387fe 100644
--- a/src/overlays/actors/ovl_En_Hintnuts/z_en_hintnuts.h
+++ b/src/overlays/actors/ovl_En_Hintnuts/z_en_hintnuts.h
@@ -2,11 +2,11 @@
#define Z_EN_HINTNUTS_H
#include "ultra64.h"
-#include "global.h"
+#include "z64actor.h"
struct EnHintnuts;
-typedef void (*EnHintnutsActionFunc)(struct EnHintnuts*, PlayState*);
+typedef void (*EnHintnutsActionFunc)(struct EnHintnuts*, struct PlayState*);
typedef struct EnHintnuts {
/* 0x0000 */ Actor actor;
diff --git a/src/overlays/actors/ovl_En_Holl/z_en_holl.c b/src/overlays/actors/ovl_En_Holl/z_en_holl.c
index 43710f7fb..37c5a087b 100644
--- a/src/overlays/actors/ovl_En_Holl/z_en_holl.c
+++ b/src/overlays/actors/ovl_En_Holl/z_en_holl.c
@@ -1,6 +1,15 @@
#include "z_en_holl.h"
#include "config.h"
+#include "gfx.h"
+#include "gfx_setupdl.h"
+#include "ichain.h"
+#include "sys_matrix.h"
+#include "z_lib.h"
+#include "z64play.h"
+#include "z64player.h"
+#include "z64save.h"
+
#define FLAGS ACTOR_FLAG_UPDATE_CULLING_DISABLED
/*
diff --git a/src/overlays/actors/ovl_En_Holl/z_en_holl.h b/src/overlays/actors/ovl_En_Holl/z_en_holl.h
index 2c87dc346..4a9409373 100644
--- a/src/overlays/actors/ovl_En_Holl/z_en_holl.h
+++ b/src/overlays/actors/ovl_En_Holl/z_en_holl.h
@@ -2,7 +2,7 @@
#define Z_EN_HOLL_H
#include "ultra64.h"
-#include "global.h"
+#include "z64actor.h"
#define ENHOLL_GET_TYPE(thisx) PARAMS_GET_U((thisx)->params, 6, 3)
#define ENHOLL_GET_SWITCH_FLAG(thisx) PARAMS_GET_U((thisx)->params, 0, 6)
@@ -35,7 +35,7 @@ typedef enum EnHollType {
struct EnHoll;
-typedef void (*EnHollActionFunc)(struct EnHoll*, PlayState*);
+typedef void (*EnHollActionFunc)(struct EnHoll*, struct PlayState*);
typedef struct EnHoll {
/* 0x0000 */ Actor actor;
diff --git a/src/overlays/actors/ovl_En_Horse/z_en_horse.c b/src/overlays/actors/ovl_En_Horse/z_en_horse.c
index 5429024c7..08f58dbce 100644
--- a/src/overlays/actors/ovl_En_Horse/z_en_horse.c
+++ b/src/overlays/actors/ovl_En_Horse/z_en_horse.c
@@ -27,10 +27,9 @@
#include "z64horse.h"
#include "z64play.h"
#include "z64player.h"
+#include "z64save.h"
#include "z64skin_matrix.h"
-#include "global.h"
-
#include "assets/objects/object_horse/object_horse.h"
#include "assets/objects/object_hni/object_hni.h"
#include "assets/scenes/overworld/spot09/spot09_scene.h"
@@ -143,7 +142,7 @@ static ColliderCylinderInit sCylinderInit2 = {
{ 20, 70, 0, { 0, 0, 0 } },
};
-static ColliderJntSphElementInit sJntSphItemsInit[1] = {
+static ColliderJntSphElementInit sJntSphElementsInit[1] = {
{
{
ELEM_MATERIAL_UNK0,
@@ -167,7 +166,7 @@ static ColliderJntSphInit sJntSphInit = {
COLSHAPE_JNTSPH,
},
1,
- sJntSphItemsInit,
+ sJntSphElementsInit,
};
static CollisionCheckInfoInit D_80A65F38 = { 10, 35, 100, MASS_HEAVY };
@@ -583,7 +582,7 @@ void EnHorse_UpdateIngoRaceInfo(EnHorse* this, PlayState* play, RaceInfo* raceIn
EnHorse_RotateToPoint(this, play, &curWaypointPos, 400);
if (distSq < SQ(300.0f)) {
- if (this->actor.xzDistToPlayer < 130.0f || this->jntSph.elements[0].base.ocElemFlags & OCELEM_HIT) {
+ if (this->actor.xzDistToPlayer < 130.0f || this->colliderJntSph.elements[0].base.ocElemFlags & OCELEM_HIT) {
s32 pad;
if (Math_SinS(this->actor.yawTowardsPlayer - this->actor.world.rot.y) > 0.0f) {
@@ -840,12 +839,12 @@ void EnHorse_Init(Actor* thisx, PlayState* play2) {
ActorShape_Init(&this->actor.shape, 0.0f, ActorShadow_DrawHorse, 20.0f);
this->action = ENHORSE_ACT_IDLE;
this->actor.speed = 0.0f;
- Collider_InitCylinder(play, &this->cyl1);
- Collider_SetCylinder(play, &this->cyl1, &this->actor, &sCylinderInit1);
- Collider_InitCylinder(play, &this->cyl2);
- Collider_SetCylinder(play, &this->cyl2, &this->actor, &sCylinderInit2);
- Collider_InitJntSph(play, &this->jntSph);
- Collider_SetJntSph(play, &this->jntSph, &this->actor, &sJntSphInit, &this->jntSphList);
+ Collider_InitCylinder(play, &this->colliderCylinder1);
+ Collider_SetCylinder(play, &this->colliderCylinder1, &this->actor, &sCylinderInit1);
+ Collider_InitCylinder(play, &this->colliderCylinder2);
+ Collider_SetCylinder(play, &this->colliderCylinder2, &this->actor, &sCylinderInit2);
+ Collider_InitJntSph(play, &this->colliderJntSph);
+ Collider_SetJntSph(play, &this->colliderJntSph, &this->actor, &sJntSphInit, this->colliderJntSphElements);
CollisionCheck_SetInfo(&this->actor.colChkInfo, DamageTable_Get(0xB), &D_80A65F38);
this->actor.focus.pos = this->actor.world.pos;
this->actor.focus.pos.y += 70.0f;
@@ -928,9 +927,9 @@ void EnHorse_Destroy(Actor* thisx, PlayState* play) {
Audio_StopSfxByPos(&this->unk_21C);
}
Skin_Free(play, &this->skin);
- Collider_DestroyCylinder(play, &this->cyl1);
- Collider_DestroyCylinder(play, &this->cyl2);
- Collider_DestroyJntSph(play, &this->jntSph);
+ Collider_DestroyCylinder(play, &this->colliderCylinder1);
+ Collider_DestroyCylinder(play, &this->colliderCylinder2);
+ Collider_DestroyJntSph(play, &this->colliderJntSph);
}
void EnHorse_RotateToPlayer(EnHorse* this, PlayState* play) {
@@ -949,9 +948,9 @@ void EnHorse_Freeze(EnHorse* this) {
}
this->prevAction = this->action;
this->action = ENHORSE_ACT_FROZEN;
- this->cyl1.base.ocFlags1 &= ~OC1_ON;
- this->cyl2.base.ocFlags1 &= ~OC1_ON;
- this->jntSph.base.ocFlags1 &= ~OC1_ON;
+ this->colliderCylinder1.base.ocFlags1 &= ~OC1_ON;
+ this->colliderCylinder2.base.ocFlags1 &= ~OC1_ON;
+ this->colliderJntSph.base.ocFlags1 &= ~OC1_ON;
this->animationIdx = ENHORSE_ANIM_IDLE;
}
}
@@ -965,9 +964,9 @@ void EnHorse_Frozen(EnHorse* this, PlayState* play) {
this->actor.speed = 0.0f;
this->noInputTimer--;
if (this->noInputTimer < 0) {
- this->cyl1.base.ocFlags1 |= OC1_ON;
- this->cyl2.base.ocFlags1 |= OC1_ON;
- this->jntSph.base.ocFlags1 |= OC1_ON;
+ this->colliderCylinder1.base.ocFlags1 |= OC1_ON;
+ this->colliderCylinder2.base.ocFlags1 |= OC1_ON;
+ this->colliderJntSph.base.ocFlags1 |= OC1_ON;
if (this->playerControlled == true) {
this->stateFlags &= ~ENHORSE_FLAG_7;
if (this->actor.params == HORSE_PTYPE_4) {
@@ -1750,9 +1749,9 @@ void EnHorse_HighJump(EnHorse* this, PlayState* play) {
}
void EnHorse_InitInactive(EnHorse* this) {
- this->cyl1.base.ocFlags1 &= ~OC1_ON;
- this->cyl2.base.ocFlags1 &= ~OC1_ON;
- this->jntSph.base.ocFlags1 &= ~OC1_ON;
+ this->colliderCylinder1.base.ocFlags1 &= ~OC1_ON;
+ this->colliderCylinder2.base.ocFlags1 &= ~OC1_ON;
+ this->colliderJntSph.base.ocFlags1 &= ~OC1_ON;
this->action = ENHORSE_ACT_INACTIVE;
this->animationIdx = ENHORSE_ANIM_WALK;
this->stateFlags |= ENHORSE_INACTIVE;
@@ -1784,9 +1783,9 @@ void EnHorse_Inactive(EnHorse* this, PlayState* play2) {
this->followTimer = 0;
EnHorse_SetFollowAnimation(this, play);
this->actor.params = HORSE_PTYPE_0;
- this->cyl1.base.ocFlags1 |= OC1_ON;
- this->cyl2.base.ocFlags1 |= OC1_ON;
- this->jntSph.base.ocFlags1 |= OC1_ON;
+ this->colliderCylinder1.base.ocFlags1 |= OC1_ON;
+ this->colliderCylinder2.base.ocFlags1 |= OC1_ON;
+ this->colliderJntSph.base.ocFlags1 |= OC1_ON;
}
}
@@ -3570,12 +3569,12 @@ void EnHorse_Update(Actor* thisx, PlayState* play2) {
this->rider->shape.rot.y = thisx->shape.rot.y;
}
}
- if (this->jntSph.elements[0].base.ocElemFlags & OCELEM_HIT) {
+ if (this->colliderJntSph.elements[0].base.ocElemFlags & OCELEM_HIT) {
if (thisx->speed > 6.0f) {
thisx->speed -= 1.0f;
}
}
- if (this->jntSph.base.acFlags & AC_HIT) {
+ if (this->colliderJntSph.base.acFlags & AC_HIT) {
this->unk_21C = this->unk_228;
if (this->stateFlags & ENHORSE_DRAW) {
Audio_PlaySfxGeneral(NA_SE_EV_HORSE_NEIGH, &this->unk_21C, 4, &gSfxDefaultFreqAndVolScale,
@@ -3585,17 +3584,21 @@ void EnHorse_Update(Actor* thisx, PlayState* play2) {
if (this->action != ENHORSE_ACT_INGO_RACE) {
EnHorse_TiltBody(this, play);
}
- Collider_UpdateCylinder(thisx, &this->cyl1);
- Collider_UpdateCylinder(thisx, &this->cyl2);
+ Collider_UpdateCylinder(thisx, &this->colliderCylinder1);
+ Collider_UpdateCylinder(thisx, &this->colliderCylinder2);
// Required to match
- this->cyl1.dim.pos.x = this->cyl1.dim.pos.x + (s16)(Math_SinS(thisx->shape.rot.y) * 11.0f);
- this->cyl1.dim.pos.z = this->cyl1.dim.pos.z + (s16)(Math_CosS(thisx->shape.rot.y) * 11.0f);
- this->cyl2.dim.pos.x = this->cyl2.dim.pos.x + (s16)(Math_SinS(thisx->shape.rot.y) * -18.0f);
- this->cyl2.dim.pos.z = this->cyl2.dim.pos.z + (s16)(Math_CosS(thisx->shape.rot.y) * -18.0f);
- CollisionCheck_SetAT(play, &play->colChkCtx, &this->cyl1.base);
- CollisionCheck_SetOC(play, &play->colChkCtx, &this->cyl1.base);
- CollisionCheck_SetOC(play, &play->colChkCtx, &this->cyl2.base);
+ this->colliderCylinder1.dim.pos.x =
+ this->colliderCylinder1.dim.pos.x + (s16)(Math_SinS(thisx->shape.rot.y) * 11.0f);
+ this->colliderCylinder1.dim.pos.z =
+ this->colliderCylinder1.dim.pos.z + (s16)(Math_CosS(thisx->shape.rot.y) * 11.0f);
+ this->colliderCylinder2.dim.pos.x =
+ this->colliderCylinder2.dim.pos.x + (s16)(Math_SinS(thisx->shape.rot.y) * -18.0f);
+ this->colliderCylinder2.dim.pos.z =
+ this->colliderCylinder2.dim.pos.z + (s16)(Math_CosS(thisx->shape.rot.y) * -18.0f);
+ CollisionCheck_SetAT(play, &play->colChkCtx, &this->colliderCylinder1.base);
+ CollisionCheck_SetOC(play, &play->colChkCtx, &this->colliderCylinder1.base);
+ CollisionCheck_SetOC(play, &play->colChkCtx, &this->colliderCylinder2.base);
if ((player->stateFlags1 & PLAYER_STATE1_0) && player->rideActor != NULL) {
if (play->sceneId != SCENE_LON_LON_RANCH ||
(play->sceneId == SCENE_LON_LON_RANCH && (thisx->world.pos.z < -2400.0f))) {
@@ -3639,9 +3642,9 @@ void EnHorse_Update(Actor* thisx, PlayState* play2) {
}
if (thisx->speed >= 5.0f) {
- this->cyl1.base.atFlags |= AT_ON;
+ this->colliderCylinder1.base.atFlags |= AT_ON;
} else {
- this->cyl1.base.atFlags &= ~AT_ON;
+ this->colliderCylinder1.base.atFlags &= ~AT_ON;
}
if (gSaveContext.save.entranceIndex != ENTR_LON_LON_RANCH_0 || gSaveContext.sceneLayer != 9) {
@@ -3836,17 +3839,17 @@ void EnHorse_PostDraw(Actor* thisx, PlayState* play, Skin* skin) {
}
}
- for (i = 0; i < this->jntSph.count; i++) {
- center.x = this->jntSph.elements[i].dim.modelSphere.center.x;
- center.y = this->jntSph.elements[i].dim.modelSphere.center.y;
- center.z = this->jntSph.elements[i].dim.modelSphere.center.z;
+ for (i = 0; i < this->colliderJntSph.count; i++) {
+ center.x = this->colliderJntSph.elements[i].dim.modelSphere.center.x;
+ center.y = this->colliderJntSph.elements[i].dim.modelSphere.center.y;
+ center.z = this->colliderJntSph.elements[i].dim.modelSphere.center.z;
- Skin_GetLimbPos(skin, this->jntSph.elements[i].dim.limb, ¢er, &newCenter);
- this->jntSph.elements[i].dim.worldSphere.center.x = newCenter.x;
- this->jntSph.elements[i].dim.worldSphere.center.y = newCenter.y;
- this->jntSph.elements[i].dim.worldSphere.center.z = newCenter.z;
- this->jntSph.elements[i].dim.worldSphere.radius =
- this->jntSph.elements[i].dim.modelSphere.radius * this->jntSph.elements[i].dim.scale;
+ Skin_GetLimbPos(skin, this->colliderJntSph.elements[i].dim.limb, ¢er, &newCenter);
+ this->colliderJntSph.elements[i].dim.worldSphere.center.x = newCenter.x;
+ this->colliderJntSph.elements[i].dim.worldSphere.center.y = newCenter.y;
+ this->colliderJntSph.elements[i].dim.worldSphere.center.z = newCenter.z;
+ this->colliderJntSph.elements[i].dim.worldSphere.radius =
+ this->colliderJntSph.elements[i].dim.modelSphere.radius * this->colliderJntSph.elements[i].dim.scale;
}
//! @bug Setting colliders in a draw function allows for duplicate entries to be added to their respective lists
@@ -3854,8 +3857,8 @@ void EnHorse_PostDraw(Actor* thisx, PlayState* play, Skin* skin) {
//! Actors will draw for a couple of frames between the pauses, but some important logic updates will not occur.
//! In the case of OC, this can cause unwanted effects such as a very large amount of displacement being applied to
//! a colliding actor.
- CollisionCheck_SetOC(play, &play->colChkCtx, &this->jntSph.base);
- CollisionCheck_SetAC(play, &play->colChkCtx, &this->jntSph.base);
+ CollisionCheck_SetOC(play, &play->colChkCtx, &this->colliderJntSph.base);
+ CollisionCheck_SetAC(play, &play->colChkCtx, &this->colliderJntSph.base);
}
// unused
diff --git a/src/overlays/actors/ovl_En_Horse/z_en_horse.h b/src/overlays/actors/ovl_En_Horse/z_en_horse.h
index 059cf6768..0eed5c001 100644
--- a/src/overlays/actors/ovl_En_Horse/z_en_horse.h
+++ b/src/overlays/actors/ovl_En_Horse/z_en_horse.h
@@ -140,10 +140,10 @@ typedef struct EnHorse {
/* 0x0264 */ Vec2f curStick;
/* 0x026C */ Vec2f lastStick;
/* 0x0274 */ f32 jumpStartY;
- /* 0x0278 */ ColliderCylinder cyl1;
- /* 0x02C4 */ ColliderCylinder cyl2;
- /* 0x0310 */ ColliderJntSph jntSph;
- /* 0x0330 */ ColliderJntSphElement jntSphList;
+ /* 0x0278 */ ColliderCylinder colliderCylinder1;
+ /* 0x02C4 */ ColliderCylinder colliderCylinder2;
+ /* 0x0310 */ ColliderJntSph colliderJntSph;
+ /* 0x0330 */ ColliderJntSphElement colliderJntSphElements[1];
/* 0x0370 */ u32 playerDir;
/* 0x0374 */ s16 unk_374;
/* 0x0376 */ s16 angleToPlayer;
diff --git a/src/overlays/actors/ovl_En_Horse_Game_Check/z_en_horse_game_check.c b/src/overlays/actors/ovl_En_Horse_Game_Check/z_en_horse_game_check.c
index 9675ab121..ac1ae2f42 100644
--- a/src/overlays/actors/ovl_En_Horse_Game_Check/z_en_horse_game_check.c
+++ b/src/overlays/actors/ovl_En_Horse_Game_Check/z_en_horse_game_check.c
@@ -6,8 +6,18 @@
#include "z_en_horse_game_check.h"
#include "overlays/actors/ovl_En_Horse/z_en_horse.h"
+
#include "libu64/debug.h"
#include "line_numbers.h"
+#include "regs.h"
+#include "sfx.h"
+#include "seqcmd.h"
+#include "sequence.h"
+#include "sys_math3d.h"
+#include "z_lib.h"
+#include "z64play.h"
+#include "z64player.h"
+#include "z64save.h"
#define FLAGS ACTOR_FLAG_UPDATE_CULLING_DISABLED
diff --git a/src/overlays/actors/ovl_En_Horse_Game_Check/z_en_horse_game_check.h b/src/overlays/actors/ovl_En_Horse_Game_Check/z_en_horse_game_check.h
index 96834860e..84ab11721 100644
--- a/src/overlays/actors/ovl_En_Horse_Game_Check/z_en_horse_game_check.h
+++ b/src/overlays/actors/ovl_En_Horse_Game_Check/z_en_horse_game_check.h
@@ -2,11 +2,11 @@
#define Z_EN_HORSE_GAME_CHECK_H
#include "ultra64.h"
-#include "global.h"
+#include "z64actor.h"
struct EnHorseGameCheckBase;
-typedef s32 (*EnHorseGameCheckFunc)(struct EnHorseGameCheckBase* this, PlayState* play);
+typedef s32 (*EnHorseGameCheckFunc)(struct EnHorseGameCheckBase* this, struct PlayState* play);
typedef struct EnHorseGameCheckBase {
/* 0x0000 */ Actor actor;
diff --git a/src/overlays/actors/ovl_En_Horse_Ganon/z_en_horse_ganon.c b/src/overlays/actors/ovl_En_Horse_Ganon/z_en_horse_ganon.c
index 0ce01f2d6..e1991688a 100644
--- a/src/overlays/actors/ovl_En_Horse_Ganon/z_en_horse_ganon.c
+++ b/src/overlays/actors/ovl_En_Horse_Ganon/z_en_horse_ganon.c
@@ -5,6 +5,18 @@
*/
#include "z_en_horse_ganon.h"
+
+#include "libc64/math64.h"
+#include "gfx.h"
+#include "gfx_setupdl.h"
+#include "ichain.h"
+#include "sfx.h"
+#include "sys_math3d.h"
+#include "z_lib.h"
+#include "z64play.h"
+#include "z64player.h"
+#include "z64skin.h"
+
#include "assets/objects/object_horse_ganon/object_horse_ganon.h"
#define FLAGS ACTOR_FLAG_UPDATE_CULLING_DISABLED
@@ -181,10 +193,10 @@ void EnHorseGanon_Init(Actor* thisx, PlayState* play) {
this->currentAnimation = 0;
Animation_PlayOnce(&this->skin.skelAnime, sAnimations[0]);
- Collider_InitCylinder(play, &this->colliderBody);
- Collider_SetCylinder(play, &this->colliderBody, &this->actor, &sCylinderInit);
- Collider_InitJntSph(play, &this->colliderHead);
- Collider_SetJntSph(play, &this->colliderHead, &this->actor, &sJntSphInit, this->headElements);
+ Collider_InitCylinder(play, &this->bodyCollider);
+ Collider_SetCylinder(play, &this->bodyCollider, &this->actor, &sCylinderInit);
+ Collider_InitJntSph(play, &this->headCollider);
+ Collider_SetJntSph(play, &this->headCollider, &this->actor, &sJntSphInit, this->headColliderElements);
CollisionCheck_SetInfo(&this->actor.colChkInfo, NULL, &sColChkInfoInit);
func_80A68AC4(this);
@@ -194,8 +206,8 @@ void EnHorseGanon_Destroy(Actor* thisx, PlayState* play) {
EnHorseGanon* this = (EnHorseGanon*)thisx;
Skin_Free(play, &this->skin);
- Collider_DestroyCylinder(play, &this->colliderBody);
- Collider_DestroyJntSph(play, &this->colliderHead);
+ Collider_DestroyCylinder(play, &this->bodyCollider);
+ Collider_DestroyJntSph(play, &this->headCollider);
}
void func_80A68AC4(EnHorseGanon* this) {
@@ -293,8 +305,8 @@ void EnHorseGanon_Update(Actor* thisx, PlayState* play) {
UPDBGCHECKINFO_FLAG_4);
this->actor.focus.pos = this->actor.world.pos;
this->actor.focus.pos.y += 70.0f;
- Collider_UpdateCylinder(&this->actor, &this->colliderBody);
- CollisionCheck_SetOC(play, &play->colChkCtx, &this->colliderBody.base);
+ Collider_UpdateCylinder(&this->actor, &this->bodyCollider);
+ CollisionCheck_SetOC(play, &play->colChkCtx, &this->bodyCollider.base);
}
void EnHorseGanon_PostDraw(Actor* thisx, PlayState* play, Skin* skin) {
@@ -303,23 +315,23 @@ void EnHorseGanon_PostDraw(Actor* thisx, PlayState* play, Skin* skin) {
EnHorseGanon* this = (EnHorseGanon*)thisx;
s32 index;
- for (index = 0; index < this->colliderHead.count; index++) {
- sp4C.x = this->colliderHead.elements[index].dim.modelSphere.center.x;
- sp4C.y = this->colliderHead.elements[index].dim.modelSphere.center.y;
- sp4C.z = this->colliderHead.elements[index].dim.modelSphere.center.z;
+ for (index = 0; index < this->headCollider.count; index++) {
+ sp4C.x = this->headCollider.elements[index].dim.modelSphere.center.x;
+ sp4C.y = this->headCollider.elements[index].dim.modelSphere.center.y;
+ sp4C.z = this->headCollider.elements[index].dim.modelSphere.center.z;
- Skin_GetLimbPos(skin, this->colliderHead.elements[index].dim.limb, &sp4C, &sp40);
+ Skin_GetLimbPos(skin, this->headCollider.elements[index].dim.limb, &sp4C, &sp40);
- this->colliderHead.elements[index].dim.worldSphere.center.x = sp40.x;
- this->colliderHead.elements[index].dim.worldSphere.center.y = sp40.y;
- this->colliderHead.elements[index].dim.worldSphere.center.z = sp40.z;
+ this->headCollider.elements[index].dim.worldSphere.center.x = sp40.x;
+ this->headCollider.elements[index].dim.worldSphere.center.y = sp40.y;
+ this->headCollider.elements[index].dim.worldSphere.center.z = sp40.z;
- this->colliderHead.elements[index].dim.worldSphere.radius =
- this->colliderHead.elements[index].dim.modelSphere.radius * this->colliderHead.elements[index].dim.scale;
+ this->headCollider.elements[index].dim.worldSphere.radius =
+ this->headCollider.elements[index].dim.modelSphere.radius * this->headCollider.elements[index].dim.scale;
}
//! @bug see relevant comment in `EnHorse_SkinCallback1`
- CollisionCheck_SetOC(play, &play->colChkCtx, &this->colliderHead.base);
+ CollisionCheck_SetOC(play, &play->colChkCtx, &this->headCollider.base);
}
void EnHorseGanon_Draw(Actor* thisx, PlayState* play) {
diff --git a/src/overlays/actors/ovl_En_Horse_Ganon/z_en_horse_ganon.h b/src/overlays/actors/ovl_En_Horse_Ganon/z_en_horse_ganon.h
index 8083adeee..473f6cecb 100644
--- a/src/overlays/actors/ovl_En_Horse_Ganon/z_en_horse_ganon.h
+++ b/src/overlays/actors/ovl_En_Horse_Ganon/z_en_horse_ganon.h
@@ -2,11 +2,12 @@
#define Z_EN_HORSE_GANON_H
#include "ultra64.h"
-#include "global.h"
+#include "z64actor.h"
+#include "z64skin.h"
struct EnHorseGanon;
-typedef void (*EnHorseGanonActionFunc)(struct EnHorseGanon*, PlayState*);
+typedef void (*EnHorseGanonActionFunc)(struct EnHorseGanon*, struct PlayState*);
typedef struct EnHorseGanon {
/* 0x0000 */ Actor actor;
@@ -19,9 +20,9 @@ typedef struct EnHorseGanon {
/* 0x01F0 */ u8 unk_1F0[0x04];
/* 0x01F4 */ f32 unk_1F4;
/* 0x01F8 */ u8 unk_1F8[0x04];
- /* 0x01FC */ ColliderCylinder colliderBody;
- /* 0x0248 */ ColliderJntSph colliderHead;
- /* 0x0268 */ ColliderJntSphElement headElements[1];
+ /* 0x01FC */ ColliderCylinder bodyCollider;
+ /* 0x0248 */ ColliderJntSph headCollider;
+ /* 0x0268 */ ColliderJntSphElement headColliderElements[1];
} EnHorseGanon; // size = 0x02A8
#endif
diff --git a/src/overlays/actors/ovl_En_Horse_Link_Child/z_en_horse_link_child.c b/src/overlays/actors/ovl_En_Horse_Link_Child/z_en_horse_link_child.c
index 755916a39..7a3307bc0 100644
--- a/src/overlays/actors/ovl_En_Horse_Link_Child/z_en_horse_link_child.c
+++ b/src/overlays/actors/ovl_En_Horse_Link_Child/z_en_horse_link_child.c
@@ -4,18 +4,24 @@
* Description: Young Epona
*/
-#include "global.h"
+#include "z_en_horse_link_child.h"
+
#include "gfx.h"
#include "gfx_setupdl.h"
#include "ichain.h"
#include "rand.h"
#include "regs.h"
+#include "segmented_address.h"
#include "sfx.h"
+#include "sys_math3d.h"
+#include "z_lib.h"
#include "z64actor.h"
#include "z64horse.h"
#include "z64player.h"
#include "z64play.h"
-#include "z_en_horse_link_child.h"
+#include "z64save.h"
+#include "z64skin.h"
+
#include "assets/objects/object_horse_link_child/object_horse_link_child.h"
#define FLAGS (ACTOR_FLAG_UPDATE_CULLING_DISABLED | ACTOR_FLAG_UPDATE_DURING_OCARINA)
@@ -66,7 +72,7 @@ static ColliderCylinderInitType1 sCylinderInit = {
{ 20, 100, 0, { 0, 0, 0 } },
};
-static ColliderJntSphElementInit sJntSphElementInit[1] = {
+static ColliderJntSphElementInit sJntSphElementsInit[1] = {
{
{
ELEM_MATERIAL_UNK0,
@@ -90,7 +96,7 @@ static ColliderJntSphInit sJntSphInit = {
COLSHAPE_JNTSPH,
},
1,
- sJntSphElementInit,
+ sJntSphElementsInit,
};
static CollisionCheckInfoInit sColCheckInfoInit = { 10, 35, 100, MASS_HEAVY };
@@ -168,7 +174,7 @@ void EnHorseLinkChild_Init(Actor* thisx, PlayState* play) {
Collider_InitCylinder(play, &this->bodyCollider);
Collider_SetCylinderType1(play, &this->bodyCollider, &this->actor, &sCylinderInit);
Collider_InitJntSph(play, &this->headCollider);
- Collider_SetJntSph(play, &this->headCollider, &this->actor, &sJntSphInit, this->headElements);
+ Collider_SetJntSph(play, &this->headCollider, &this->actor, &sJntSphInit, this->headColliderElements);
CollisionCheck_SetInfo(&this->actor.colChkInfo, NULL, &sColCheckInfoInit);
this->unk_1F0 = 0;
this->eyeTexIndex = 0;
diff --git a/src/overlays/actors/ovl_En_Horse_Link_Child/z_en_horse_link_child.h b/src/overlays/actors/ovl_En_Horse_Link_Child/z_en_horse_link_child.h
index 3ad5a449a..a4e9b512d 100644
--- a/src/overlays/actors/ovl_En_Horse_Link_Child/z_en_horse_link_child.h
+++ b/src/overlays/actors/ovl_En_Horse_Link_Child/z_en_horse_link_child.h
@@ -20,7 +20,7 @@ typedef struct EnHorseLinkChild {
/* 0x01F0 */ s32 unk_1F0;
/* 0x01F4 */ ColliderCylinder bodyCollider;
/* 0x0240 */ ColliderJntSph headCollider;
- /* 0x0260 */ ColliderJntSphElement headElements[1];
+ /* 0x0260 */ ColliderJntSphElement headColliderElements[1];
/* 0x02A0 */ s32 unk_2A0;
} EnHorseLinkChild; // size = 0x02A4
diff --git a/src/overlays/actors/ovl_En_Horse_Normal/z_en_horse_normal.c b/src/overlays/actors/ovl_En_Horse_Normal/z_en_horse_normal.c
index 7764f3d02..1ddc46944 100644
--- a/src/overlays/actors/ovl_En_Horse_Normal/z_en_horse_normal.c
+++ b/src/overlays/actors/ovl_En_Horse_Normal/z_en_horse_normal.c
@@ -5,6 +5,22 @@
*/
#include "z_en_horse_normal.h"
+
+#include "libc64/math64.h"
+#include "libc64/qrand.h"
+#include "gfx.h"
+#include "gfx_setupdl.h"
+#include "ichain.h"
+#include "regs.h"
+#include "segmented_address.h"
+#include "sfx.h"
+#include "sys_matrix.h"
+#include "z_lib.h"
+#include "z64play.h"
+#include "z64save.h"
+#include "z64skin.h"
+#include "z64skin_matrix.h"
+
#include "assets/objects/gameplay_keep/gameplay_keep.h"
#include "assets/objects/object_horse_normal/object_horse_normal.h"
@@ -197,7 +213,7 @@ void EnHorseNormal_Init(Actor* thisx, PlayState* play) {
Collider_InitCylinder(play, &this->bodyCollider);
Collider_SetCylinder(play, &this->bodyCollider, &this->actor, &sCylinderInit1);
Collider_InitJntSph(play, &this->headCollider);
- Collider_SetJntSph(play, &this->headCollider, &this->actor, &sJntSphInit, this->headElements);
+ Collider_SetJntSph(play, &this->headCollider, &this->actor, &sJntSphInit, this->headColliderElements);
Collider_InitCylinder(play, &this->cloneCollider);
Collider_SetCylinder(play, &this->cloneCollider, &this->actor, &sCylinderInit2);
CollisionCheck_SetInfo(&this->actor.colChkInfo, NULL, &sColChkInfoInit);
diff --git a/src/overlays/actors/ovl_En_Horse_Normal/z_en_horse_normal.h b/src/overlays/actors/ovl_En_Horse_Normal/z_en_horse_normal.h
index f9445eb18..01ddd4460 100644
--- a/src/overlays/actors/ovl_En_Horse_Normal/z_en_horse_normal.h
+++ b/src/overlays/actors/ovl_En_Horse_Normal/z_en_horse_normal.h
@@ -2,11 +2,12 @@
#define Z_EN_HORSE_NORMAL_H
#include "ultra64.h"
-#include "global.h"
+#include "z64actor.h"
+#include "z64skin.h"
struct EnHorseNormal;
-typedef void (*EnHorseNormalActionFunc)(struct EnHorseNormal*, PlayState*);
+typedef void (*EnHorseNormalActionFunc)(struct EnHorseNormal*, struct PlayState*);
typedef struct EnHorseNormal {
/* 0x0000 */ Actor actor;
@@ -26,7 +27,7 @@ typedef struct EnHorseNormal {
/* 0x0224 */ char unk_224[0x04];
/* 0x0228 */ ColliderCylinder bodyCollider;
/* 0x0274 */ ColliderJntSph headCollider;
- /* 0x0294 */ ColliderJntSphElement headElements[1];
+ /* 0x0294 */ ColliderJntSphElement headColliderElements[1];
/* 0x02D4 */ ColliderCylinder cloneCollider;
/* 0x0320 */ char unk_320[0x04];
/* 0x0324 */ s32 waypoint;
diff --git a/src/overlays/actors/ovl_En_Horse_Zelda/z_en_horse_zelda.c b/src/overlays/actors/ovl_En_Horse_Zelda/z_en_horse_zelda.c
index 04b7b1933..059f88c3a 100644
--- a/src/overlays/actors/ovl_En_Horse_Zelda/z_en_horse_zelda.c
+++ b/src/overlays/actors/ovl_En_Horse_Zelda/z_en_horse_zelda.c
@@ -5,6 +5,17 @@
*/
#include "z_en_horse_zelda.h"
+
+#include "libc64/math64.h"
+#include "gfx.h"
+#include "gfx_setupdl.h"
+#include "ichain.h"
+#include "sfx.h"
+#include "sys_math3d.h"
+#include "z_lib.h"
+#include "z64play.h"
+#include "z64player.h"
+
#include "assets/objects/object_horse_zelda/object_horse_zelda.h"
#define FLAGS ACTOR_FLAG_UPDATE_CULLING_DISABLED
@@ -163,8 +174,8 @@ void EnHorseZelda_Init(Actor* thisx, PlayState* play) {
Animation_PlayOnce(&this->skin.skelAnime, sAnimationHeaders[0]);
Collider_InitCylinder(play, &this->colliderCylinder);
Collider_SetCylinderType1(play, &this->colliderCylinder, &this->actor, &sCylinderInit);
- Collider_InitJntSph(play, &this->colliderSphere);
- Collider_SetJntSph(play, &this->colliderSphere, &this->actor, &sJntSphInit, &this->colliderSphereItem);
+ Collider_InitJntSph(play, &this->colliderJntSph);
+ Collider_SetJntSph(play, &this->colliderJntSph, &this->actor, &sJntSphInit, this->colliderJntSphElements);
CollisionCheck_SetInfo(&this->actor.colChkInfo, NULL, &sColChkInfoInit);
this->animationIndex = 0;
EnHorseZelda_SetupStop(this);
@@ -174,7 +185,7 @@ void EnHorseZelda_Destroy(Actor* thisx, PlayState* play) {
EnHorseZelda* this = (EnHorseZelda*)thisx;
Collider_DestroyCylinder(play, &this->colliderCylinder);
- Collider_DestroyJntSph(play, &this->colliderSphere);
+ Collider_DestroyJntSph(play, &this->colliderJntSph);
Skin_Free(play, &this->skin);
}
@@ -250,23 +261,23 @@ void EnHorseZelda_PostDraw(Actor* thisx, PlayState* play, Skin* skin) {
EnHorseZelda* this = (EnHorseZelda*)thisx;
s32 i;
- for (i = 0; i < this->colliderSphere.count; i++) {
- offset.x = this->colliderSphere.elements[i].dim.modelSphere.center.x;
- offset.y = this->colliderSphere.elements[i].dim.modelSphere.center.y;
- offset.z = this->colliderSphere.elements[i].dim.modelSphere.center.z;
+ for (i = 0; i < this->colliderJntSph.count; i++) {
+ offset.x = this->colliderJntSph.elements[i].dim.modelSphere.center.x;
+ offset.y = this->colliderJntSph.elements[i].dim.modelSphere.center.y;
+ offset.z = this->colliderJntSph.elements[i].dim.modelSphere.center.z;
- Skin_GetLimbPos(skin, this->colliderSphere.elements[i].dim.limb, &offset, &dst);
+ Skin_GetLimbPos(skin, this->colliderJntSph.elements[i].dim.limb, &offset, &dst);
- this->colliderSphere.elements[i].dim.worldSphere.center.x = dst.x;
- this->colliderSphere.elements[i].dim.worldSphere.center.y = dst.y;
- this->colliderSphere.elements[i].dim.worldSphere.center.z = dst.z;
+ this->colliderJntSph.elements[i].dim.worldSphere.center.x = dst.x;
+ this->colliderJntSph.elements[i].dim.worldSphere.center.y = dst.y;
+ this->colliderJntSph.elements[i].dim.worldSphere.center.z = dst.z;
- this->colliderSphere.elements[i].dim.worldSphere.radius =
- this->colliderSphere.elements[i].dim.modelSphere.radius * this->colliderSphere.elements[i].dim.scale;
+ this->colliderJntSph.elements[i].dim.worldSphere.radius =
+ this->colliderJntSph.elements[i].dim.modelSphere.radius * this->colliderJntSph.elements[i].dim.scale;
}
//! @bug see relevant comment in `EnHorse_SkinCallback1`
- CollisionCheck_SetOC(play, &play->colChkCtx, &this->colliderSphere.base);
+ CollisionCheck_SetOC(play, &play->colChkCtx, &this->colliderJntSph.base);
}
void EnHorseZelda_Draw(Actor* thisx, PlayState* play) {
diff --git a/src/overlays/actors/ovl_En_Horse_Zelda/z_en_horse_zelda.h b/src/overlays/actors/ovl_En_Horse_Zelda/z_en_horse_zelda.h
index 7ce6cace3..86b851c77 100644
--- a/src/overlays/actors/ovl_En_Horse_Zelda/z_en_horse_zelda.h
+++ b/src/overlays/actors/ovl_En_Horse_Zelda/z_en_horse_zelda.h
@@ -2,11 +2,12 @@
#define Z_EN_HORSE_ZELDA_H
#include "ultra64.h"
-#include "global.h"
+#include "z64actor.h"
+#include "z64skin.h"
struct EnHorseZelda;
-typedef void (*EnHorseZeldaActionFunc)(struct EnHorseZelda*, PlayState*);
+typedef void (*EnHorseZeldaActionFunc)(struct EnHorseZelda*, struct PlayState*);
typedef struct EnHorseZelda {
/* 0x0000 */ Actor actor;
@@ -19,8 +20,8 @@ typedef struct EnHorseZelda {
/* 0x01F4 */ f32 floorYForwards;
/* 0x01F8 */ char unk_1F8[0x4];
/* 0x01FC */ ColliderCylinder colliderCylinder;
- /* 0x0248 */ ColliderJntSph colliderSphere;
- /* 0x0268 */ ColliderJntSphElement colliderSphereItem;
+ /* 0x0248 */ ColliderJntSph colliderJntSph;
+ /* 0x0268 */ ColliderJntSphElement colliderJntSphElements[1];
} EnHorseZelda; // size = 0x02A8
#endif
diff --git a/src/overlays/actors/ovl_En_Hs/z_en_hs.c b/src/overlays/actors/ovl_En_Hs/z_en_hs.c
index 66d12bafb..88a548a41 100644
--- a/src/overlays/actors/ovl_En_Hs/z_en_hs.c
+++ b/src/overlays/actors/ovl_En_Hs/z_en_hs.c
@@ -5,7 +5,17 @@
*/
#include "z_en_hs.h"
+
+#include "gfx.h"
+#include "gfx_setupdl.h"
+#include "sfx.h"
+#include "sys_matrix.h"
#include "terminal.h"
+#include "z_lib.h"
+#include "z64play.h"
+#include "z64player.h"
+#include "z64save.h"
+
#include "assets/objects/object_hs/object_hs.h"
#define FLAGS (ACTOR_FLAG_ATTENTION_ENABLED | ACTOR_FLAG_FRIENDLY)
diff --git a/src/overlays/actors/ovl_En_Hs/z_en_hs.h b/src/overlays/actors/ovl_En_Hs/z_en_hs.h
index f4b89ce15..f938b5151 100644
--- a/src/overlays/actors/ovl_En_Hs/z_en_hs.h
+++ b/src/overlays/actors/ovl_En_Hs/z_en_hs.h
@@ -2,11 +2,11 @@
#define Z_EN_HS_H
#include "ultra64.h"
-#include "global.h"
+#include "z64actor.h"
struct EnHs;
-typedef void (*EnHsActionFunc)(struct EnHs*, PlayState*);
+typedef void (*EnHsActionFunc)(struct EnHs*, struct PlayState*);
typedef struct EnHs {
/* 0x0000 */ Actor actor;
diff --git a/src/overlays/actors/ovl_En_Hs2/z_en_hs2.c b/src/overlays/actors/ovl_En_Hs2/z_en_hs2.c
index b1b04107f..4914be17e 100644
--- a/src/overlays/actors/ovl_En_Hs2/z_en_hs2.c
+++ b/src/overlays/actors/ovl_En_Hs2/z_en_hs2.c
@@ -5,7 +5,15 @@
*/
#include "z_en_hs2.h"
+
+#include "gfx.h"
+#include "gfx_setupdl.h"
+#include "sys_matrix.h"
#include "terminal.h"
+#include "z_lib.h"
+#include "z64face_reaction.h"
+#include "z64play.h"
+
#include "assets/objects/object_hs/object_hs.h"
#define FLAGS (ACTOR_FLAG_ATTENTION_ENABLED | ACTOR_FLAG_FRIENDLY)
diff --git a/src/overlays/actors/ovl_En_Hs2/z_en_hs2.h b/src/overlays/actors/ovl_En_Hs2/z_en_hs2.h
index e2f66f79c..dec1533f8 100644
--- a/src/overlays/actors/ovl_En_Hs2/z_en_hs2.h
+++ b/src/overlays/actors/ovl_En_Hs2/z_en_hs2.h
@@ -2,11 +2,11 @@
#define Z_EN_HS2_H
#include "ultra64.h"
-#include "global.h"
+#include "z64actor.h"
struct EnHs2;
-typedef void (*EnHs2ActionFunc)(struct EnHs2*, PlayState*);
+typedef void (*EnHs2ActionFunc)(struct EnHs2*, struct PlayState*);
typedef struct EnHs2 {
/* 0x0000 */ Actor actor;
diff --git a/src/overlays/actors/ovl_En_Hy/z_en_hy.c b/src/overlays/actors/ovl_En_Hy/z_en_hy.c
index 2aa163d0f..3af23db48 100644
--- a/src/overlays/actors/ovl_En_Hy/z_en_hy.c
+++ b/src/overlays/actors/ovl_En_Hy/z_en_hy.c
@@ -5,7 +5,22 @@
*/
#include "z_en_hy.h"
+
+#include "attributes.h"
+#include "gfx.h"
+#include "gfx_setupdl.h"
+#include "segmented_address.h"
+#include "sequence.h"
+#include "sfx.h"
+#include "sys_matrix.h"
#include "versions.h"
+#include "z_lib.h"
+#include "z64audio.h"
+#include "z64face_reaction.h"
+#include "z64play.h"
+#include "z64player.h"
+#include "z64save.h"
+
#include "assets/objects/object_aob/object_aob.h"
#include "assets/objects/object_ahg/object_ahg.h"
#include "assets/objects/object_bob/object_bob.h"
diff --git a/src/overlays/actors/ovl_En_Hy/z_en_hy.h b/src/overlays/actors/ovl_En_Hy/z_en_hy.h
index a5c04ed3a..50bdc9093 100644
--- a/src/overlays/actors/ovl_En_Hy/z_en_hy.h
+++ b/src/overlays/actors/ovl_En_Hy/z_en_hy.h
@@ -2,7 +2,7 @@
#define Z_EN_HY_H
#include "ultra64.h"
-#include "global.h"
+#include "z64actor.h"
#define ENHY_GET_TYPE(thisx) PARAMS_GET_S((thisx)->params, 0, 7)
#define ENHY_GET_PATH_INDEX(thisx) PARAMS_GET_S((thisx)->params, 7, 4)
@@ -54,7 +54,7 @@ typedef enum EnHyLimb {
struct EnHy;
-typedef void (*EnHyActionFunc)(struct EnHy*, PlayState*);
+typedef void (*EnHyActionFunc)(struct EnHy*, struct PlayState*);
typedef struct EnHy {
/* 0x0000 */ Actor actor;
@@ -68,7 +68,7 @@ typedef struct EnHy {
/* 0x0199 */ s8 objectSlotOsAnime;
/* 0x019C */ ColliderCylinder collider;
/* 0x01E8 */ NpcInteractInfo interactInfo;
- /* 0x0210 */ Path* path;
+ /* 0x0210 */ struct Path* path;
/* 0x0214 */ s8 waypoint;
/* 0x0215 */ s8 playedSfx;
/* 0x0216 */ char unk_216[2]; // unused
diff --git a/src/overlays/actors/ovl_En_Ice_Hono/z_en_ice_hono.c b/src/overlays/actors/ovl_En_Ice_Hono/z_en_ice_hono.c
index a0fc6e7bd..4c230f210 100644
--- a/src/overlays/actors/ovl_En_Ice_Hono/z_en_ice_hono.c
+++ b/src/overlays/actors/ovl_En_Ice_Hono/z_en_ice_hono.c
@@ -5,6 +5,19 @@
*/
#include "z_en_ice_hono.h"
+
+#include "libc64/qrand.h"
+#include "gfx.h"
+#include "gfx_setupdl.h"
+#include "ichain.h"
+#include "sfx.h"
+#include "sys_matrix.h"
+#include "z_lib.h"
+#include "z64item.h"
+#include "z64light.h"
+#include "z64play.h"
+#include "z64player.h"
+
#include "assets/objects/gameplay_keep/gameplay_keep.h"
#define FLAGS 0
diff --git a/src/overlays/actors/ovl_En_Ice_Hono/z_en_ice_hono.h b/src/overlays/actors/ovl_En_Ice_Hono/z_en_ice_hono.h
index e5ad5fd1c..ea975199a 100644
--- a/src/overlays/actors/ovl_En_Ice_Hono/z_en_ice_hono.h
+++ b/src/overlays/actors/ovl_En_Ice_Hono/z_en_ice_hono.h
@@ -2,11 +2,12 @@
#define Z_EN_ICE_HONO_H
#include "ultra64.h"
-#include "global.h"
+#include "z64actor.h"
+#include "z64light.h"
struct EnIceHono;
-typedef void (*EnIceHonoActionFunc)(struct EnIceHono*, PlayState*);
+typedef void (*EnIceHonoActionFunc)(struct EnIceHono*, struct PlayState*);
typedef struct EnIceHono {
/* 0x0000 */ Actor actor;
diff --git a/src/overlays/actors/ovl_En_Ik/z_en_ik.c b/src/overlays/actors/ovl_En_Ik/z_en_ik.c
index e6e2d0924..61573e535 100644
--- a/src/overlays/actors/ovl_En_Ik/z_en_ik.c
+++ b/src/overlays/actors/ovl_En_Ik/z_en_ik.c
@@ -22,6 +22,7 @@
#include "z64effect.h"
#include "z64play.h"
#include "z64player.h"
+#include "z64save.h"
#include "z64skin_matrix.h"
#include "assets/scenes/dungeons/jyasinboss/jyasinboss_scene.h"
diff --git a/src/overlays/actors/ovl_En_In/z_en_in.c b/src/overlays/actors/ovl_En_In/z_en_in.c
index 333550942..fec848723 100644
--- a/src/overlays/actors/ovl_En_In/z_en_in.c
+++ b/src/overlays/actors/ovl_En_In/z_en_in.c
@@ -13,10 +13,10 @@
#include "versions.h"
#include "z_lib.h"
#include "z64audio.h"
+#include "z64face_reaction.h"
#include "z64play.h"
#include "z64player.h"
-
-#include "global.h"
+#include "z64save.h"
#include "assets/objects/object_in/object_in.h"
diff --git a/src/overlays/actors/ovl_En_Insect/z_en_insect.c b/src/overlays/actors/ovl_En_Insect/z_en_insect.c
index 51ad0b9b3..9135ccd11 100644
--- a/src/overlays/actors/ovl_En_Insect/z_en_insect.c
+++ b/src/overlays/actors/ovl_En_Insect/z_en_insect.c
@@ -18,6 +18,7 @@
#include "z64effect.h"
#include "z64play.h"
#include "z64player.h"
+#include "z64save.h"
#include "assets/objects/gameplay_keep/gameplay_keep.h"
@@ -67,7 +68,7 @@ ActorProfile En_Insect_Profile = {
/**/ EnInsect_Draw,
};
-static ColliderJntSphElementInit sColliderItemInit[1] = {
+static ColliderJntSphElementInit sColliderElementsInit[1] = {
{
{
ELEM_MATERIAL_UNK0,
@@ -91,7 +92,7 @@ static ColliderJntSphInit sColliderInit = {
COLSHAPE_JNTSPH,
},
1,
- sColliderItemInit,
+ sColliderElementsInit,
};
/**
@@ -204,7 +205,7 @@ void EnInsect_Init(Actor* thisx, PlayState* play2) {
SkelAnime_Init(play, &this->skelAnime, &gBugSkel, &gBugCrawlAnim, this->jointTable, this->morphTable, 24);
Collider_InitJntSph(play, &this->collider);
- Collider_SetJntSph(play, &this->collider, &this->actor, &sColliderInit, &this->colliderItem);
+ Collider_SetJntSph(play, &this->collider, &this->actor, &sColliderInit, this->colliderElements);
this->actor.colChkInfo.mass = 30;
diff --git a/src/overlays/actors/ovl_En_Insect/z_en_insect.h b/src/overlays/actors/ovl_En_Insect/z_en_insect.h
index 733758935..7bf443a2e 100644
--- a/src/overlays/actors/ovl_En_Insect/z_en_insect.h
+++ b/src/overlays/actors/ovl_En_Insect/z_en_insect.h
@@ -21,7 +21,7 @@ typedef void (*EnInsectActionFunc)(struct EnInsect*, struct PlayState*);
typedef struct EnInsect {
/* 0x0000 */ Actor actor;
/* 0x014C */ ColliderJntSph collider;
- /* 0x016C */ ColliderJntSphElement colliderItem;
+ /* 0x016C */ ColliderJntSphElement colliderElements[1];
/* 0x01AC */ SkelAnime skelAnime;
/* 0x01F0 */ Vec3s jointTable[24];
/* 0x0280 */ Vec3s morphTable[24];
diff --git a/src/overlays/actors/ovl_En_Ishi/z_en_ishi.c b/src/overlays/actors/ovl_En_Ishi/z_en_ishi.c
index 9bc210414..6f0531a6c 100644
--- a/src/overlays/actors/ovl_En_Ishi/z_en_ishi.c
+++ b/src/overlays/actors/ovl_En_Ishi/z_en_ishi.c
@@ -21,6 +21,7 @@
#include "z_en_item00.h"
#include "z_lib.h"
#include "z64effect.h"
+#include "z64item.h"
#include "z64play.h"
#include "assets/objects/gameplay_field_keep/gameplay_field_keep.h"
diff --git a/src/overlays/actors/ovl_En_It/z_en_it.c b/src/overlays/actors/ovl_En_It/z_en_it.c
index 312ceec96..975fe8411 100644
--- a/src/overlays/actors/ovl_En_It/z_en_it.c
+++ b/src/overlays/actors/ovl_En_It/z_en_it.c
@@ -6,6 +6,8 @@
#include "z_en_it.h"
+#include "z64play.h"
+
#define FLAGS 0
void EnIt_Init(Actor* thisx, PlayState* play);
diff --git a/src/overlays/actors/ovl_En_It/z_en_it.h b/src/overlays/actors/ovl_En_It/z_en_it.h
index fb150fcb0..9f1f794e4 100644
--- a/src/overlays/actors/ovl_En_It/z_en_it.h
+++ b/src/overlays/actors/ovl_En_It/z_en_it.h
@@ -2,7 +2,7 @@
#define Z_EN_IT_H
#include "ultra64.h"
-#include "global.h"
+#include "z64actor.h"
struct EnIt;
diff --git a/src/overlays/actors/ovl_En_Jj/z_en_jj.c b/src/overlays/actors/ovl_En_Jj/z_en_jj.c
index a03c20c9e..3f6b3c587 100644
--- a/src/overlays/actors/ovl_En_Jj/z_en_jj.c
+++ b/src/overlays/actors/ovl_En_Jj/z_en_jj.c
@@ -5,9 +5,21 @@
*/
#include "z_en_jj.h"
-#include "assets/objects/object_jj/object_jj.h"
#include "overlays/actors/ovl_Eff_Dust/z_eff_dust.h"
+#include "gfx.h"
+#include "gfx_setupdl.h"
+#include "ichain.h"
+#include "segmented_address.h"
+#include "sfx.h"
+#include "sys_matrix.h"
+#include "z_lib.h"
+#include "z64play.h"
+#include "z64player.h"
+#include "z64save.h"
+
+#include "assets/objects/object_jj/object_jj.h"
+
#define FLAGS (ACTOR_FLAG_UPDATE_CULLING_DISABLED | ACTOR_FLAG_DRAW_CULLING_DISABLED)
typedef enum EnJjEyeState {
diff --git a/src/overlays/actors/ovl_En_Jj/z_en_jj.h b/src/overlays/actors/ovl_En_Jj/z_en_jj.h
index c5d624120..9ac2df8bb 100644
--- a/src/overlays/actors/ovl_En_Jj/z_en_jj.h
+++ b/src/overlays/actors/ovl_En_Jj/z_en_jj.h
@@ -2,11 +2,11 @@
#define Z_EN_JJ_H
#include "ultra64.h"
-#include "global.h"
+#include "z64actor.h"
struct EnJj;
-typedef void (*EnJjActionFunc)(struct EnJj*, PlayState*);
+typedef void (*EnJjActionFunc)(struct EnJj*, struct PlayState*);
typedef struct EnJj {
/* 0x0000 */ DynaPolyActor dyna;
diff --git a/src/overlays/actors/ovl_En_Js/z_en_js.c b/src/overlays/actors/ovl_En_Js/z_en_js.c
index 6cd5163ae..f5aee34c6 100644
--- a/src/overlays/actors/ovl_En_Js/z_en_js.c
+++ b/src/overlays/actors/ovl_En_Js/z_en_js.c
@@ -5,6 +5,15 @@
*/
#include "z_en_js.h"
+
+#include "gfx.h"
+#include "gfx_setupdl.h"
+#include "regs.h"
+#include "sys_matrix.h"
+#include "z_lib.h"
+#include "z64play.h"
+#include "z64save.h"
+
#include "assets/objects/object_js/object_js.h"
#define FLAGS (ACTOR_FLAG_ATTENTION_ENABLED | ACTOR_FLAG_FRIENDLY)
diff --git a/src/overlays/actors/ovl_En_Js/z_en_js.h b/src/overlays/actors/ovl_En_Js/z_en_js.h
index f1e356b2c..e1e22f547 100644
--- a/src/overlays/actors/ovl_En_Js/z_en_js.h
+++ b/src/overlays/actors/ovl_En_Js/z_en_js.h
@@ -2,11 +2,11 @@
#define Z_EN_JS_H
#include "ultra64.h"
-#include "global.h"
+#include "z64actor.h"
struct EnJs;
-typedef void (*EnJsActionFunc)(struct EnJs*, PlayState*);
+typedef void (*EnJsActionFunc)(struct EnJs*, struct PlayState*);
typedef struct EnJs {
/* 0x0000 */ Actor actor;
diff --git a/src/overlays/actors/ovl_En_Jsjutan/z_en_jsjutan.c b/src/overlays/actors/ovl_En_Jsjutan/z_en_jsjutan.c
index 6650e3171..2d0ed48af 100644
--- a/src/overlays/actors/ovl_En_Jsjutan/z_en_jsjutan.c
+++ b/src/overlays/actors/ovl_En_Jsjutan/z_en_jsjutan.c
@@ -7,6 +7,16 @@
#include "z_en_jsjutan.h"
#include "overlays/actors/ovl_En_Bom/z_en_bom.h"
+#include "gfx.h"
+#include "gfx_setupdl.h"
+#include "segmented_address.h"
+#include "sys_math.h"
+#include "sys_matrix.h"
+#include "z_lib.h"
+#include "z64play.h"
+#include "z64player.h"
+#include "z64save.h"
+
#define FLAGS (ACTOR_FLAG_ATTENTION_ENABLED | ACTOR_FLAG_FRIENDLY)
void EnJsjutan_Init(Actor* thisx, PlayState* play);
diff --git a/src/overlays/actors/ovl_En_Jsjutan/z_en_jsjutan.h b/src/overlays/actors/ovl_En_Jsjutan/z_en_jsjutan.h
index 63a694bad..b6c4b0759 100644
--- a/src/overlays/actors/ovl_En_Jsjutan/z_en_jsjutan.h
+++ b/src/overlays/actors/ovl_En_Jsjutan/z_en_jsjutan.h
@@ -2,7 +2,7 @@
#define Z_EN_JSJUTAN_H
#include "ultra64.h"
-#include "global.h"
+#include "z64actor.h"
struct EnJsjutan;
diff --git a/src/overlays/actors/ovl_En_Kakasi/z_en_kakasi.c b/src/overlays/actors/ovl_En_Kakasi/z_en_kakasi.c
index d5ada1830..7a38ebc93 100644
--- a/src/overlays/actors/ovl_En_Kakasi/z_en_kakasi.c
+++ b/src/overlays/actors/ovl_En_Kakasi/z_en_kakasi.c
@@ -5,7 +5,20 @@
*/
#include "z_en_kakasi.h"
+
+#include "gfx.h"
+#include "gfx_setupdl.h"
+#include "one_point_cutscene.h"
+#include "rand.h"
+#include "regs.h"
+#include "sfx.h"
#include "terminal.h"
+#include "z_lib.h"
+#include "z64ocarina.h"
+#include "z64play.h"
+#include "z64player.h"
+#include "z64save.h"
+
#include "assets/objects/object_ka/object_ka.h"
#define FLAGS (ACTOR_FLAG_ATTENTION_ENABLED | ACTOR_FLAG_FRIENDLY | ACTOR_FLAG_UPDATE_DURING_OCARINA)
diff --git a/src/overlays/actors/ovl_En_Kakasi/z_en_kakasi.h b/src/overlays/actors/ovl_En_Kakasi/z_en_kakasi.h
index ceef6afe9..c2eff368c 100644
--- a/src/overlays/actors/ovl_En_Kakasi/z_en_kakasi.h
+++ b/src/overlays/actors/ovl_En_Kakasi/z_en_kakasi.h
@@ -2,11 +2,11 @@
#define Z_EN_KAKASI_H
#include "ultra64.h"
-#include "global.h"
+#include "z64actor.h"
struct EnKakasi;
-typedef void (*EnKakasiFunc)(struct EnKakasi*, PlayState*);
+typedef void (*EnKakasiFunc)(struct EnKakasi*, struct PlayState*);
typedef struct EnKakasi {
/* 0x0000 */ Actor actor;
diff --git a/src/overlays/actors/ovl_En_Kakasi2/z_en_kakasi2.c b/src/overlays/actors/ovl_En_Kakasi2/z_en_kakasi2.c
index 51a9e0267..abb4b5476 100644
--- a/src/overlays/actors/ovl_En_Kakasi2/z_en_kakasi2.c
+++ b/src/overlays/actors/ovl_En_Kakasi2/z_en_kakasi2.c
@@ -16,6 +16,7 @@
#include "z64ocarina.h"
#include "z64play.h"
#include "z64player.h"
+#include "z64save.h"
#include "assets/objects/object_ka/object_ka.h"
diff --git a/src/overlays/actors/ovl_En_Kakasi3/z_en_kakasi3.c b/src/overlays/actors/ovl_En_Kakasi3/z_en_kakasi3.c
index c670a19ef..6ae299d96 100644
--- a/src/overlays/actors/ovl_En_Kakasi3/z_en_kakasi3.c
+++ b/src/overlays/actors/ovl_En_Kakasi3/z_en_kakasi3.c
@@ -5,7 +5,20 @@
*/
#include "z_en_kakasi3.h"
+
+#include "gfx.h"
+#include "gfx_setupdl.h"
+#include "one_point_cutscene.h"
+#include "rand.h"
+#include "regs.h"
+#include "sfx.h"
#include "terminal.h"
+#include "z_lib.h"
+#include "z64ocarina.h"
+#include "z64play.h"
+#include "z64player.h"
+#include "z64save.h"
+
#include "assets/objects/object_ka/object_ka.h"
#define FLAGS (ACTOR_FLAG_ATTENTION_ENABLED | ACTOR_FLAG_FRIENDLY | ACTOR_FLAG_UPDATE_DURING_OCARINA)
diff --git a/src/overlays/actors/ovl_En_Kakasi3/z_en_kakasi3.h b/src/overlays/actors/ovl_En_Kakasi3/z_en_kakasi3.h
index f402ab5de..e09b98a9f 100644
--- a/src/overlays/actors/ovl_En_Kakasi3/z_en_kakasi3.h
+++ b/src/overlays/actors/ovl_En_Kakasi3/z_en_kakasi3.h
@@ -2,11 +2,11 @@
#define Z_EN_KAKASI3_H
#include "ultra64.h"
-#include "global.h"
+#include "z64actor.h"
struct EnKakasi3;
-typedef void (*EnKakasi3ActionFunc)(struct EnKakasi3*, PlayState*);
+typedef void (*EnKakasi3ActionFunc)(struct EnKakasi3*, struct PlayState*);
typedef struct EnKakasi3 {
/* 0x0000 */ Actor actor;
diff --git a/src/overlays/actors/ovl_En_Kanban/z_en_kanban.c b/src/overlays/actors/ovl_En_Kanban/z_en_kanban.c
index 03242220e..5c2b65243 100644
--- a/src/overlays/actors/ovl_En_Kanban/z_en_kanban.c
+++ b/src/overlays/actors/ovl_En_Kanban/z_en_kanban.c
@@ -5,10 +5,26 @@
*/
#include "z_en_kanban.h"
-#include "global.h"
+
+#include "libc64/math64.h"
+#include "libc64/qrand.h"
+#include "attributes.h"
+#include "gfx.h"
+#include "gfx_setupdl.h"
+#include "rand.h"
+#include "segmented_address.h"
+#include "sfx.h"
+#include "sys_matrix.h"
+#include "terminal.h"
+#include "z_lib.h"
+#include "z64effect.h"
+#include "z64ocarina.h"
+#include "z64play.h"
+#include "z64player.h"
+#include "z64save.h"
+
#include "assets/objects/gameplay_keep/gameplay_keep.h"
#include "assets/objects/object_kanban/object_kanban.h"
-#include "terminal.h"
#define FLAGS (ACTOR_FLAG_ATTENTION_ENABLED | ACTOR_FLAG_FRIENDLY | ACTOR_FLAG_UPDATE_CULLING_DISABLED)
diff --git a/src/overlays/actors/ovl_En_Kanban/z_en_kanban_gfx.inc.c b/src/overlays/actors/ovl_En_Kanban/z_en_kanban_gfx.inc.c
index c38e9df94..3dca1d625 100644
--- a/src/overlays/actors/ovl_En_Kanban/z_en_kanban_gfx.inc.c
+++ b/src/overlays/actors/ovl_En_Kanban/z_en_kanban_gfx.inc.c
@@ -1,4 +1,4 @@
-#include "z_en_kanban.h"
+#include "ultra64.h"
static u16 sShadowTexFlags[] = {
0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x100,
diff --git a/src/overlays/actors/ovl_En_Karebaba/z_en_karebaba.c b/src/overlays/actors/ovl_En_Karebaba/z_en_karebaba.c
index cdba59e66..be3b0eacb 100644
--- a/src/overlays/actors/ovl_En_Karebaba/z_en_karebaba.c
+++ b/src/overlays/actors/ovl_En_Karebaba/z_en_karebaba.c
@@ -5,9 +5,21 @@
*/
#include "z_en_karebaba.h"
+#include "overlays/effects/ovl_Effect_Ss_Hahen/z_eff_ss_hahen.h"
+
+#include "gfx.h"
+#include "gfx_setupdl.h"
+#include "ichain.h"
+#include "sfx.h"
+#include "sys_matrix.h"
+#include "z_lib.h"
+#include "z64effect.h"
+#include "z64play.h"
+#include "z64player.h"
+#include "z64save.h"
+
#include "assets/objects/object_dekubaba/object_dekubaba.h"
#include "assets/objects/gameplay_keep/gameplay_keep.h"
-#include "overlays/effects/ovl_Effect_Ss_Hahen/z_eff_ss_hahen.h"
#define FLAGS (ACTOR_FLAG_ATTENTION_ENABLED | ACTOR_FLAG_HOSTILE)
diff --git a/src/overlays/actors/ovl_En_Karebaba/z_en_karebaba.h b/src/overlays/actors/ovl_En_Karebaba/z_en_karebaba.h
index 0687ade58..97b04f1a7 100644
--- a/src/overlays/actors/ovl_En_Karebaba/z_en_karebaba.h
+++ b/src/overlays/actors/ovl_En_Karebaba/z_en_karebaba.h
@@ -2,11 +2,11 @@
#define Z_EN_KAREBABA_H
#include "ultra64.h"
-#include "global.h"
+#include "z64actor.h"
struct EnKarebaba;
-typedef void (*EnKarebabaActionFunc)(struct EnKarebaba*, PlayState*);
+typedef void (*EnKarebabaActionFunc)(struct EnKarebaba*, struct PlayState*);
typedef struct EnKarebaba {
/* 0x0000 */ Actor actor;
@@ -14,7 +14,7 @@ typedef struct EnKarebaba {
/* 0x0190 */ EnKarebabaActionFunc actionFunc;
/* 0x0194 */ Vec3s jointTable[8];
/* 0x01C4 */ Vec3s morphTable[8];
- /* 0x01F4 */ CollisionPoly* boundFloor;
+ /* 0x01F4 */ struct CollisionPoly* boundFloor;
/* 0x01F8 */ ColliderCylinder headCollider;
/* 0x0244 */ ColliderCylinder bodyCollider;
} EnKarebaba; // size = 0x0290
diff --git a/src/overlays/actors/ovl_En_Ko/z_en_ko.c b/src/overlays/actors/ovl_En_Ko/z_en_ko.c
index b9013cbbe..055a3bef4 100644
--- a/src/overlays/actors/ovl_En_Ko/z_en_ko.c
+++ b/src/overlays/actors/ovl_En_Ko/z_en_ko.c
@@ -5,12 +5,24 @@
*/
#include "z_en_ko.h"
+
+#include "attributes.h"
+#include "gfx.h"
+#include "segmented_address.h"
+#include "sfx.h"
+#include "sys_matrix.h"
+#include "terminal.h"
+#include "versions.h"
+#include "z_lib.h"
+#include "z64face_reaction.h"
+#include "z64play.h"
+#include "z64player.h"
+#include "z64save.h"
+
#include "assets/objects/object_fa/object_fa.h"
#include "assets/objects/object_os_anime/object_os_anime.h"
#include "assets/objects/object_km1/object_km1.h"
#include "assets/objects/object_kw1/object_kw1.h"
-#include "terminal.h"
-#include "versions.h"
#define FLAGS (ACTOR_FLAG_ATTENTION_ENABLED | ACTOR_FLAG_FRIENDLY | ACTOR_FLAG_UPDATE_CULLING_DISABLED)
diff --git a/src/overlays/actors/ovl_En_Ko/z_en_ko.h b/src/overlays/actors/ovl_En_Ko/z_en_ko.h
index 085e9aca5..d9531e57e 100644
--- a/src/overlays/actors/ovl_En_Ko/z_en_ko.h
+++ b/src/overlays/actors/ovl_En_Ko/z_en_ko.h
@@ -2,11 +2,11 @@
#define Z_EN_KO_H
#include "ultra64.h"
-#include "global.h"
+#include "z64actor.h"
struct EnKo;
-typedef void (*EnKoActionFunc)(struct EnKo*, PlayState*);
+typedef void (*EnKoActionFunc)(struct EnKo*, struct PlayState*);
typedef struct EnKo {
/* 0x0000 */ Actor actor;
@@ -17,7 +17,7 @@ typedef struct EnKo {
/* 0x0196 */ s8 legsObjectSlot;
/* 0x0197 */ s8 osAnimeObjectSlot;
/* 0x0198 */ ColliderCylinder collider;
- /* 0x01E4 */ Path* path;
+ /* 0x01E4 */ struct Path* path;
/* 0x01E8 */ NpcInteractInfo interactInfo;
/* 0x0210 */ u8 unk_210; // block trade quest sfx
/* 0x0212 */ s16 forestQuestState;
diff --git a/src/overlays/actors/ovl_En_Kz/z_en_kz.c b/src/overlays/actors/ovl_En_Kz/z_en_kz.c
index a4aaf4e1c..7caa73573 100644
--- a/src/overlays/actors/ovl_En_Kz/z_en_kz.c
+++ b/src/overlays/actors/ovl_En_Kz/z_en_kz.c
@@ -5,7 +5,21 @@
*/
#include "z_en_kz.h"
+
+#include "libc64/math64.h"
+#include "attributes.h"
+#include "gfx.h"
+#include "gfx_setupdl.h"
+#include "segmented_address.h"
+#include "sfx.h"
+#include "sys_matrix.h"
#include "versions.h"
+#include "z_lib.h"
+#include "z64face_reaction.h"
+#include "z64play.h"
+#include "z64player.h"
+#include "z64save.h"
+
#include "assets/objects/object_kz/object_kz.h"
#define FLAGS (ACTOR_FLAG_ATTENTION_ENABLED | ACTOR_FLAG_FRIENDLY)
diff --git a/src/overlays/actors/ovl_En_Kz/z_en_kz.h b/src/overlays/actors/ovl_En_Kz/z_en_kz.h
index b5cd38079..933fbe261 100644
--- a/src/overlays/actors/ovl_En_Kz/z_en_kz.h
+++ b/src/overlays/actors/ovl_En_Kz/z_en_kz.h
@@ -2,11 +2,11 @@
#define Z_EN_KZ_H
#include "ultra64.h"
-#include "global.h"
+#include "z64actor.h"
struct EnKz;
-typedef void (*EnKzActionFunc)(struct EnKz*, PlayState*);
+typedef void (*EnKzActionFunc)(struct EnKz*, struct PlayState*);
typedef struct EnKz {
/* 0x0000 */ Actor actor;
diff --git a/src/overlays/actors/ovl_En_Light/z_en_light.c b/src/overlays/actors/ovl_En_Light/z_en_light.c
index 33d671a95..f0cc5dddc 100644
--- a/src/overlays/actors/ovl_En_Light/z_en_light.c
+++ b/src/overlays/actors/ovl_En_Light/z_en_light.c
@@ -5,6 +5,17 @@
*/
#include "z_en_light.h"
+
+#include "libc64/qrand.h"
+#include "gfx.h"
+#include "gfx_setupdl.h"
+#include "sfx.h"
+#include "sys_matrix.h"
+#include "z_lib.h"
+#include "z64light.h"
+#include "z64play.h"
+#include "z64save.h"
+
#include "assets/objects/gameplay_keep/gameplay_keep.h"
#include "assets/objects/gameplay_dangeon_keep/gameplay_dangeon_keep.h"
diff --git a/src/overlays/actors/ovl_En_Light/z_en_light.h b/src/overlays/actors/ovl_En_Light/z_en_light.h
index 1cbf786b0..035471f47 100644
--- a/src/overlays/actors/ovl_En_Light/z_en_light.h
+++ b/src/overlays/actors/ovl_En_Light/z_en_light.h
@@ -2,7 +2,8 @@
#define Z_EN_LIGHT_H
#include "ultra64.h"
-#include "global.h"
+#include "z64actor.h"
+#include "z64light.h"
struct EnLight;
diff --git a/src/overlays/actors/ovl_En_Lightbox/z_en_lightbox.c b/src/overlays/actors/ovl_En_Lightbox/z_en_lightbox.c
index c2b6ca1d6..b4bd3af91 100644
--- a/src/overlays/actors/ovl_En_Lightbox/z_en_lightbox.c
+++ b/src/overlays/actors/ovl_En_Lightbox/z_en_lightbox.c
@@ -5,6 +5,12 @@
*/
#include "z_en_lightbox.h"
+
+#include "regs.h"
+#include "sfx.h"
+#include "z_lib.h"
+#include "z64play.h"
+
#include "assets/objects/object_lightbox/object_lightbox.h"
#define FLAGS ACTOR_FLAG_UPDATE_CULLING_DISABLED
diff --git a/src/overlays/actors/ovl_En_Lightbox/z_en_lightbox.h b/src/overlays/actors/ovl_En_Lightbox/z_en_lightbox.h
index e24afd44e..c09c77f85 100644
--- a/src/overlays/actors/ovl_En_Lightbox/z_en_lightbox.h
+++ b/src/overlays/actors/ovl_En_Lightbox/z_en_lightbox.h
@@ -2,7 +2,7 @@
#define Z_EN_LIGHTBOX_H
#include "ultra64.h"
-#include "global.h"
+#include "z64actor.h"
struct EnLightbox;
diff --git a/src/overlays/actors/ovl_En_M_Fire1/z_en_m_fire1.c b/src/overlays/actors/ovl_En_M_Fire1/z_en_m_fire1.c
index 9acedc155..2097bb9d2 100644
--- a/src/overlays/actors/ovl_En_M_Fire1/z_en_m_fire1.c
+++ b/src/overlays/actors/ovl_En_M_Fire1/z_en_m_fire1.c
@@ -6,6 +6,9 @@
#include "z_en_m_fire1.h"
+#include "z_lib.h"
+#include "z64play.h"
+
#define FLAGS 0
void EnMFire1_Init(Actor* thisx, PlayState* play);
diff --git a/src/overlays/actors/ovl_En_M_Fire1/z_en_m_fire1.h b/src/overlays/actors/ovl_En_M_Fire1/z_en_m_fire1.h
index 10d3e3fef..59ebb4431 100644
--- a/src/overlays/actors/ovl_En_M_Fire1/z_en_m_fire1.h
+++ b/src/overlays/actors/ovl_En_M_Fire1/z_en_m_fire1.h
@@ -2,7 +2,7 @@
#define Z_EN_M_FIRE1_H
#include "ultra64.h"
-#include "global.h"
+#include "z64actor.h"
struct EnMFire1;
diff --git a/src/overlays/actors/ovl_En_M_Thunder/z_en_m_thunder.c b/src/overlays/actors/ovl_En_M_Thunder/z_en_m_thunder.c
index eb7745aa8..ba34f9adc 100644
--- a/src/overlays/actors/ovl_En_M_Thunder/z_en_m_thunder.c
+++ b/src/overlays/actors/ovl_En_M_Thunder/z_en_m_thunder.c
@@ -1,4 +1,17 @@
#include "z_en_m_thunder.h"
+
+#include "gfx.h"
+#include "gfx_setupdl.h"
+#include "rumble.h"
+#include "sfx.h"
+#include "sys_matrix.h"
+#include "z_lib.h"
+#include "z64audio.h"
+#include "z64light.h"
+#include "z64play.h"
+#include "z64player.h"
+#include "z64save.h"
+
#include "assets/objects/gameplay_keep/gameplay_keep.h"
#define FLAGS 0
diff --git a/src/overlays/actors/ovl_En_M_Thunder/z_en_m_thunder.h b/src/overlays/actors/ovl_En_M_Thunder/z_en_m_thunder.h
index 4cb7ad215..8c7cdd7a1 100644
--- a/src/overlays/actors/ovl_En_M_Thunder/z_en_m_thunder.h
+++ b/src/overlays/actors/ovl_En_M_Thunder/z_en_m_thunder.h
@@ -2,11 +2,12 @@
#define Z_EN_M_THUNDER_H
#include "ultra64.h"
-#include "global.h"
+#include "z64actor.h"
+#include "z64light.h"
struct EnMThunder;
-typedef void (*EnMThunderActionFunc)(struct EnMThunder*, PlayState*);
+typedef void (*EnMThunderActionFunc)(struct EnMThunder*, struct PlayState*);
typedef struct EnMThunder {
/* 0x0000 */ Actor actor;
diff --git a/src/overlays/actors/ovl_En_Ma1/z_en_ma1.c b/src/overlays/actors/ovl_En_Ma1/z_en_ma1.c
index d0c16c3a7..9c1689a52 100644
--- a/src/overlays/actors/ovl_En_Ma1/z_en_ma1.c
+++ b/src/overlays/actors/ovl_En_Ma1/z_en_ma1.c
@@ -5,6 +5,20 @@
*/
#include "z_en_ma1.h"
+
+#include "gfx.h"
+#include "gfx_setupdl.h"
+#include "segmented_address.h"
+#include "sequence.h"
+#include "sys_matrix.h"
+#include "z_lib.h"
+#include "z64audio.h"
+#include "z64face_reaction.h"
+#include "z64ocarina.h"
+#include "z64play.h"
+#include "z64player.h"
+#include "z64save.h"
+
#include "assets/objects/object_ma1/object_ma1.h"
#define FLAGS \
diff --git a/src/overlays/actors/ovl_En_Ma1/z_en_ma1.h b/src/overlays/actors/ovl_En_Ma1/z_en_ma1.h
index ef69c0c8e..3664fc98a 100644
--- a/src/overlays/actors/ovl_En_Ma1/z_en_ma1.h
+++ b/src/overlays/actors/ovl_En_Ma1/z_en_ma1.h
@@ -2,11 +2,11 @@
#define Z_EN_MA1_H
#include "ultra64.h"
-#include "global.h"
+#include "z64actor.h"
struct EnMa1;
-typedef void (*EnMa1ActionFunc)(struct EnMa1*, PlayState*);
+typedef void (*EnMa1ActionFunc)(struct EnMa1*, struct PlayState*);
typedef struct EnMa1 {
/* 0x0000 */ Actor actor;
diff --git a/src/overlays/actors/ovl_En_Ma2/z_en_ma2.c b/src/overlays/actors/ovl_En_Ma2/z_en_ma2.c
index a4a4a1704..aed88bb92 100644
--- a/src/overlays/actors/ovl_En_Ma2/z_en_ma2.c
+++ b/src/overlays/actors/ovl_En_Ma2/z_en_ma2.c
@@ -1,4 +1,19 @@
#include "z_en_ma2.h"
+
+#include "gfx.h"
+#include "gfx_setupdl.h"
+#include "segmented_address.h"
+#include "sequence.h"
+#include "sfx.h"
+#include "sys_matrix.h"
+#include "z_lib.h"
+#include "z64audio.h"
+#include "z64face_reaction.h"
+#include "z64ocarina.h"
+#include "z64play.h"
+#include "z64player.h"
+#include "z64save.h"
+
#include "assets/objects/object_ma2/object_ma2.h"
#define FLAGS \
diff --git a/src/overlays/actors/ovl_En_Ma2/z_en_ma2.h b/src/overlays/actors/ovl_En_Ma2/z_en_ma2.h
index 390c61da2..81fddf767 100644
--- a/src/overlays/actors/ovl_En_Ma2/z_en_ma2.h
+++ b/src/overlays/actors/ovl_En_Ma2/z_en_ma2.h
@@ -2,11 +2,11 @@
#define Z_EN_MA2_H
#include "ultra64.h"
-#include "global.h"
+#include "z64actor.h"
struct EnMa2;
-typedef void (*EnMa2ActionFunc)(struct EnMa2*, PlayState*);
+typedef void (*EnMa2ActionFunc)(struct EnMa2*, struct PlayState*);
typedef enum AdultMalonLimb {
/* 0x00 */ MALON_ADULT_LIMB_NONE,
diff --git a/src/overlays/actors/ovl_En_Ma3/z_en_ma3.c b/src/overlays/actors/ovl_En_Ma3/z_en_ma3.c
index 69dc0d907..cdac00922 100644
--- a/src/overlays/actors/ovl_En_Ma3/z_en_ma3.c
+++ b/src/overlays/actors/ovl_En_Ma3/z_en_ma3.c
@@ -5,8 +5,21 @@
*/
#include "z_en_ma3.h"
-#include "assets/objects/object_ma2/object_ma2.h"
+
+#include "attributes.h"
+#include "gfx.h"
+#include "gfx_setupdl.h"
+#include "segmented_address.h"
+#include "sequence.h"
+#include "sys_matrix.h"
+#include "z_lib.h"
#include "versions.h"
+#include "z64audio.h"
+#include "z64play.h"
+#include "z64player.h"
+#include "z64save.h"
+
+#include "assets/objects/object_ma2/object_ma2.h"
#define FLAGS \
(ACTOR_FLAG_ATTENTION_ENABLED | ACTOR_FLAG_FRIENDLY | ACTOR_FLAG_UPDATE_CULLING_DISABLED | \
diff --git a/src/overlays/actors/ovl_En_Ma3/z_en_ma3.h b/src/overlays/actors/ovl_En_Ma3/z_en_ma3.h
index 2b9dea812..ecf637561 100644
--- a/src/overlays/actors/ovl_En_Ma3/z_en_ma3.h
+++ b/src/overlays/actors/ovl_En_Ma3/z_en_ma3.h
@@ -2,11 +2,11 @@
#define Z_EN_MA3_H
#include "ultra64.h"
-#include "global.h"
+#include "z64actor.h"
struct EnMa3;
-typedef void (*EnMa3ActionFunc)(struct EnMa3*, PlayState*);
+typedef void (*EnMa3ActionFunc)(struct EnMa3*, struct PlayState*);
typedef enum AdultMalonLimb {
/* 0x00 */ MALON_ADULT_LIMB_NONE,
diff --git a/src/overlays/actors/ovl_En_Mag/z_en_mag.c b/src/overlays/actors/ovl_En_Mag/z_en_mag.c
index 974fbb49d..ac6e9311b 100644
--- a/src/overlays/actors/ovl_En_Mag/z_en_mag.c
+++ b/src/overlays/actors/ovl_En_Mag/z_en_mag.c
@@ -5,12 +5,24 @@
*/
#include "z_en_mag.h"
-#include "versions.h"
-#include "assets/objects/object_mag/object_mag.h"
+
+#include "controller.h"
+#include "gfx.h"
+#include "gfx_setupdl.h"
+#include "gfxalloc.h"
#if PLATFORM_N64
#include "n64dd.h"
#endif
+#include "regs.h"
+#include "sfx.h"
#include "versions.h"
+#include "z64audio.h"
+#include "z64cutscene_flags.h"
+#include "z64play.h"
+#include "z64save.h"
+#include "z64ss_sram.h"
+
+#include "assets/objects/object_mag/object_mag.h"
#define FLAGS (ACTOR_FLAG_UPDATE_CULLING_DISABLED | ACTOR_FLAG_DRAW_CULLING_DISABLED)
@@ -58,8 +70,8 @@ void EnMag_ResetSram(void) {
SsSram_ReadWrite(OS_K1_TO_PHYSICAL(0xA8007000), buffer, 0x800, 1);
SsSram_ReadWrite(OS_K1_TO_PHYSICAL(0xA8007800), buffer, 0x800, 1);
- gSaveContext.audioSetting = gSaveContext.zTargetSetting = 0;
- func_800F6700(gSaveContext.audioSetting);
+ gSaveContext.soundSetting = gSaveContext.zTargetSetting = 0; // SOUND_SETTING_STEREO/Z_TARGET_SETTING_SWITCH
+ Audio_SetSoundMode(gSaveContext.soundSetting);
}
#endif
diff --git a/src/overlays/actors/ovl_En_Mag/z_en_mag.h b/src/overlays/actors/ovl_En_Mag/z_en_mag.h
index e7c516c62..ace842727 100644
--- a/src/overlays/actors/ovl_En_Mag/z_en_mag.h
+++ b/src/overlays/actors/ovl_En_Mag/z_en_mag.h
@@ -2,7 +2,8 @@
#define Z_EN_MAG_H
#include "ultra64.h"
-#include "global.h"
+#include "z64actor.h"
+#include "z64message.h"
struct EnMag;
diff --git a/src/overlays/actors/ovl_En_Md/z_en_md.c b/src/overlays/actors/ovl_En_Md/z_en_md.c
index d8838f74e..7b1f6b2ca 100644
--- a/src/overlays/actors/ovl_En_Md/z_en_md.c
+++ b/src/overlays/actors/ovl_En_Md/z_en_md.c
@@ -5,9 +5,23 @@
*/
#include "z_en_md.h"
-#include "assets/objects/object_md/object_md.h"
#include "overlays/actors/ovl_En_Elf/z_en_elf.h"
+#include "libc64/math64.h"
+#include "attributes.h"
+#include "gfx.h"
+#include "segmented_address.h"
+#include "sfx.h"
+#include "sys_matrix.h"
+#include "z_lib.h"
+#include "z64face_reaction.h"
+#include "z64ocarina.h"
+#include "z64play.h"
+#include "z64player.h"
+#include "z64save.h"
+
+#include "assets/objects/object_md/object_md.h"
+
#define FLAGS \
(ACTOR_FLAG_ATTENTION_ENABLED | ACTOR_FLAG_FRIENDLY | ACTOR_FLAG_UPDATE_CULLING_DISABLED | \
ACTOR_FLAG_UPDATE_DURING_OCARINA)
diff --git a/src/overlays/actors/ovl_En_Md/z_en_md.h b/src/overlays/actors/ovl_En_Md/z_en_md.h
index 6a78a2490..bfd9b0450 100644
--- a/src/overlays/actors/ovl_En_Md/z_en_md.h
+++ b/src/overlays/actors/ovl_En_Md/z_en_md.h
@@ -2,7 +2,7 @@
#define Z_EN_MD_H
#include "ultra64.h"
-#include "global.h"
+#include "z64actor.h"
struct EnMd;
@@ -27,7 +27,7 @@ typedef enum EnMdLimb {
ENMD_LIMB_MAX
} EnMdLimb;
-typedef void (*EnMdActionFunc)(struct EnMd*, PlayState*);
+typedef void (*EnMdActionFunc)(struct EnMd*, struct PlayState*);
#define ENMD_GET_PATH_INDEX(this) PARAMS_GET_S(this->actor.params, 8, 8)
#define ENMD_GET_PATH_INDEX_NOSHIFT(this) PARAMS_GET_NOSHIFT(this->actor.params, 8, 8)
diff --git a/src/overlays/actors/ovl_En_Mk/z_en_mk.c b/src/overlays/actors/ovl_En_Mk/z_en_mk.c
index df7708a69..f035f2d33 100644
--- a/src/overlays/actors/ovl_En_Mk/z_en_mk.c
+++ b/src/overlays/actors/ovl_En_Mk/z_en_mk.c
@@ -5,6 +5,17 @@
*/
#include "z_en_mk.h"
+
+#include "gfx.h"
+#include "gfx_setupdl.h"
+#include "sfx.h"
+#include "sys_matrix.h"
+#include "z_lib.h"
+#include "z64face_reaction.h"
+#include "z64play.h"
+#include "z64player.h"
+#include "z64save.h"
+
#include "assets/objects/object_mk/object_mk.h"
#define FLAGS (ACTOR_FLAG_ATTENTION_ENABLED | ACTOR_FLAG_FRIENDLY | ACTOR_FLAG_UPDATE_CULLING_DISABLED)
diff --git a/src/overlays/actors/ovl_En_Mk/z_en_mk.h b/src/overlays/actors/ovl_En_Mk/z_en_mk.h
index 5b8a438a0..53df56b76 100644
--- a/src/overlays/actors/ovl_En_Mk/z_en_mk.h
+++ b/src/overlays/actors/ovl_En_Mk/z_en_mk.h
@@ -2,11 +2,11 @@
#define Z_EN_MK_H
#include "ultra64.h"
-#include "global.h"
+#include "z64actor.h"
struct EnMk;
-typedef void (*EnMkActionFunc)(struct EnMk*, PlayState*);
+typedef void (*EnMkActionFunc)(struct EnMk*, struct PlayState*);
typedef struct EnMk {
/* 0x0000 */ Actor actor;
diff --git a/src/overlays/actors/ovl_En_Mm/z_en_mm.c b/src/overlays/actors/ovl_En_Mm/z_en_mm.c
index b081f8304..75969dd22 100644
--- a/src/overlays/actors/ovl_En_Mm/z_en_mm.c
+++ b/src/overlays/actors/ovl_En_Mm/z_en_mm.c
@@ -5,6 +5,20 @@
*/
#include "z_en_mm.h"
+
+#include "libc64/math64.h"
+#include "gfx.h"
+#include "gfx_setupdl.h"
+#include "ichain.h"
+#include "segmented_address.h"
+#include "sfx.h"
+#include "sys_matrix.h"
+#include "z_lib.h"
+#include "z64face_reaction.h"
+#include "z64play.h"
+#include "z64player.h"
+#include "z64save.h"
+
#include "assets/objects/object_mm/object_mm.h"
#include "assets/objects/object_link_child/object_link_child.h"
diff --git a/src/overlays/actors/ovl_En_Mm/z_en_mm.h b/src/overlays/actors/ovl_En_Mm/z_en_mm.h
index 7646e1f04..555073753 100644
--- a/src/overlays/actors/ovl_En_Mm/z_en_mm.h
+++ b/src/overlays/actors/ovl_En_Mm/z_en_mm.h
@@ -2,11 +2,11 @@
#define Z_EN_MM_H
#include "ultra64.h"
-#include "global.h"
+#include "z64actor.h"
struct EnMm;
-typedef void (*EnMmActionFunc)(struct EnMm*, PlayState*);
+typedef void (*EnMmActionFunc)(struct EnMm*, struct PlayState*);
typedef struct EnMm {
/* 0x0000 */ Actor actor;
diff --git a/src/overlays/actors/ovl_En_Mm2/z_en_mm2.c b/src/overlays/actors/ovl_En_Mm2/z_en_mm2.c
index 3082b5c35..3958fce49 100644
--- a/src/overlays/actors/ovl_En_Mm2/z_en_mm2.c
+++ b/src/overlays/actors/ovl_En_Mm2/z_en_mm2.c
@@ -5,7 +5,18 @@
*/
#include "z_en_mm2.h"
+
+#include "libu64/debug.h"
+#include "gfx.h"
+#include "gfx_setupdl.h"
+#include "ichain.h"
+#include "segmented_address.h"
+#include "sys_matrix.h"
#include "terminal.h"
+#include "z_lib.h"
+#include "z64play.h"
+#include "z64save.h"
+
#include "assets/objects/object_mm/object_mm.h"
#define FLAGS (ACTOR_FLAG_ATTENTION_ENABLED | ACTOR_FLAG_FRIENDLY | ACTOR_FLAG_UPDATE_CULLING_DISABLED)
diff --git a/src/overlays/actors/ovl_En_Mm2/z_en_mm2.h b/src/overlays/actors/ovl_En_Mm2/z_en_mm2.h
index a5edeb9cb..8e48261d7 100644
--- a/src/overlays/actors/ovl_En_Mm2/z_en_mm2.h
+++ b/src/overlays/actors/ovl_En_Mm2/z_en_mm2.h
@@ -2,11 +2,11 @@
#define Z_EN_MM2_H
#include "ultra64.h"
-#include "global.h"
+#include "z64actor.h"
struct EnMm2;
-typedef void (*EnMm2ActionFunc)(struct EnMm2*, PlayState*);
+typedef void (*EnMm2ActionFunc)(struct EnMm2*, struct PlayState*);
typedef struct EnMm2 {
/* 0x0000 */ Actor actor;
diff --git a/src/overlays/actors/ovl_En_Ms/z_en_ms.c b/src/overlays/actors/ovl_En_Ms/z_en_ms.c
index 35796e1eb..32ac75357 100644
--- a/src/overlays/actors/ovl_En_Ms/z_en_ms.c
+++ b/src/overlays/actors/ovl_En_Ms/z_en_ms.c
@@ -5,6 +5,14 @@
*/
#include "z_en_ms.h"
+
+#include "gfx.h"
+#include "gfx_setupdl.h"
+#include "ichain.h"
+#include "z64face_reaction.h"
+#include "z64play.h"
+#include "z64save.h"
+
#include "assets/objects/object_ms/object_ms.h"
#define FLAGS (ACTOR_FLAG_ATTENTION_ENABLED | ACTOR_FLAG_FRIENDLY)
diff --git a/src/overlays/actors/ovl_En_Ms/z_en_ms.h b/src/overlays/actors/ovl_En_Ms/z_en_ms.h
index 53c6bbeac..9ace7bc2d 100644
--- a/src/overlays/actors/ovl_En_Ms/z_en_ms.h
+++ b/src/overlays/actors/ovl_En_Ms/z_en_ms.h
@@ -2,11 +2,11 @@
#define Z_EN_MS_H
#include "ultra64.h"
-#include "global.h"
+#include "z64actor.h"
struct EnMs;
-typedef void (*EnMsActionFunc)(struct EnMs*, PlayState*);
+typedef void (*EnMsActionFunc)(struct EnMs*, struct PlayState*);
typedef struct EnMs {
/* 0x0000 */ Actor actor;
diff --git a/src/overlays/actors/ovl_En_Mu/z_en_mu.c b/src/overlays/actors/ovl_En_Mu/z_en_mu.c
index 4f4221820..7360dd7f1 100644
--- a/src/overlays/actors/ovl_En_Mu/z_en_mu.c
+++ b/src/overlays/actors/ovl_En_Mu/z_en_mu.c
@@ -5,6 +5,15 @@
*/
#include "z_en_mu.h"
+
+#include "libc64/qrand.h"
+#include "gfx.h"
+#include "sys_matrix.h"
+#include "z_lib.h"
+#include "z64face_reaction.h"
+#include "z64play.h"
+#include "z64save.h"
+
#include "assets/objects/object_mu/object_mu.h"
#define FLAGS (ACTOR_FLAG_ATTENTION_ENABLED | ACTOR_FLAG_FRIENDLY)
diff --git a/src/overlays/actors/ovl_En_Mu/z_en_mu.h b/src/overlays/actors/ovl_En_Mu/z_en_mu.h
index 1b098eb41..417ce242b 100644
--- a/src/overlays/actors/ovl_En_Mu/z_en_mu.h
+++ b/src/overlays/actors/ovl_En_Mu/z_en_mu.h
@@ -2,7 +2,7 @@
#define Z_EN_MU_H
#include "ultra64.h"
-#include "global.h"
+#include "z64actor.h"
struct EnMu;
diff --git a/src/overlays/actors/ovl_En_Nb/z_en_nb.c b/src/overlays/actors/ovl_En_Nb/z_en_nb.c
index 983af0678..4b615342c 100644
--- a/src/overlays/actors/ovl_En_Nb/z_en_nb.c
+++ b/src/overlays/actors/ovl_En_Nb/z_en_nb.c
@@ -5,10 +5,26 @@
*/
#include "z_en_nb.h"
-#include "terminal.h"
-#include "assets/objects/object_nb/object_nb.h"
#include "overlays/actors/ovl_Door_Warp1/z_door_warp1.h"
+#include "libc64/math64.h"
+#include "gfx.h"
+#include "gfx_setupdl.h"
+#include "regs.h"
+#include "segmented_address.h"
+#include "seqcmd.h"
+#include "sequence.h"
+#include "sfx.h"
+#include "sys_matrix.h"
+#include "terminal.h"
+#include "z_lib.h"
+#include "z64face_reaction.h"
+#include "z64play.h"
+#include "z64player.h"
+#include "z64save.h"
+
+#include "assets/objects/object_nb/object_nb.h"
+
#define FLAGS ACTOR_FLAG_UPDATE_CULLING_DISABLED
typedef enum EnNbAction {
diff --git a/src/overlays/actors/ovl_En_Nb/z_en_nb.h b/src/overlays/actors/ovl_En_Nb/z_en_nb.h
index 997af0f57..3ed08cbf8 100644
--- a/src/overlays/actors/ovl_En_Nb/z_en_nb.h
+++ b/src/overlays/actors/ovl_En_Nb/z_en_nb.h
@@ -2,7 +2,7 @@
#define Z_EN_NB_H
#include "ultra64.h"
-#include "global.h"
+#include "z64actor.h"
struct EnNb;
@@ -29,8 +29,8 @@ typedef enum EnNbLimb {
/* 0x13 */ NB_LIMB_MAX
} EnNbLimb;
-typedef void (*EnNbActionFunc)(struct EnNb*, PlayState*);
-typedef void (*EnNbDrawFunc)(struct EnNb*, PlayState*);
+typedef void (*EnNbActionFunc)(struct EnNb*, struct PlayState*);
+typedef void (*EnNbDrawFunc)(struct EnNb*, struct PlayState*);
typedef struct EnNb {
/* 0x0000 */ Actor actor;
diff --git a/src/overlays/actors/ovl_En_Niw/z_en_niw.c b/src/overlays/actors/ovl_En_Niw/z_en_niw.c
index 284e725a6..00fde6a46 100644
--- a/src/overlays/actors/ovl_En_Niw/z_en_niw.c
+++ b/src/overlays/actors/ovl_En_Niw/z_en_niw.c
@@ -24,6 +24,7 @@
#include "z64effect.h"
#include "z64play.h"
#include "z64player.h"
+#include "z64save.h"
#include "assets/objects/object_niw/object_niw.h"
diff --git a/src/overlays/actors/ovl_En_Niw_Girl/z_en_niw_girl.c b/src/overlays/actors/ovl_En_Niw_Girl/z_en_niw_girl.c
index 8521831bc..2250042f8 100644
--- a/src/overlays/actors/ovl_En_Niw_Girl/z_en_niw_girl.c
+++ b/src/overlays/actors/ovl_En_Niw_Girl/z_en_niw_girl.c
@@ -17,6 +17,7 @@
#include "z_lib.h"
#include "z64play.h"
#include "z64player.h"
+#include "z64save.h"
#include "assets/objects/object_gr/object_gr.h"
diff --git a/src/overlays/actors/ovl_En_Niw_Lady/z_en_niw_lady.c b/src/overlays/actors/ovl_En_Niw_Lady/z_en_niw_lady.c
index 0415f95bb..33881ed73 100644
--- a/src/overlays/actors/ovl_En_Niw_Lady/z_en_niw_lady.c
+++ b/src/overlays/actors/ovl_En_Niw_Lady/z_en_niw_lady.c
@@ -1,9 +1,23 @@
#include "z_en_niw_lady.h"
-#include "assets/objects/object_ane/object_ane.h"
-#include "assets/objects/object_os_anime/object_os_anime.h"
#include "overlays/actors/ovl_En_Niw/z_en_niw.h"
+
+#include "attributes.h"
+#include "gfx.h"
+#include "gfx_setupdl.h"
+#include "rand.h"
+#include "regs.h"
+#include "segmented_address.h"
+#include "sfx.h"
#include "terminal.h"
#include "versions.h"
+#include "z_lib.h"
+#include "z64face_reaction.h"
+#include "z64play.h"
+#include "z64player.h"
+#include "z64save.h"
+
+#include "assets/objects/object_ane/object_ane.h"
+#include "assets/objects/object_os_anime/object_os_anime.h"
#define FLAGS (ACTOR_FLAG_ATTENTION_ENABLED | ACTOR_FLAG_FRIENDLY | ACTOR_FLAG_UPDATE_CULLING_DISABLED)
diff --git a/src/overlays/actors/ovl_En_Niw_Lady/z_en_niw_lady.h b/src/overlays/actors/ovl_En_Niw_Lady/z_en_niw_lady.h
index 7ecb165cc..a6167454d 100644
--- a/src/overlays/actors/ovl_En_Niw_Lady/z_en_niw_lady.h
+++ b/src/overlays/actors/ovl_En_Niw_Lady/z_en_niw_lady.h
@@ -2,11 +2,11 @@
#define Z_EN_NIW_LADY_H
#include "ultra64.h"
-#include "global.h"
+#include "z64actor.h"
struct EnNiwLady;
-typedef void (*EnNiwLadyActionFunc)(struct EnNiwLady*, PlayState*);
+typedef void (*EnNiwLadyActionFunc)(struct EnNiwLady*, struct PlayState*);
typedef struct EnNiwLady {
/* 0x0000 */ Actor actor;
diff --git a/src/overlays/actors/ovl_En_Nutsball/z_en_nutsball.c b/src/overlays/actors/ovl_En_Nutsball/z_en_nutsball.c
index d76c28b72..3511a3c45 100644
--- a/src/overlays/actors/ovl_En_Nutsball/z_en_nutsball.c
+++ b/src/overlays/actors/ovl_En_Nutsball/z_en_nutsball.c
@@ -14,6 +14,7 @@
#include "z64effect.h"
#include "z64play.h"
#include "z64player.h"
+#include "z64save.h"
#include "assets/objects/object_dekunuts/object_dekunuts.h"
#include "assets/objects/object_hintnuts/object_hintnuts.h"
diff --git a/src/overlays/actors/ovl_En_Nwc/z_en_nwc.c b/src/overlays/actors/ovl_En_Nwc/z_en_nwc.c
index a990438ad..a5f322def 100644
--- a/src/overlays/actors/ovl_En_Nwc/z_en_nwc.c
+++ b/src/overlays/actors/ovl_En_Nwc/z_en_nwc.c
@@ -5,6 +5,14 @@
*/
#include "z_en_nwc.h"
+
+#include "libc64/qrand.h"
+#include "gfx.h"
+#include "gfx_setupdl.h"
+#include "sys_matrix.h"
+#include "z_lib.h"
+#include "z64play.h"
+
#include "assets/objects/object_nwc/object_nwc.h"
#define FLAGS (ACTOR_FLAG_UPDATE_CULLING_DISABLED | ACTOR_FLAG_DRAW_CULLING_DISABLED)
diff --git a/src/overlays/actors/ovl_En_Nwc/z_en_nwc.h b/src/overlays/actors/ovl_En_Nwc/z_en_nwc.h
index e927cb3b6..fbb64d1ca 100644
--- a/src/overlays/actors/ovl_En_Nwc/z_en_nwc.h
+++ b/src/overlays/actors/ovl_En_Nwc/z_en_nwc.h
@@ -2,13 +2,13 @@
#define Z_EN_NWC_H
#include "ultra64.h"
-#include "global.h"
+#include "z64actor.h"
struct EnNwc;
struct EnNwcChick;
-typedef void (*EnNwcUpdateFunc)(struct EnNwc*, PlayState*);
-typedef void (*EnNwcChickFunc)(struct EnNwcChick*, struct EnNwc*, PlayState*);
+typedef void (*EnNwcUpdateFunc)(struct EnNwc*, struct PlayState*);
+typedef void (*EnNwcChickFunc)(struct EnNwcChick*, struct EnNwc*, struct PlayState*);
typedef struct EnNwcChick {
/* 0x00 */ s8 type;
@@ -21,8 +21,8 @@ typedef struct EnNwcChick {
/* 0x2C */ f32 velY;
/* 0x30 */ Vec3s rot;
/* 0x36 */ u16 height;
- /* 0x38 */ CollisionPoly* floorPoly;
- /* 0x44 */ char unk_3C[0x20];
+ /* 0x38 */ struct CollisionPoly* floorPoly;
+ /* 0x3C */ char unk_3C[0x20];
} EnNwcChick; // size = 0x5C
typedef struct EnNwc {
diff --git a/src/overlays/actors/ovl_En_OE2/z_en_oe2.c b/src/overlays/actors/ovl_En_OE2/z_en_oe2.c
index f89eb3ce9..f568d1812 100644
--- a/src/overlays/actors/ovl_En_OE2/z_en_oe2.c
+++ b/src/overlays/actors/ovl_En_OE2/z_en_oe2.c
@@ -6,6 +6,8 @@
#include "z_en_oe2.h"
+#include "z64play.h"
+
#define FLAGS (ACTOR_FLAG_ATTENTION_ENABLED | ACTOR_FLAG_FRIENDLY)
void EnOE2_Init(Actor* thisx, PlayState* play);
diff --git a/src/overlays/actors/ovl_En_OE2/z_en_oe2.h b/src/overlays/actors/ovl_En_OE2/z_en_oe2.h
index 635495bb7..062e10381 100644
--- a/src/overlays/actors/ovl_En_OE2/z_en_oe2.h
+++ b/src/overlays/actors/ovl_En_OE2/z_en_oe2.h
@@ -2,11 +2,11 @@
#define Z_EN_OE2_H
#include "ultra64.h"
-#include "global.h"
+#include "z64actor.h"
struct EnOE2;
-typedef void (*EnOE2ActionFunc)(struct EnOE2*, PlayState*);
+typedef void (*EnOE2ActionFunc)(struct EnOE2*, struct PlayState*);
typedef struct EnOE2 {
/* 0x0000 */ Actor actor;
diff --git a/src/overlays/actors/ovl_En_Okarina_Effect/z_en_okarina_effect.c b/src/overlays/actors/ovl_En_Okarina_Effect/z_en_okarina_effect.c
index 6f5eda832..cb01d782e 100644
--- a/src/overlays/actors/ovl_En_Okarina_Effect/z_en_okarina_effect.c
+++ b/src/overlays/actors/ovl_En_Okarina_Effect/z_en_okarina_effect.c
@@ -11,11 +11,11 @@
#include "terminal.h"
#include "versions.h"
#include "z64audio.h"
+#include "z64cutscene_flags.h"
#include "z64debug_display.h"
#include "z64frame_advance.h"
#include "z64play.h"
-
-#include "global.h"
+#include "z64save.h"
#define FLAGS (ACTOR_FLAG_UPDATE_CULLING_DISABLED | ACTOR_FLAG_UPDATE_DURING_OCARINA)
diff --git a/src/overlays/actors/ovl_En_Okarina_Tag/z_en_okarina_tag.c b/src/overlays/actors/ovl_En_Okarina_Tag/z_en_okarina_tag.c
index 0e4460028..457a15b93 100644
--- a/src/overlays/actors/ovl_En_Okarina_Tag/z_en_okarina_tag.c
+++ b/src/overlays/actors/ovl_En_Okarina_Tag/z_en_okarina_tag.c
@@ -18,6 +18,7 @@
#include "z64ocarina.h"
#include "z64play.h"
#include "z64player.h"
+#include "z64save.h"
#include "assets/scenes/misc/hakaana_ouke/hakaana_ouke_scene.h"
#include "assets/scenes/overworld/spot02/spot02_scene.h"
diff --git a/src/overlays/actors/ovl_En_Okuta/z_en_okuta.c b/src/overlays/actors/ovl_En_Okuta/z_en_okuta.c
index ce8c8cfe0..c383e5927 100644
--- a/src/overlays/actors/ovl_En_Okuta/z_en_okuta.c
+++ b/src/overlays/actors/ovl_En_Okuta/z_en_okuta.c
@@ -11,6 +11,7 @@
#include "z64effect.h"
#include "z64play.h"
#include "z64player.h"
+#include "z64save.h"
#include "assets/objects/object_okuta/object_okuta.h"
#include "config.h"
diff --git a/src/overlays/actors/ovl_En_Ossan/z_en_ossan.c b/src/overlays/actors/ovl_En_Ossan/z_en_ossan.c
index bc93f8911..6955a7cbe 100644
--- a/src/overlays/actors/ovl_En_Ossan/z_en_ossan.c
+++ b/src/overlays/actors/ovl_En_Ossan/z_en_ossan.c
@@ -15,6 +15,7 @@
#include "z_lib.h"
#include "z64play.h"
#include "z64player.h"
+#include "z64save.h"
#include "widescreen.h"
#include "assets/objects/gameplay_keep/gameplay_keep.h"
diff --git a/src/overlays/actors/ovl_En_Owl/z_en_owl.c b/src/overlays/actors/ovl_En_Owl/z_en_owl.c
index 46696027f..827bf75c0 100644
--- a/src/overlays/actors/ovl_En_Owl/z_en_owl.c
+++ b/src/overlays/actors/ovl_En_Owl/z_en_owl.c
@@ -5,10 +5,29 @@
*/
#include "z_en_owl.h"
+
+#include "libc64/qrand.h"
+#include "gfx.h"
+#include "gfx_setupdl.h"
+#include "ichain.h"
+#include "one_point_cutscene.h"
+#include "rand.h"
+#include "segmented_address.h"
+#include "seqcmd.h"
+#include "sequence.h"
+#include "sfx.h"
+#include "sys_math3d.h"
+#include "sys_matrix.h"
+#include "terminal.h"
+#include "z_lib.h"
+#include "z64audio.h"
+#include "z64play.h"
+#include "z64player.h"
+#include "z64save.h"
+
#include "assets/objects/object_owl/object_owl.h"
#include "assets/scenes/overworld/spot06/spot06_scene.h"
#include "assets/scenes/overworld/spot16/spot16_scene.h"
-#include "terminal.h"
#define FLAGS (ACTOR_FLAG_ATTENTION_ENABLED | ACTOR_FLAG_FRIENDLY | ACTOR_FLAG_UPDATE_CULLING_DISABLED)
diff --git a/src/overlays/actors/ovl_En_Owl/z_en_owl.h b/src/overlays/actors/ovl_En_Owl/z_en_owl.h
index 4f92ef1b4..2f9e0939f 100644
--- a/src/overlays/actors/ovl_En_Owl/z_en_owl.h
+++ b/src/overlays/actors/ovl_En_Owl/z_en_owl.h
@@ -2,11 +2,11 @@
#define Z_EN_OWL_H
#include "ultra64.h"
-#include "global.h"
+#include "z64actor.h"
struct EnOwl;
-typedef void (*EnOwlActionFunc)(struct EnOwl*, PlayState*);
+typedef void (*EnOwlActionFunc)(struct EnOwl*, struct PlayState*);
typedef void (*OwlFunc)(struct EnOwl*);
typedef struct EnOwl {
diff --git a/src/overlays/actors/ovl_En_Peehat/z_en_peehat.c b/src/overlays/actors/ovl_En_Peehat/z_en_peehat.c
index adaf5e84d..2246b3df1 100644
--- a/src/overlays/actors/ovl_En_Peehat/z_en_peehat.c
+++ b/src/overlays/actors/ovl_En_Peehat/z_en_peehat.c
@@ -15,6 +15,7 @@
#include "z64effect.h"
#include "z64play.h"
#include "z64player.h"
+#include "z64save.h"
#include "assets/objects/object_peehat/object_peehat.h"
@@ -89,7 +90,7 @@ static ColliderCylinderInit sCylinderInit = {
{ 50, 160, -70, { 0, 0, 0 } },
};
-static ColliderJntSphElementInit sJntSphElemInit[1] = {
+static ColliderJntSphElementInit sJntSphElementsInit[1] = {
{
{
ELEM_MATERIAL_UNK0,
@@ -113,7 +114,7 @@ static ColliderJntSphInit sJntSphInit = {
COLSHAPE_JNTSPH,
},
1,
- sJntSphElemInit,
+ sJntSphElementsInit,
};
static ColliderQuadInit sQuadInit = {
@@ -218,12 +219,12 @@ void EnPeehat_Init(Actor* thisx, PlayState* play) {
this->actor.colChkInfo.health = 6;
this->actor.colChkInfo.damageTable = &sDamageTable;
this->actor.floorHeight = this->actor.world.pos.y;
- Collider_InitCylinder(play, &this->colCylinder);
- Collider_SetCylinder(play, &this->colCylinder, &this->actor, &sCylinderInit);
- Collider_InitQuad(play, &this->colQuad);
- Collider_SetQuad(play, &this->colQuad, &this->actor, &sQuadInit);
- Collider_InitJntSph(play, &this->colJntSph);
- Collider_SetJntSph(play, &this->colJntSph, &this->actor, &sJntSphInit, this->colJntSphItemList);
+ Collider_InitCylinder(play, &this->colliderCylinder);
+ Collider_SetCylinder(play, &this->colliderCylinder, &this->actor, &sCylinderInit);
+ Collider_InitQuad(play, &this->colliderQuad);
+ Collider_SetQuad(play, &this->colliderQuad, &this->actor, &sQuadInit);
+ Collider_InitJntSph(play, &this->colliderJntSph);
+ Collider_SetJntSph(play, &this->colliderJntSph, &this->actor, &sJntSphInit, this->colliderJntSphElements);
this->actor.naviEnemyId = NAVI_ENEMY_PEAHAT;
this->xzDistToRise = 740.0f;
@@ -245,12 +246,12 @@ void EnPeehat_Init(Actor* thisx, PlayState* play) {
case PEAHAT_TYPE_LARVA:
this->actor.scale.x = this->actor.scale.z = 0.006f;
this->actor.scale.y = 0.003f;
- this->colCylinder.dim.radius = 25;
- this->colCylinder.dim.height = 15;
- this->colCylinder.dim.yShift = -5;
- this->colCylinder.elem.acDmgInfo.dmgFlags = DMG_ARROW | DMG_SLINGSHOT;
- this->colQuad.base.atFlags = AT_ON | AT_TYPE_ENEMY;
- this->colQuad.base.acFlags = AC_ON | AC_TYPE_PLAYER;
+ this->colliderCylinder.dim.radius = 25;
+ this->colliderCylinder.dim.height = 15;
+ this->colliderCylinder.dim.yShift = -5;
+ this->colliderCylinder.elem.acDmgInfo.dmgFlags = DMG_ARROW | DMG_SLINGSHOT;
+ this->colliderQuad.base.atFlags = AT_ON | AT_TYPE_ENEMY;
+ this->colliderQuad.base.acFlags = AC_ON | AC_TYPE_PLAYER;
this->actor.naviEnemyId = NAVI_ENEMY_PEAHAT_LARVA;
EnPeehat_Larva_SetStateSeekPlayer(this);
break;
@@ -261,8 +262,8 @@ void EnPeehat_Destroy(Actor* thisx, PlayState* play) {
EnPeehat* this = (EnPeehat*)thisx;
EnPeehat* parent;
- Collider_DestroyCylinder(play, &this->colCylinder);
- Collider_DestroyJntSph(play, &this->colJntSph);
+ Collider_DestroyCylinder(play, &this->colliderCylinder);
+ Collider_DestroyJntSph(play, &this->colliderJntSph);
// If PEAHAT_TYPE_LARVA, decrement total larva spawned
if (this->actor.params > 0) {
@@ -295,7 +296,7 @@ void EnPeehat_SpawnDust(PlayState* play, EnPeehat* this, Vec3f* pos, f32 arg3, s
* Handles being hit when on the ground
*/
void EnPeehat_HitWhenGrounded(EnPeehat* this, PlayState* play) {
- this->colCylinder.base.acFlags &= ~AC_HIT;
+ this->colliderCylinder.base.acFlags &= ~AC_HIT;
if ((play->gameplayFrames & 0xF) == 0) {
Vec3f itemDropPos = this->actor.world.pos;
@@ -307,7 +308,7 @@ void EnPeehat_HitWhenGrounded(EnPeehat* this, PlayState* play) {
} else {
s32 i;
- this->colCylinder.base.acFlags &= ~AC_HIT;
+ this->colliderCylinder.base.acFlags &= ~AC_HIT;
for (i = MAX_LARVA - this->unk_2FA; i > 0; i--) {
Actor* larva =
Actor_SpawnAsChild(&play->actorCtx, &this->actor, play, ACTOR_EN_PEEHAT,
@@ -333,7 +334,7 @@ void EnPeehat_Ground_SetStateGround(EnPeehat* this) {
this->unk_2D4 = 0;
this->unk_2FA = 0;
this->state = PEAHAT_STATE_3;
- this->colCylinder.base.acFlags &= ~AC_HIT;
+ this->colliderCylinder.base.acFlags &= ~AC_HIT;
EnPeehat_SetupAction(this, EnPeehat_Ground_StateGround);
}
@@ -358,7 +359,7 @@ void EnPeehat_Ground_StateGround(EnPeehat* this, PlayState* play) {
} else {
Math_SmoothStepToF(&this->scaleShift, 0.0f, 1.0f, 0.005f, 0.0f);
}
- } else if (this->colCylinder.base.acFlags & AC_HIT) {
+ } else if (this->colliderCylinder.base.acFlags & AC_HIT) {
EnPeehat_HitWhenGrounded(this, play);
}
}
@@ -388,7 +389,7 @@ void EnPeehat_Flying_StateGrounded(EnPeehat* this, PlayState* play) {
} else {
Math_SmoothStepToF(&this->scaleShift, 0.0f, 1.0f, 0.005f, 0.0f);
}
- } else if (this->colCylinder.base.acFlags & AC_HIT) {
+ } else if (this->colliderCylinder.base.acFlags & AC_HIT) {
EnPeehat_HitWhenGrounded(this, play);
}
}
@@ -575,22 +576,22 @@ void EnPeehat_Larva_StateSeekPlayer(EnPeehat* this, PlayState* play) {
this->bladeRot += this->bladeRotVel;
Math_SmoothStepToF(&this->scaleShift, 0.075f, 1.0f, 0.005f, 0.0f);
Actor_PlaySfx(&this->actor, NA_SE_EN_PIHAT_SM_FLY - SFX_FLAG);
- if (this->colQuad.base.atFlags & AT_BOUNCED) {
+ if (this->colliderQuad.base.atFlags & AT_BOUNCED) {
this->actor.colChkInfo.health = 0;
- this->colQuad.base.acFlags &= ~AC_BOUNCED;
+ this->colliderQuad.base.acFlags &= ~AC_BOUNCED;
EnPeehat_SetStateAttackRecoil(this);
- } else if ((this->colQuad.base.atFlags & AT_HIT) || (this->colCylinder.base.acFlags & AC_HIT) ||
+ } else if ((this->colliderQuad.base.atFlags & AT_HIT) || (this->colliderCylinder.base.acFlags & AC_HIT) ||
(this->actor.bgCheckFlags & BGCHECKFLAG_GROUND)) {
Player* player = GET_PLAYER(play);
- this->colQuad.base.atFlags &= ~AT_HIT;
- if (!(this->colCylinder.base.acFlags & AC_HIT) && &player->actor == this->colQuad.base.at) {
+ this->colliderQuad.base.atFlags &= ~AT_HIT;
+ if (!(this->colliderCylinder.base.acFlags & AC_HIT) && &player->actor == this->colliderQuad.base.at) {
if (Rand_ZeroOne() > 0.5f) {
this->actor.world.rot.y += 0x2000;
} else {
this->actor.world.rot.y -= 0x2000;
}
this->unk_2D4 = 40;
- } else if (this->colCylinder.base.acFlags & AC_HIT || this->actor.bgCheckFlags & BGCHECKFLAG_GROUND) {
+ } else if (this->colliderCylinder.base.acFlags & AC_HIT || this->actor.bgCheckFlags & BGCHECKFLAG_GROUND) {
Vec3f zeroVec = { 0, 0, 0 };
s32 i;
for (i = 4; i >= 0; i--) {
@@ -601,7 +602,7 @@ void EnPeehat_Larva_StateSeekPlayer(EnPeehat* this, PlayState* play) {
EffectSsDeadDb_Spawn(play, &pos, &zeroVec, &zeroVec, 40, 7, 255, 255, 255, 255, 255, 0, 0, 1, 9, 1);
}
}
- if (&player->actor != this->colQuad.base.at || this->colCylinder.base.acFlags & AC_HIT) {
+ if (&player->actor != this->colliderQuad.base.at || this->colliderCylinder.base.acFlags & AC_HIT) {
if (!(this->actor.bgCheckFlags & BGCHECKFLAG_GROUND)) {
EffectSsDeadSound_SpawnStationary(play, &this->actor.projectedPos, NA_SE_EN_PIHAT_SM_DEAD, 1, 1, 40);
}
@@ -894,13 +895,13 @@ void EnPeehat_StateExplode(EnPeehat* this, PlayState* play) {
}
void EnPeehat_Adult_CollisionCheck(EnPeehat* this, PlayState* play) {
- if ((this->colCylinder.base.acFlags & AC_BOUNCED) || (this->colQuad.base.acFlags & AC_BOUNCED)) {
- this->colQuad.base.acFlags &= ~AC_BOUNCED;
- this->colCylinder.base.acFlags &= ~AC_BOUNCED;
- this->colJntSph.base.acFlags &= ~AC_HIT;
- } else if (this->colJntSph.base.acFlags & AC_HIT) {
- this->colJntSph.base.acFlags &= ~AC_HIT;
- Actor_SetDropFlagJntSph(&this->actor, &this->colJntSph, true);
+ if ((this->colliderCylinder.base.acFlags & AC_BOUNCED) || (this->colliderQuad.base.acFlags & AC_BOUNCED)) {
+ this->colliderQuad.base.acFlags &= ~AC_BOUNCED;
+ this->colliderCylinder.base.acFlags &= ~AC_BOUNCED;
+ this->colliderJntSph.base.acFlags &= ~AC_HIT;
+ } else if (this->colliderJntSph.base.acFlags & AC_HIT) {
+ this->colliderJntSph.base.acFlags &= ~AC_HIT;
+ Actor_SetDropFlagJntSph(&this->actor, &this->colliderJntSph, true);
if (this->actor.colChkInfo.damageEffect == PEAHAT_DMG_EFF_NUT ||
this->actor.colChkInfo.damageEffect == PEAHAT_DMG_EFF_LIGHT_ICE_ARROW) {
return;
@@ -963,9 +964,9 @@ void EnPeehat_Update(Actor* thisx, PlayState* play) {
// if PEAHAT_TYPE_GROUNDED
if (thisx->params < 0) {
// Set the Z-Target point on the Peahat's weak point
- thisx->focus.pos.x = this->colJntSph.elements[0].dim.worldSphere.center.x;
- thisx->focus.pos.y = this->colJntSph.elements[0].dim.worldSphere.center.y;
- thisx->focus.pos.z = this->colJntSph.elements[0].dim.worldSphere.center.z;
+ thisx->focus.pos.x = this->colliderJntSph.elements[0].dim.worldSphere.center.x;
+ thisx->focus.pos.y = this->colliderJntSph.elements[0].dim.worldSphere.center.y;
+ thisx->focus.pos.z = this->colliderJntSph.elements[0].dim.worldSphere.center.z;
if (this->state == PEAHAT_STATE_SEEK_PLAYER) {
Math_SmoothStepToS(&thisx->shape.rot.x, 6000, 1, 300, 0);
} else {
@@ -974,21 +975,21 @@ void EnPeehat_Update(Actor* thisx, PlayState* play) {
} else {
thisx->focus.pos = thisx->world.pos;
}
- Collider_UpdateCylinder(thisx, &this->colCylinder);
+ Collider_UpdateCylinder(thisx, &this->colliderCylinder);
if (thisx->colChkInfo.health > 0) {
// If Adult Peahat
if (thisx->params <= 0) {
- CollisionCheck_SetOC(play, &play->colChkCtx, &this->colCylinder.base);
- CollisionCheck_SetOC(play, &play->colChkCtx, &this->colJntSph.base);
+ CollisionCheck_SetOC(play, &play->colChkCtx, &this->colliderCylinder.base);
+ CollisionCheck_SetOC(play, &play->colChkCtx, &this->colliderJntSph.base);
if (thisx->colorFilterTimer == 0 || !(thisx->colorFilterParams & 0x4000)) {
if (this->state != PEAHAT_STATE_EXPLODE) {
- CollisionCheck_SetAC(play, &play->colChkCtx, &this->colJntSph.base);
+ CollisionCheck_SetAC(play, &play->colChkCtx, &this->colliderJntSph.base);
}
}
}
- if (thisx->params != PEAHAT_TYPE_FLYING && this->colQuad.base.atFlags & AT_HIT) {
- this->colQuad.base.atFlags &= ~AT_HIT;
- if (&player->actor == this->colQuad.base.at) {
+ if (thisx->params != PEAHAT_TYPE_FLYING && this->colliderQuad.base.atFlags & AT_HIT) {
+ this->colliderQuad.base.atFlags &= ~AT_HIT;
+ if (&player->actor == this->colliderQuad.base.at) {
EnPeehat_SetStateAttackRecoil(this);
}
}
@@ -996,8 +997,8 @@ void EnPeehat_Update(Actor* thisx, PlayState* play) {
if (this->state == PEAHAT_STATE_15 || this->state == PEAHAT_STATE_SEEK_PLAYER || this->state == PEAHAT_STATE_FLY ||
this->state == PEAHAT_STATE_RETURN_HOME || this->state == PEAHAT_STATE_EXPLODE) {
if (thisx->params != PEAHAT_TYPE_FLYING) {
- CollisionCheck_SetAT(play, &play->colChkCtx, &this->colQuad.base);
- CollisionCheck_SetAC(play, &play->colChkCtx, &this->colQuad.base);
+ CollisionCheck_SetAT(play, &play->colChkCtx, &this->colliderQuad.base);
+ CollisionCheck_SetAC(play, &play->colChkCtx, &this->colliderQuad.base);
}
// if PEAHAT_TYPE_GROUNDED
if (thisx->params < 0 && (thisx->flags & ACTOR_FLAG_INSIDE_CULLING_VOLUME)) {
@@ -1012,10 +1013,10 @@ void EnPeehat_Update(Actor* thisx, PlayState* play) {
}
}
} else if (thisx->params != PEAHAT_TYPE_FLYING) {
- CollisionCheck_SetAC(play, &play->colChkCtx, &this->colCylinder.base);
+ CollisionCheck_SetAC(play, &play->colChkCtx, &this->colliderCylinder.base);
}
} else {
- CollisionCheck_SetAC(play, &play->colChkCtx, &this->colCylinder.base);
+ CollisionCheck_SetAC(play, &play->colChkCtx, &this->colliderCylinder.base);
}
Math_SmoothStepToF(&this->scaleShift, 0.0f, 1.0f, 0.001f, 0.0f);
}
@@ -1064,7 +1065,7 @@ void EnPeehat_PostLimbDraw(PlayState* play, s32 limbIndex, Gfx** dList, Vec3s* r
OPEN_DISPS(play->state.gfxCtx, "../z_en_peehat.c", 1981);
Matrix_Push();
Matrix_Translate(-1000.0f, 0.0f, 0.0f, MTXMODE_APPLY);
- Collider_UpdateSpheres(0, &this->colJntSph);
+ Collider_UpdateSpheres(0, &this->colliderJntSph);
Matrix_Translate(500.0f, 0.0f, 0.0f, MTXMODE_APPLY);
if (this->actor.colorFilterTimer != 0 && (this->actor.colorFilterParams & 0x4000)) {
damageYRot = Math_SinS(this->actor.colorFilterTimer * 0x4E20) * 0.35f;
@@ -1088,11 +1089,11 @@ void EnPeehat_Draw(Actor* thisx, PlayState* play) {
SkelAnime_DrawOpa(play, this->skelAnime.skeleton, this->skelAnime.jointTable, EnPeehat_OverrideLimbDraw,
EnPeehat_PostLimbDraw, this);
if (this->actor.speed != 0.0f || this->actor.velocity.y != 0.0f) {
- Matrix_MultVec3f(&D_80AD285C[0], &this->colQuad.dim.quad[1]);
- Matrix_MultVec3f(&D_80AD285C[1], &this->colQuad.dim.quad[0]);
- Matrix_MultVec3f(&D_80AD285C[2], &this->colQuad.dim.quad[3]);
- Matrix_MultVec3f(&D_80AD285C[3], &this->colQuad.dim.quad[2]);
- Collider_SetQuadVertices(&this->colQuad, &this->colQuad.dim.quad[0], &this->colQuad.dim.quad[1],
- &this->colQuad.dim.quad[2], &this->colQuad.dim.quad[3]);
+ Matrix_MultVec3f(&D_80AD285C[0], &this->colliderQuad.dim.quad[1]);
+ Matrix_MultVec3f(&D_80AD285C[1], &this->colliderQuad.dim.quad[0]);
+ Matrix_MultVec3f(&D_80AD285C[2], &this->colliderQuad.dim.quad[3]);
+ Matrix_MultVec3f(&D_80AD285C[3], &this->colliderQuad.dim.quad[2]);
+ Collider_SetQuadVertices(&this->colliderQuad, &this->colliderQuad.dim.quad[0], &this->colliderQuad.dim.quad[1],
+ &this->colliderQuad.dim.quad[2], &this->colliderQuad.dim.quad[3]);
}
}
diff --git a/src/overlays/actors/ovl_En_Peehat/z_en_peehat.h b/src/overlays/actors/ovl_En_Peehat/z_en_peehat.h
index a10bff420..deb24089f 100644
--- a/src/overlays/actors/ovl_En_Peehat/z_en_peehat.h
+++ b/src/overlays/actors/ovl_En_Peehat/z_en_peehat.h
@@ -38,10 +38,10 @@ typedef struct EnPeehat {
/* 0x02FA */ s16 unk_2FA; // larva count (PEAHAT_TYPE_FLYING, PEAHAT_TYPE_GROUNDED),
// shape rotation direction (PEAHAT_TYPE_GROUNDED)
/* 0x02FC */ s16 animTimer;
- /* 0x0300 */ ColliderCylinder colCylinder;
- /* 0x034C */ ColliderJntSph colJntSph;
- /* 0x036C */ ColliderJntSphElement colJntSphItemList[1];
- /* 0x03AC */ ColliderQuad colQuad;
+ /* 0x0300 */ ColliderCylinder colliderCylinder;
+ /* 0x034C */ ColliderJntSph colliderJntSph;
+ /* 0x036C */ ColliderJntSphElement colliderJntSphElements[1];
+ /* 0x03AC */ ColliderQuad colliderQuad;
} EnPeehat; // size = 0x042C
#endif
diff --git a/src/overlays/actors/ovl_En_Po_Desert/z_en_po_desert.c b/src/overlays/actors/ovl_En_Po_Desert/z_en_po_desert.c
index fefa80aec..57ef9a85b 100644
--- a/src/overlays/actors/ovl_En_Po_Desert/z_en_po_desert.c
+++ b/src/overlays/actors/ovl_En_Po_Desert/z_en_po_desert.c
@@ -5,6 +5,18 @@
*/
#include "z_en_po_desert.h"
+
+#include "libc64/qrand.h"
+#include "gfx.h"
+#include "gfx_setupdl.h"
+#include "ichain.h"
+#include "segmented_address.h"
+#include "sfx.h"
+#include "sys_matrix.h"
+#include "z_lib.h"
+#include "z64light.h"
+#include "z64play.h"
+
#include "assets/objects/object_po_field/object_po_field.h"
#define FLAGS (ACTOR_FLAG_UPDATE_CULLING_DISABLED | ACTOR_FLAG_REACT_TO_LENS | ACTOR_FLAG_IGNORE_QUAKE)
diff --git a/src/overlays/actors/ovl_En_Po_Desert/z_en_po_desert.h b/src/overlays/actors/ovl_En_Po_Desert/z_en_po_desert.h
index aeb2503ed..3f93eeb01 100644
--- a/src/overlays/actors/ovl_En_Po_Desert/z_en_po_desert.h
+++ b/src/overlays/actors/ovl_En_Po_Desert/z_en_po_desert.h
@@ -2,11 +2,12 @@
#define Z_EN_PO_DESERT_H
#include "ultra64.h"
-#include "global.h"
+#include "z64actor.h"
+#include "z64light.h"
struct EnPoDesert;
-typedef void (*EnPoDesertActionFunc)(struct EnPoDesert*, PlayState*);
+typedef void (*EnPoDesertActionFunc)(struct EnPoDesert*, struct PlayState*);
typedef struct EnPoDesert {
/* 0x0000 */ Actor actor;
diff --git a/src/overlays/actors/ovl_En_Po_Field/z_en_po_field.c b/src/overlays/actors/ovl_En_Po_Field/z_en_po_field.c
index 00eff4a39..30218e20e 100644
--- a/src/overlays/actors/ovl_En_Po_Field/z_en_po_field.c
+++ b/src/overlays/actors/ovl_En_Po_Field/z_en_po_field.c
@@ -5,6 +5,21 @@
*/
#include "z_en_po_field.h"
+
+#include "libc64/qrand.h"
+#include "gfx.h"
+#include "gfx_setupdl.h"
+#include "ichain.h"
+#include "segmented_address.h"
+#include "sfx.h"
+#include "sys_matrix.h"
+#include "z_lib.h"
+#include "z64effect.h"
+#include "z64light.h"
+#include "z64play.h"
+#include "z64player.h"
+#include "z64save.h"
+
#include "assets/objects/gameplay_keep/gameplay_keep.h"
#include "assets/objects/object_po_field/object_po_field.h"
@@ -143,8 +158,8 @@ static EnPoFieldInfo sPoFieldInfo[2] = {
static Vec3f D_80AD714C = { 0.0f, 1400.0f, 0.0f };
-#pragma increment_block_number "gc-jp:128 gc-jp-ce:128 gc-jp-mq:128 gc-us:128 gc-us-mq:128 ntsc-1.2:128 pal-1.0:128" \
- "pal-1.1:128"
+#pragma increment_block_number "gc-jp:128 gc-jp-ce:128 gc-jp-mq:128 gc-us:128 gc-us-mq:128 ntsc-1.0:128 ntsc-1.1:128" \
+ "ntsc-1.2:128 pal-1.0:128 pal-1.1:128"
static Vec3s sSpawnPositions[10];
static u8 sSpawnSwitchFlags[10];
diff --git a/src/overlays/actors/ovl_En_Po_Field/z_en_po_field.h b/src/overlays/actors/ovl_En_Po_Field/z_en_po_field.h
index f07a9233d..17e08ee99 100644
--- a/src/overlays/actors/ovl_En_Po_Field/z_en_po_field.h
+++ b/src/overlays/actors/ovl_En_Po_Field/z_en_po_field.h
@@ -2,11 +2,12 @@
#define Z_EN_PO_FIELD_H
#include "ultra64.h"
-#include "global.h"
+#include "z64actor.h"
+#include "z64light.h"
struct EnPoField;
-typedef void (*EnPoFieldActionFunc)(struct EnPoField*, PlayState*);
+typedef void (*EnPoFieldActionFunc)(struct EnPoField*, struct PlayState*);
typedef enum EnPoFieldSize {
EN_PO_FIELD_SMALL,
diff --git a/src/overlays/actors/ovl_En_Po_Relay/z_en_po_relay.c b/src/overlays/actors/ovl_En_Po_Relay/z_en_po_relay.c
index a0f605204..983dbf0d7 100644
--- a/src/overlays/actors/ovl_En_Po_Relay/z_en_po_relay.c
+++ b/src/overlays/actors/ovl_En_Po_Relay/z_en_po_relay.c
@@ -21,6 +21,7 @@
#include "z64light.h"
#include "z64play.h"
#include "z64player.h"
+#include "z64save.h"
#include "assets/objects/object_tk/object_tk.h"
diff --git a/src/overlays/actors/ovl_En_Po_Sisters/z_en_po_sisters.c b/src/overlays/actors/ovl_En_Po_Sisters/z_en_po_sisters.c
index 1b549f772..0f24ad4d0 100644
--- a/src/overlays/actors/ovl_En_Po_Sisters/z_en_po_sisters.c
+++ b/src/overlays/actors/ovl_En_Po_Sisters/z_en_po_sisters.c
@@ -22,8 +22,6 @@
#include "z64play.h"
#include "z64player.h"
-#include "global.h"
-
#include "assets/objects/gameplay_keep/gameplay_keep.h"
#include "assets/objects/object_po_sisters/object_po_sisters.h"
diff --git a/src/overlays/actors/ovl_En_Poh/z_en_poh.c b/src/overlays/actors/ovl_En_Poh/z_en_poh.c
index 2deead514..fceb18ef7 100644
--- a/src/overlays/actors/ovl_En_Poh/z_en_poh.c
+++ b/src/overlays/actors/ovl_En_Poh/z_en_poh.c
@@ -18,8 +18,7 @@
#include "z64light.h"
#include "z64play.h"
#include "z64player.h"
-
-#include "global.h"
+#include "z64save.h"
#include "assets/objects/object_poh/object_poh.h"
#include "assets/objects/object_po_composer/object_po_composer.h"
@@ -91,7 +90,7 @@ static ColliderCylinderInit sCylinderInit = {
{ 20, 40, 20, { 0, 0, 0 } },
};
-static ColliderJntSphElementInit D_80AE1AA0[1] = {
+static ColliderJntSphElementInit sJntSphElementsInit[1] = {
{
{
ELEM_MATERIAL_UNK0,
@@ -115,7 +114,7 @@ static ColliderJntSphInit sJntSphInit = {
COLSHAPE_JNTSPH,
},
1,
- D_80AE1AA0,
+ sJntSphElementsInit,
};
static CollisionCheckInfoInit sColChkInfoInit = { 4, 25, 50, 40 };
@@ -205,14 +204,14 @@ void EnPoh_Init(Actor* thisx, PlayState* play) {
Actor_ProcessInitChain(&this->actor, sInitChain);
ActorShape_Init(&this->actor.shape, 0.0f, ActorShadow_DrawCircle, 30.0f);
- Collider_InitJntSph(play, &this->colliderSph);
- Collider_SetJntSph(play, &this->colliderSph, &this->actor, &sJntSphInit, &this->colliderSphItem);
- this->colliderSph.elements[0].dim.worldSphere.radius = 0;
- this->colliderSph.elements[0].dim.worldSphere.center.x = this->actor.world.pos.x;
- this->colliderSph.elements[0].dim.worldSphere.center.y = this->actor.world.pos.y;
- this->colliderSph.elements[0].dim.worldSphere.center.z = this->actor.world.pos.z;
- Collider_InitCylinder(play, &this->colliderCyl);
- Collider_SetCylinder(play, &this->colliderCyl, &this->actor, &sCylinderInit);
+ Collider_InitJntSph(play, &this->colliderJntSph);
+ Collider_SetJntSph(play, &this->colliderJntSph, &this->actor, &sJntSphInit, this->colliderJntSphElements);
+ this->colliderJntSph.elements[0].dim.worldSphere.radius = 0;
+ this->colliderJntSph.elements[0].dim.worldSphere.center.x = this->actor.world.pos.x;
+ this->colliderJntSph.elements[0].dim.worldSphere.center.y = this->actor.world.pos.y;
+ this->colliderJntSph.elements[0].dim.worldSphere.center.z = this->actor.world.pos.z;
+ Collider_InitCylinder(play, &this->colliderCylinder);
+ Collider_SetCylinder(play, &this->colliderCylinder, &this->actor, &sCylinderInit);
CollisionCheck_SetInfo(&this->actor.colChkInfo, &sDamageTable, &sColChkInfoInit);
this->unk_194 = 0;
this->unk_195 = 32;
@@ -265,8 +264,8 @@ void EnPoh_Destroy(Actor* thisx, PlayState* play) {
EnPoh* this = (EnPoh*)thisx;
LightContext_RemoveLight(play, &play->lightCtx, this->lightNode);
- Collider_DestroyJntSph(play, &this->colliderSph);
- Collider_DestroyCylinder(play, &this->colliderCyl);
+ Collider_DestroyJntSph(play, &this->colliderJntSph);
+ Collider_DestroyCylinder(play, &this->colliderCylinder);
if (this->actor.params == EN_POH_RUPEE) {
D_80AE1A50--;
}
@@ -310,12 +309,12 @@ void func_80ADE28C(EnPoh* this) {
} else {
Animation_PlayOnce(&this->skelAnime, &gPoeComposerDamagedAnim);
}
- if (this->colliderCyl.elem.acHitElem->atDmgInfo.dmgFlags & (DMG_ARROW | DMG_SLINGSHOT)) {
- this->actor.world.rot.y = this->colliderCyl.base.ac->world.rot.y;
+ if (this->colliderCylinder.elem.acHitElem->atDmgInfo.dmgFlags & (DMG_ARROW | DMG_SLINGSHOT)) {
+ this->actor.world.rot.y = this->colliderCylinder.base.ac->world.rot.y;
} else {
- this->actor.world.rot.y = Actor_WorldYawTowardActor(&this->actor, this->colliderCyl.base.ac) + 0x8000;
+ this->actor.world.rot.y = Actor_WorldYawTowardActor(&this->actor, this->colliderCylinder.base.ac) + 0x8000;
}
- this->colliderCyl.base.acFlags &= ~AC_ON;
+ this->colliderCylinder.base.acFlags &= ~AC_ON;
this->actor.speed = 5.0f;
Actor_SetColorFilter(&this->actor, COLORFILTER_COLORFLAG_RED, 255, COLORFILTER_BUFFLAG_OPA, 16);
this->actionFunc = func_80ADEECC;
@@ -325,7 +324,7 @@ void func_80ADE368(EnPoh* this) {
Animation_MorphToLoop(&this->skelAnime, this->info->fleeAnim, -5.0f);
this->actor.speed = 5.0f;
this->actor.world.rot.y = this->actor.shape.rot.y + 0x8000;
- this->colliderCyl.base.acFlags |= AC_ON;
+ this->colliderCylinder.base.acFlags |= AC_ON;
this->unk_198 = 200;
this->actionFunc = func_80ADF894;
}
@@ -429,13 +428,13 @@ void func_80ADE6D4(EnPoh* this) {
void EnPoh_Talk(EnPoh* this, PlayState* play) {
this->actor.home.pos.y = this->actor.world.pos.y;
Actor_SetFocus(&this->actor, -10.0f);
- this->colliderCyl.dim.radius = 13;
- this->colliderCyl.dim.height = 30;
- this->colliderCyl.dim.yShift = 0;
- this->colliderCyl.dim.pos.x = this->actor.world.pos.x;
- this->colliderCyl.dim.pos.y = this->actor.world.pos.y - 20.0f;
- this->colliderCyl.dim.pos.z = this->actor.world.pos.z;
- this->colliderCyl.base.ocFlags1 = OC1_ON | OC1_TYPE_PLAYER;
+ this->colliderCylinder.dim.radius = 13;
+ this->colliderCylinder.dim.height = 30;
+ this->colliderCylinder.dim.yShift = 0;
+ this->colliderCylinder.dim.pos.x = this->actor.world.pos.x;
+ this->colliderCylinder.dim.pos.y = this->actor.world.pos.y - 20.0f;
+ this->colliderCylinder.dim.pos.z = this->actor.world.pos.z;
+ this->colliderCylinder.base.ocFlags1 = OC1_ON | OC1_TYPE_PLAYER;
if (this->actor.params == EN_POH_FLAT || this->actor.params == EN_POH_SHARP) {
if (CHECK_QUEST_ITEM(QUEST_SONG_SUN)) {
this->actor.textId = 0x5000;
@@ -793,12 +792,12 @@ void func_80ADFE80(EnPoh* this, PlayState* play) {
this->actor.flags &= ~ACTOR_FLAG_TALK_OFFER_AUTO_ACCEPTED;
return;
}
- if (this->colliderCyl.base.ocFlags1 & OC1_HIT) {
+ if (this->colliderCylinder.base.ocFlags1 & OC1_HIT) {
this->actor.flags |= ACTOR_FLAG_TALK_OFFER_AUTO_ACCEPTED;
Actor_OfferTalkNearColChkInfoCylinder(&this->actor, play);
} else {
this->actor.flags &= ~ACTOR_FLAG_TALK_OFFER_AUTO_ACCEPTED;
- CollisionCheck_SetOC(play, &play->colChkCtx, &this->colliderCyl.base);
+ CollisionCheck_SetOC(play, &play->colChkCtx, &this->colliderCylinder.base);
}
this->actor.world.pos.y = Math_SinS(this->unk_195 * 0x800) * 5.0f + this->actor.home.pos.y;
if (this->unk_195 != 0) {
@@ -807,7 +806,7 @@ void func_80ADFE80(EnPoh* this, PlayState* play) {
if (this->unk_195 == 0) {
this->unk_195 = 32;
}
- this->colliderCyl.dim.pos.y = this->actor.world.pos.y - 20.0f;
+ this->colliderCylinder.dim.pos.y = this->actor.world.pos.y - 20.0f;
Actor_SetFocus(&this->actor, -10.0f);
Lights_PointNoGlowSetInfo(&this->lightInfo, this->actor.world.pos.x, this->actor.world.pos.y,
this->actor.world.pos.z, this->info->lightColor.r, this->info->lightColor.g,
@@ -879,8 +878,8 @@ void EnPoh_TalkComposer(EnPoh* this, PlayState* play) {
}
void func_80AE032C(EnPoh* this, PlayState* play) {
- if (this->colliderCyl.base.acFlags & AC_HIT) {
- this->colliderCyl.base.acFlags &= ~AC_HIT;
+ if (this->colliderCylinder.base.acFlags & AC_HIT) {
+ this->colliderCylinder.base.acFlags &= ~AC_HIT;
if (this->actor.colChkInfo.damageEffect != 0 || this->actor.colChkInfo.damage != 0) {
if (Actor_ApplyDamage(&this->actor) == 0) {
Enemy_StartFinishingBlow(play, &this->actor);
@@ -934,12 +933,12 @@ void EnPoh_Update(Actor* thisx, PlayState* play) {
SkelAnime_InitFlex(play, &this->skelAnime, &gPoeComposerSkel, &gPoeComposerFloatAnim, this->jointTable,
this->morphTable, 12);
this->actor.draw = EnPoh_DrawComposer;
- this->colliderSph.elements[0].dim.limb = 9;
- this->colliderSph.elements[0].dim.modelSphere.center.y *= -1;
+ this->colliderJntSph.elements[0].dim.limb = 9;
+ this->colliderJntSph.elements[0].dim.modelSphere.center.y *= -1;
this->actor.shape.rot.y = this->actor.world.rot.y = -0x4000;
- this->colliderCyl.dim.radius = 20;
- this->colliderCyl.dim.height = 55;
- this->colliderCyl.dim.yShift = 15;
+ this->colliderCylinder.dim.radius = 20;
+ this->colliderCylinder.dim.height = 55;
+ this->colliderCylinder.dim.yShift = 15;
}
this->actor.flags &= ~ACTOR_FLAG_UPDATE_CULLING_DISABLED;
EnPoh_SetupInitialAction(this);
@@ -1004,8 +1003,8 @@ void EnPoh_UpdateLiving(Actor* thisx, PlayState* play) {
Vec3f checkPos;
s32 bgId;
- if (this->colliderSph.base.atFlags & AT_HIT) {
- this->colliderSph.base.atFlags &= ~AT_HIT;
+ if (this->colliderJntSph.base.atFlags & AT_HIT) {
+ this->colliderJntSph.base.atFlags &= ~AT_HIT;
func_80ADE4C8(this);
}
func_80AE032C(this, play);
@@ -1014,14 +1013,14 @@ void EnPoh_UpdateLiving(Actor* thisx, PlayState* play) {
Actor_MoveXZGravity(&this->actor);
if (this->actionFunc == EnPoh_Attack && this->unk_198 < 10) {
this->actor.flags |= ACTOR_FLAG_SFX_FOR_PLAYER_BODY_HIT;
- CollisionCheck_SetAT(play, &play->colChkCtx, &this->colliderSph.base);
+ CollisionCheck_SetAT(play, &play->colChkCtx, &this->colliderJntSph.base);
}
- Collider_UpdateCylinder(&this->actor, &this->colliderCyl);
- if ((this->colliderCyl.base.acFlags & AC_ON) && this->lightColor.a == 255) {
- CollisionCheck_SetAC(play, &play->colChkCtx, &this->colliderCyl.base);
+ Collider_UpdateCylinder(&this->actor, &this->colliderCylinder);
+ if ((this->colliderCylinder.base.acFlags & AC_ON) && this->lightColor.a == 255) {
+ CollisionCheck_SetAC(play, &play->colChkCtx, &this->colliderCylinder.base);
}
- CollisionCheck_SetOC(play, &play->colChkCtx, &this->colliderCyl.base);
- CollisionCheck_SetOC(play, &play->colChkCtx, &this->colliderSph.base);
+ CollisionCheck_SetOC(play, &play->colChkCtx, &this->colliderCylinder.base);
+ CollisionCheck_SetOC(play, &play->colChkCtx, &this->colliderJntSph.base);
Actor_SetFocus(&this->actor, 42.0f);
if (this->actionFunc != func_80ADEECC && this->actionFunc != func_80ADF574) {
if (this->actionFunc == func_80ADF894) {
@@ -1060,7 +1059,7 @@ s32 EnPoh_OverrideLimbDraw(PlayState* play, s32 limbIndex, Gfx** dList, Vec3f* p
void EnPoh_PostLimbDraw(PlayState* play, s32 limbIndex, Gfx** dList, Vec3s* rot, void* thisx, Gfx** gfxP) {
EnPoh* this = (EnPoh*)thisx;
- Collider_UpdateSpheres(limbIndex, &this->colliderSph);
+ Collider_UpdateSpheres(limbIndex, &this->colliderJntSph);
if (this->actionFunc == func_80ADF15C && this->unk_198 >= 2 && limbIndex == this->info->unk_7) {
MATRIX_FINALIZE_AND_LOAD((*gfxP)++, play->state.gfxCtx, "../z_en_poh.c", 2460);
gSPDisplayList((*gfxP)++, this->info->burnDisplayList);
@@ -1076,9 +1075,9 @@ void EnPoh_PostLimbDraw(PlayState* play, s32 limbIndex, Gfx** dList, Vec3s* rot,
this->actor.world.pos.y = this->unk_368.yw;
this->actor.world.pos.z = this->unk_368.zw;
}
- Lights_PointGlowSetInfo(&this->lightInfo, this->colliderSph.elements[0].dim.worldSphere.center.x,
- this->colliderSph.elements[0].dim.worldSphere.center.y,
- this->colliderSph.elements[0].dim.worldSphere.center.z, this->envColor.r,
+ Lights_PointGlowSetInfo(&this->lightInfo, this->colliderJntSph.elements[0].dim.worldSphere.center.x,
+ this->colliderJntSph.elements[0].dim.worldSphere.center.y,
+ this->colliderJntSph.elements[0].dim.worldSphere.center.z, this->envColor.r,
this->envColor.g, this->envColor.b, this->envColor.a * (200.0f / 255));
}
}
diff --git a/src/overlays/actors/ovl_En_Poh/z_en_poh.h b/src/overlays/actors/ovl_En_Poh/z_en_poh.h
index 93dd40e17..7e7db7d99 100644
--- a/src/overlays/actors/ovl_En_Poh/z_en_poh.h
+++ b/src/overlays/actors/ovl_En_Poh/z_en_poh.h
@@ -54,9 +54,9 @@ typedef struct EnPoh {
/* 0x02A4 */ EnPohInfo* info;
/* 0x02A8 */ LightNode* lightNode;
/* 0x02AC */ LightInfo lightInfo;
- /* 0x02BC */ ColliderCylinder colliderCyl;
- /* 0x0308 */ ColliderJntSph colliderSph;
- /* 0x0328 */ ColliderJntSphElement colliderSphItem;
+ /* 0x02BC */ ColliderCylinder colliderCylinder;
+ /* 0x0308 */ ColliderJntSph colliderJntSph;
+ /* 0x0328 */ ColliderJntSphElement colliderJntSphElements[1];
/* 0x0368 */ MtxF unk_368;
} EnPoh; // size = 0x03A8
diff --git a/src/overlays/actors/ovl_En_Pu_box/z_en_pu_box.c b/src/overlays/actors/ovl_En_Pu_box/z_en_pu_box.c
index 495046f95..e984f316f 100644
--- a/src/overlays/actors/ovl_En_Pu_box/z_en_pu_box.c
+++ b/src/overlays/actors/ovl_En_Pu_box/z_en_pu_box.c
@@ -5,6 +5,11 @@
*/
#include "z_en_pu_box.h"
+
+#include "sfx.h"
+#include "z_lib.h"
+#include "z64play.h"
+
#include "assets/objects/object_pu_box/object_pu_box.h"
#define FLAGS ACTOR_FLAG_UPDATE_CULLING_DISABLED
diff --git a/src/overlays/actors/ovl_En_Pu_box/z_en_pu_box.h b/src/overlays/actors/ovl_En_Pu_box/z_en_pu_box.h
index 0aa0aaaf4..cd15c66c1 100644
--- a/src/overlays/actors/ovl_En_Pu_box/z_en_pu_box.h
+++ b/src/overlays/actors/ovl_En_Pu_box/z_en_pu_box.h
@@ -2,7 +2,7 @@
#define Z_EN_PU_BOX_H
#include "ultra64.h"
-#include "global.h"
+#include "z64actor.h"
struct EnPubox;
diff --git a/src/overlays/actors/ovl_En_Rd/z_en_rd.c b/src/overlays/actors/ovl_En_Rd/z_en_rd.c
index b73551405..af9ed8f11 100644
--- a/src/overlays/actors/ovl_En_Rd/z_en_rd.c
+++ b/src/overlays/actors/ovl_En_Rd/z_en_rd.c
@@ -19,8 +19,7 @@
#include "z64effect.h"
#include "z64play.h"
#include "z64player.h"
-
-#include "global.h"
+#include "z64save.h"
#include "assets/objects/object_rd/object_rd.h"
diff --git a/src/overlays/actors/ovl_En_River_Sound/z_en_river_sound.c b/src/overlays/actors/ovl_En_River_Sound/z_en_river_sound.c
index a3861adec..871cf6668 100644
--- a/src/overlays/actors/ovl_En_River_Sound/z_en_river_sound.c
+++ b/src/overlays/actors/ovl_En_River_Sound/z_en_river_sound.c
@@ -6,6 +6,15 @@
#include "z_en_river_sound.h"
+#include "segmented_address.h"
+#include "sequence.h"
+#include "sfx.h"
+#include "z_lib.h"
+#include "z64audio.h"
+#include "z64play.h"
+#include "z64player.h"
+#include "z64save.h"
+
#define FLAGS (ACTOR_FLAG_UPDATE_CULLING_DISABLED | ACTOR_FLAG_DRAW_CULLING_DISABLED)
void EnRiverSound_Init(Actor* thisx, PlayState* play);
diff --git a/src/overlays/actors/ovl_En_River_Sound/z_en_river_sound.h b/src/overlays/actors/ovl_En_River_Sound/z_en_river_sound.h
index c64718521..4332af602 100644
--- a/src/overlays/actors/ovl_En_River_Sound/z_en_river_sound.h
+++ b/src/overlays/actors/ovl_En_River_Sound/z_en_river_sound.h
@@ -2,7 +2,7 @@
#define Z_EN_RIVER_SOUND_H
#include "ultra64.h"
-#include "global.h"
+#include "z64actor.h"
struct EnRiverSound;
diff --git a/src/overlays/actors/ovl_En_Rl/z_en_rl.c b/src/overlays/actors/ovl_En_Rl/z_en_rl.c
index 6d79ef628..56e27591f 100644
--- a/src/overlays/actors/ovl_En_Rl/z_en_rl.c
+++ b/src/overlays/actors/ovl_En_Rl/z_en_rl.c
@@ -5,7 +5,17 @@
*/
#include "z_en_rl.h"
+
+#include "gfx.h"
+#include "gfx_setupdl.h"
+#include "regs.h"
+#include "segmented_address.h"
#include "terminal.h"
+#include "z_lib.h"
+#include "z64play.h"
+#include "z64player.h"
+#include "z64save.h"
+
#include "assets/objects/object_rl/object_rl.h"
#define FLAGS ACTOR_FLAG_UPDATE_CULLING_DISABLED
diff --git a/src/overlays/actors/ovl_En_Rl/z_en_rl.h b/src/overlays/actors/ovl_En_Rl/z_en_rl.h
index 9aa6b9ae6..9ce9949aa 100644
--- a/src/overlays/actors/ovl_En_Rl/z_en_rl.h
+++ b/src/overlays/actors/ovl_En_Rl/z_en_rl.h
@@ -2,12 +2,12 @@
#define Z_EN_RL_H
#include "ultra64.h"
-#include "global.h"
+#include "z64actor.h"
struct EnRl;
-typedef void (*EnRlActionFunc)(struct EnRl*, PlayState*);
-typedef void (*EnRlDrawFunc)(struct EnRl*, PlayState*);
+typedef void (*EnRlActionFunc)(struct EnRl*, struct PlayState*);
+typedef void (*EnRlDrawFunc)(struct EnRl*, struct PlayState*);
typedef struct EnRl {
/* 0x0000 */ Actor actor;
diff --git a/src/overlays/actors/ovl_En_Rr/z_en_rr.c b/src/overlays/actors/ovl_En_Rr/z_en_rr.c
index f252b8d08..07bb91664 100644
--- a/src/overlays/actors/ovl_En_Rr/z_en_rr.c
+++ b/src/overlays/actors/ovl_En_Rr/z_en_rr.c
@@ -21,6 +21,7 @@
#include "z64effect.h"
#include "z64play.h"
#include "z64player.h"
+#include "z64save.h"
#include "assets/objects/object_rr/object_rr.h"
diff --git a/src/overlays/actors/ovl_En_Ru1/z_en_ru1.c b/src/overlays/actors/ovl_En_Ru1/z_en_ru1.c
index 3586ed73d..16bc86f02 100644
--- a/src/overlays/actors/ovl_En_Ru1/z_en_ru1.c
+++ b/src/overlays/actors/ovl_En_Ru1/z_en_ru1.c
@@ -5,10 +5,27 @@
*/
#include "z_en_ru1.h"
-#include "assets/objects/object_ru1/object_ru1.h"
+#include "overlays/actors/ovl_Demo_Effect/z_demo_effect.h"
+
+#include "libc64/math64.h"
+#include "gfx.h"
+#include "gfx_setupdl.h"
+#include "regs.h"
+#include "segmented_address.h"
+#include "seqcmd.h"
+#include "sequence.h"
+#include "sfx.h"
+#include "sys_matrix.h"
#include "terminal.h"
#include "versions.h"
-#include "overlays/actors/ovl_Demo_Effect/z_demo_effect.h"
+#include "z_lib.h"
+#include "z64effect.h"
+#include "z64face_reaction.h"
+#include "z64play.h"
+#include "z64player.h"
+#include "z64save.h"
+
+#include "assets/objects/object_ru1/object_ru1.h"
#define FLAGS (ACTOR_FLAG_ATTENTION_ENABLED | ACTOR_FLAG_UPDATE_CULLING_DISABLED | ACTOR_FLAG_CAN_PRESS_SWITCHES)
diff --git a/src/overlays/actors/ovl_En_Ru1/z_en_ru1.h b/src/overlays/actors/ovl_En_Ru1/z_en_ru1.h
index 8223bfda4..8778174ef 100644
--- a/src/overlays/actors/ovl_En_Ru1/z_en_ru1.h
+++ b/src/overlays/actors/ovl_En_Ru1/z_en_ru1.h
@@ -2,16 +2,16 @@
#define Z_EN_RU1_H
#include "ultra64.h"
-#include "global.h"
+#include "z64actor.h"
#include "overlays/actors/ovl_Bg_Bdan_Objects/z_bg_bdan_objects.h"
#include "overlays/actors/ovl_Door_Warp1/z_door_warp1.h"
struct EnRu1;
-typedef void (*EnRu1ActionFunc)(struct EnRu1*, PlayState*);
-typedef void (*EnRu1DrawFunc)(struct EnRu1*, PlayState*);
-typedef void (*EnRu1PreLimbDrawFunc)(struct EnRu1*, PlayState*, s32, Vec3s*);
+typedef void (*EnRu1ActionFunc)(struct EnRu1*, struct PlayState*);
+typedef void (*EnRu1DrawFunc)(struct EnRu1*, struct PlayState*);
+typedef void (*EnRu1PreLimbDrawFunc)(struct EnRu1*, struct PlayState*, s32, Vec3s*);
typedef struct EnRu1 {
/* 0x0000 */ Actor actor;
diff --git a/src/overlays/actors/ovl_En_Ru2/z_en_ru2.c b/src/overlays/actors/ovl_En_Ru2/z_en_ru2.c
index eff82bc1e..402bb2329 100644
--- a/src/overlays/actors/ovl_En_Ru2/z_en_ru2.c
+++ b/src/overlays/actors/ovl_En_Ru2/z_en_ru2.c
@@ -5,9 +5,23 @@
*/
#include "z_en_ru2.h"
-#include "assets/objects/object_ru2/object_ru2.h"
#include "overlays/actors/ovl_Door_Warp1/z_door_warp1.h"
+
+#include "gfx.h"
+#include "gfx_setupdl.h"
+#include "one_point_cutscene.h"
+#include "regs.h"
+#include "segmented_address.h"
+#include "sequence.h"
+#include "sfx.h"
#include "terminal.h"
+#include "z_lib.h"
+#include "z64audio.h"
+#include "z64play.h"
+#include "z64player.h"
+#include "z64save.h"
+
+#include "assets/objects/object_ru2/object_ru2.h"
#define FLAGS ACTOR_FLAG_UPDATE_CULLING_DISABLED
diff --git a/src/overlays/actors/ovl_En_Ru2/z_en_ru2.h b/src/overlays/actors/ovl_En_Ru2/z_en_ru2.h
index 12333051b..ca051d180 100644
--- a/src/overlays/actors/ovl_En_Ru2/z_en_ru2.h
+++ b/src/overlays/actors/ovl_En_Ru2/z_en_ru2.h
@@ -2,15 +2,15 @@
#define Z_EN_RU2_H
#include "ultra64.h"
-#include "global.h"
+#include "z64actor.h"
#define ENRU2_GET_SWITCH_FLAG(thisx) PARAMS_GET_U(thisx->actor.params, 8, 8)
#define ENRU2_GET_TYPE(thisx) PARAMS_GET_U(thisx->actor.params, 0, 8)
struct EnRu2;
-typedef void (*EnRu2ActionFunc)(struct EnRu2*, PlayState*);
-typedef void (*EnRu2DrawFunc)(struct EnRu2*, PlayState*);
+typedef void (*EnRu2ActionFunc)(struct EnRu2*, struct PlayState*);
+typedef void (*EnRu2DrawFunc)(struct EnRu2*, struct PlayState*);
typedef struct EnRu2 {
/* 0x0000 */ Actor actor;
diff --git a/src/overlays/actors/ovl_En_Sa/z_en_sa.c b/src/overlays/actors/ovl_En_Sa/z_en_sa.c
index b2543c317..fb834576f 100644
--- a/src/overlays/actors/ovl_En_Sa/z_en_sa.c
+++ b/src/overlays/actors/ovl_En_Sa/z_en_sa.c
@@ -1,5 +1,17 @@
#include "z_en_sa.h"
#include "overlays/actors/ovl_En_Elf/z_en_elf.h"
+
+#include "attributes.h"
+#include "gfx.h"
+#include "segmented_address.h"
+#include "sfx.h"
+#include "sys_matrix.h"
+#include "z_lib.h"
+#include "z64face_reaction.h"
+#include "z64play.h"
+#include "z64player.h"
+#include "z64save.h"
+
#include "assets/objects/object_sa/object_sa.h"
#include "assets/scenes/overworld/spot04/spot04_scene.h"
#include "assets/scenes/overworld/spot05/spot05_scene.h"
diff --git a/src/overlays/actors/ovl_En_Sa/z_en_sa.h b/src/overlays/actors/ovl_En_Sa/z_en_sa.h
index 27c2c740f..013287773 100644
--- a/src/overlays/actors/ovl_En_Sa/z_en_sa.h
+++ b/src/overlays/actors/ovl_En_Sa/z_en_sa.h
@@ -2,11 +2,11 @@
#define Z_EN_SA_H
#include "ultra64.h"
-#include "global.h"
+#include "z64actor.h"
struct EnSa;
-typedef void (*EnSaActionFunc)(struct EnSa*, PlayState*);
+typedef void (*EnSaActionFunc)(struct EnSa*, struct PlayState*);
typedef struct EnSa {
/* 0x0000 */ Actor actor;
diff --git a/src/overlays/actors/ovl_En_Scene_Change/z_en_scene_change.c b/src/overlays/actors/ovl_En_Scene_Change/z_en_scene_change.c
index 26d322f9b..425b30b8f 100644
--- a/src/overlays/actors/ovl_En_Scene_Change/z_en_scene_change.c
+++ b/src/overlays/actors/ovl_En_Scene_Change/z_en_scene_change.c
@@ -6,6 +6,10 @@
#include "z_en_scene_change.h"
+#include "gfx.h"
+#include "gfx_setupdl.h"
+#include "z64play.h"
+
#define FLAGS 0
void EnSceneChange_Init(Actor* thisx, PlayState* play);
diff --git a/src/overlays/actors/ovl_En_Scene_Change/z_en_scene_change.h b/src/overlays/actors/ovl_En_Scene_Change/z_en_scene_change.h
index 4add7d11e..d1fcb16d9 100644
--- a/src/overlays/actors/ovl_En_Scene_Change/z_en_scene_change.h
+++ b/src/overlays/actors/ovl_En_Scene_Change/z_en_scene_change.h
@@ -2,11 +2,11 @@
#define Z_ITEM_SCENE_CHANGE_H
#include "ultra64.h"
-#include "global.h"
+#include "z64actor.h"
struct EnSceneChange;
-typedef void (*EnSceneChangeActionFunc)(struct EnSceneChange*, PlayState*);
+typedef void (*EnSceneChangeActionFunc)(struct EnSceneChange*, struct PlayState*);
typedef struct EnSceneChange {
/* 0x0000 */ Actor actor;
diff --git a/src/overlays/actors/ovl_En_Sda/z_en_sda.c b/src/overlays/actors/ovl_En_Sda/z_en_sda.c
index 62bd38cc1..95a1f773e 100644
--- a/src/overlays/actors/ovl_En_Sda/z_en_sda.c
+++ b/src/overlays/actors/ovl_En_Sda/z_en_sda.c
@@ -6,6 +6,13 @@
#include "z_en_sda.h"
+#include "gfx.h"
+#include "gfx_setupdl.h"
+#include "regs.h"
+#include "sys_matrix.h"
+#include "z64play.h"
+#include "z64player.h"
+
#define FLAGS (ACTOR_FLAG_UPDATE_CULLING_DISABLED | ACTOR_FLAG_DRAW_CULLING_DISABLED)
void EnSda_Init(Actor* thisx, PlayState* play);
diff --git a/src/overlays/actors/ovl_En_Sda/z_en_sda.h b/src/overlays/actors/ovl_En_Sda/z_en_sda.h
index 4dd2abd3a..27cba9966 100644
--- a/src/overlays/actors/ovl_En_Sda/z_en_sda.h
+++ b/src/overlays/actors/ovl_En_Sda/z_en_sda.h
@@ -2,7 +2,7 @@
#define Z_EN_SDA_H
#include "ultra64.h"
-#include "global.h"
+#include "z64actor.h"
struct EnSda;
diff --git a/src/overlays/actors/ovl_En_Shopnuts/z_en_shopnuts.c b/src/overlays/actors/ovl_En_Shopnuts/z_en_shopnuts.c
index eee717b35..4e082fcd4 100644
--- a/src/overlays/actors/ovl_En_Shopnuts/z_en_shopnuts.c
+++ b/src/overlays/actors/ovl_En_Shopnuts/z_en_shopnuts.c
@@ -14,6 +14,7 @@
#include "sys_matrix.h"
#include "z_lib.h"
#include "z64play.h"
+#include "z64save.h"
#include "assets/objects/object_shopnuts/object_shopnuts.h"
diff --git a/src/overlays/actors/ovl_En_Si/z_en_si.c b/src/overlays/actors/ovl_En_Si/z_en_si.c
index 308d84074..5a10b7786 100644
--- a/src/overlays/actors/ovl_En_Si/z_en_si.c
+++ b/src/overlays/actors/ovl_En_Si/z_en_si.c
@@ -5,7 +5,14 @@
*/
#include "z_en_si.h"
+
+#include "sequence.h"
+#include "z_lib.h"
+#include "z64audio.h"
#include "z64draw.h"
+#include "z64play.h"
+#include "z64player.h"
+#include "z64save.h"
#define FLAGS (ACTOR_FLAG_ATTENTION_ENABLED | ACTOR_FLAG_HOOKSHOT_PULLS_ACTOR)
diff --git a/src/overlays/actors/ovl_En_Si/z_en_si.h b/src/overlays/actors/ovl_En_Si/z_en_si.h
index b52e831a3..a4ec86302 100644
--- a/src/overlays/actors/ovl_En_Si/z_en_si.h
+++ b/src/overlays/actors/ovl_En_Si/z_en_si.h
@@ -2,11 +2,11 @@
#define Z_EN_SI_H
#include "ultra64.h"
-#include "global.h"
+#include "z64actor.h"
struct EnSi;
-typedef void (*EnSiActionFunc)(struct EnSi*, PlayState*);
+typedef void (*EnSiActionFunc)(struct EnSi*, struct PlayState*);
typedef struct EnSi {
/* 0x0000 */ Actor actor;
diff --git a/src/overlays/actors/ovl_En_Siofuki/z_en_siofuki.c b/src/overlays/actors/ovl_En_Siofuki/z_en_siofuki.c
index 1a1093f22..ecdab8d5b 100644
--- a/src/overlays/actors/ovl_En_Siofuki/z_en_siofuki.c
+++ b/src/overlays/actors/ovl_En_Siofuki/z_en_siofuki.c
@@ -5,6 +5,20 @@
*/
#include "z_en_siofuki.h"
+
+#include "libc64/math64.h"
+#include "gfx.h"
+#include "gfx_setupdl.h"
+#include "ichain.h"
+#include "one_point_cutscene.h"
+#include "sfx.h"
+#include "sys_matrix.h"
+#include "z_lib.h"
+#include "z64audio.h"
+#include "z64effect.h"
+#include "z64play.h"
+#include "z64player.h"
+
#include "assets/objects/object_siofuki/object_siofuki.h"
#define FLAGS (ACTOR_FLAG_UPDATE_CULLING_DISABLED | ACTOR_FLAG_DRAW_CULLING_DISABLED)
diff --git a/src/overlays/actors/ovl_En_Siofuki/z_en_siofuki.h b/src/overlays/actors/ovl_En_Siofuki/z_en_siofuki.h
index 23074bfac..56a08bff6 100644
--- a/src/overlays/actors/ovl_En_Siofuki/z_en_siofuki.h
+++ b/src/overlays/actors/ovl_En_Siofuki/z_en_siofuki.h
@@ -2,7 +2,7 @@
#define Z_EN_SIOFUKI_H
#include "ultra64.h"
-#include "global.h"
+#include "z64actor.h"
typedef enum EnSiofukiType {
/* 0x00 */ EN_SIOFUKI_RAISING,
@@ -11,7 +11,7 @@ typedef enum EnSiofukiType {
struct EnSiofuki;
-typedef void (*EnSiofukiActionFunc)(struct EnSiofuki*, PlayState*);
+typedef void (*EnSiofukiActionFunc)(struct EnSiofuki*, struct PlayState*);
typedef struct EnSiofuki {
/* 0x0000 */ DynaPolyActor dyna;
diff --git a/src/overlays/actors/ovl_En_Skb/z_en_skb.c b/src/overlays/actors/ovl_En_Skb/z_en_skb.c
index f7b41eb31..52e521df9 100644
--- a/src/overlays/actors/ovl_En_Skb/z_en_skb.c
+++ b/src/overlays/actors/ovl_En_Skb/z_en_skb.c
@@ -19,6 +19,7 @@
#include "z64effect.h"
#include "z64play.h"
#include "z64player.h"
+#include "z64save.h"
#include "assets/objects/object_skb/object_skb.h"
diff --git a/src/overlays/actors/ovl_En_Skj/z_en_skj.c b/src/overlays/actors/ovl_En_Skj/z_en_skj.c
index 223f8e870..a1e6e4430 100644
--- a/src/overlays/actors/ovl_En_Skj/z_en_skj.c
+++ b/src/overlays/actors/ovl_En_Skj/z_en_skj.c
@@ -13,12 +13,12 @@
#include "z_lib.h"
#include "z64audio.h"
#include "z64debug_display.h"
+#include "z64face_reaction.h"
#include "z64ocarina.h"
#include "z64effect.h"
#include "z64play.h"
#include "z64player.h"
-
-#include "global.h"
+#include "z64save.h"
#include "assets/objects/object_skj/object_skj.h"
diff --git a/src/overlays/actors/ovl_En_Ssh/z_en_ssh.c b/src/overlays/actors/ovl_En_Ssh/z_en_ssh.c
index 09b9df91c..46c4d7559 100644
--- a/src/overlays/actors/ovl_En_Ssh/z_en_ssh.c
+++ b/src/overlays/actors/ovl_En_Ssh/z_en_ssh.c
@@ -1,4 +1,16 @@
#include "z_en_ssh.h"
+
+#include "gfx.h"
+#include "segmented_address.h"
+#include "sfx.h"
+#include "sys_matrix.h"
+#include "z_lib.h"
+#include "z64effect.h"
+#include "z64face_reaction.h"
+#include "z64play.h"
+#include "z64player.h"
+#include "z64save.h"
+
#include "assets/objects/object_ssh/object_ssh.h"
#define FLAGS \
@@ -198,25 +210,25 @@ void EnSsh_InitColliders(EnSsh* this, PlayState* play) {
s32 pad;
for (i = 0; i < ARRAY_COUNT(cylinders); i++) {
- Collider_InitCylinder(play, &this->colCylinder[i]);
- Collider_SetCylinder(play, &this->colCylinder[i], &this->actor, cylinders[i]);
+ Collider_InitCylinder(play, &this->colliderCylinders[i]);
+ Collider_SetCylinder(play, &this->colliderCylinders[i], &this->actor, cylinders[i]);
}
- this->colCylinder[0].elem.acDmgInfo.dmgFlags =
+ this->colliderCylinders[0].elem.acDmgInfo.dmgFlags =
DMG_ARROW | DMG_MAGIC_FIRE | DMG_HOOKSHOT | DMG_HAMMER_SWING | DMG_EXPLOSIVE | DMG_DEKU_NUT;
- this->colCylinder[1].elem.acDmgInfo.dmgFlags =
+ this->colliderCylinders[1].elem.acDmgInfo.dmgFlags =
DMG_DEFAULT & ~(DMG_ARROW | DMG_MAGIC_FIRE | DMG_HOOKSHOT | DMG_HAMMER_SWING | DMG_EXPLOSIVE | DMG_DEKU_NUT) &
~(DMG_MAGIC_LIGHT | DMG_MAGIC_ICE);
- this->colCylinder[2].base.colMaterial = COL_MATERIAL_METAL;
- this->colCylinder[2].elem.acElemFlags = ACELEM_ON | ACELEM_HOOKABLE | ACELEM_NO_AT_INFO;
- this->colCylinder[2].elem.elemMaterial = ELEM_MATERIAL_UNK2;
- this->colCylinder[2].elem.acDmgInfo.dmgFlags =
+ this->colliderCylinders[2].base.colMaterial = COL_MATERIAL_METAL;
+ this->colliderCylinders[2].elem.acElemFlags = ACELEM_ON | ACELEM_HOOKABLE | ACELEM_NO_AT_INFO;
+ this->colliderCylinders[2].elem.elemMaterial = ELEM_MATERIAL_UNK2;
+ this->colliderCylinders[2].elem.acDmgInfo.dmgFlags =
DMG_DEFAULT & ~(DMG_ARROW | DMG_MAGIC_FIRE | DMG_HOOKSHOT | DMG_HAMMER_SWING | DMG_EXPLOSIVE | DMG_DEKU_NUT);
CollisionCheck_SetInfo2(&this->actor.colChkInfo, DamageTable_Get(2), &sColChkInfoInit);
- Collider_InitJntSph(play, &this->colSph);
- Collider_SetJntSph(play, &this->colSph, &this->actor, &sJntSphInit, this->colSphElements);
+ Collider_InitJntSph(play, &this->colliderJntSph);
+ Collider_SetJntSph(play, &this->colliderJntSph, &this->actor, &sJntSphInit, this->colliderJntSphElements);
}
f32 EnSsh_SetAnimation(EnSsh* this, s32 animIndex) {
@@ -270,21 +282,21 @@ void EnSsh_SetColliderScale(EnSsh* this, f32 scale, f32 radiusMod) {
f32 yShift;
s32 i;
- radius = this->colSph.elements[0].dim.modelSphere.radius;
+ radius = this->colliderJntSph.elements[0].dim.modelSphere.radius;
radius *= scale;
- this->colSph.elements[0].dim.modelSphere.radius = radius;
+ this->colliderJntSph.elements[0].dim.modelSphere.radius = radius;
for (i = 0; i < 6; i++) {
- yShift = this->colCylinder[i].dim.yShift;
- radius = this->colCylinder[i].dim.radius;
- height = this->colCylinder[i].dim.height;
+ yShift = this->colliderCylinders[i].dim.yShift;
+ radius = this->colliderCylinders[i].dim.radius;
+ height = this->colliderCylinders[i].dim.height;
yShift *= scale;
radius *= scale * radiusMod;
height *= scale;
- this->colCylinder[i].dim.yShift = yShift;
- this->colCylinder[i].dim.radius = radius;
- this->colCylinder[i].dim.height = height;
+ this->colliderCylinders[i].dim.yShift = yShift;
+ this->colliderCylinders[i].dim.radius = radius;
+ this->colliderCylinders[i].dim.height = height;
}
Actor_SetScale(&this->actor, 0.04f * scale);
this->floorHeightOffset = 40.0f * scale;
@@ -436,17 +448,17 @@ void EnSsh_Sway(EnSsh* this) {
}
void EnSsh_CheckBodyStickHit(EnSsh* this, PlayState* play) {
- ColliderElement* elem = &this->colCylinder[0].elem;
+ ColliderElement* elem = &this->colliderCylinders[0].elem;
Player* player = GET_PLAYER(play);
if (player->unk_860 != 0) {
elem->acDmgInfo.dmgFlags |= DMG_DEKU_STICK;
- this->colCylinder[1].elem.acDmgInfo.dmgFlags &= ~DMG_DEKU_STICK;
- this->colCylinder[2].elem.acDmgInfo.dmgFlags &= ~DMG_DEKU_STICK;
+ this->colliderCylinders[1].elem.acDmgInfo.dmgFlags &= ~DMG_DEKU_STICK;
+ this->colliderCylinders[2].elem.acDmgInfo.dmgFlags &= ~DMG_DEKU_STICK;
} else {
elem->acDmgInfo.dmgFlags &= ~DMG_DEKU_STICK;
- this->colCylinder[1].elem.acDmgInfo.dmgFlags |= DMG_DEKU_STICK;
- this->colCylinder[2].elem.acDmgInfo.dmgFlags |= DMG_DEKU_STICK;
+ this->colliderCylinders[1].elem.acDmgInfo.dmgFlags |= DMG_DEKU_STICK;
+ this->colliderCylinders[2].elem.acDmgInfo.dmgFlags |= DMG_DEKU_STICK;
}
}
@@ -458,8 +470,8 @@ s32 EnSsh_CheckHitPlayer(EnSsh* this, PlayState* play) {
return false;
}
for (i = 0; i < 3; i++) {
- if (this->colCylinder[i + 3].base.ocFlags2 & OC2_HIT_PLAYER) {
- this->colCylinder[i + 3].base.ocFlags2 &= ~OC2_HIT_PLAYER;
+ if (this->colliderCylinders[i + 3].base.ocFlags2 & OC2_HIT_PLAYER) {
+ this->colliderCylinders[i + 3].base.ocFlags2 &= ~OC2_HIT_PLAYER;
hit = true;
}
}
@@ -481,13 +493,13 @@ s32 EnSsh_CheckHitPlayer(EnSsh* this, PlayState* play) {
s32 EnSsh_CheckHitFront(EnSsh* this) {
u32 acFlags;
- if (this->colCylinder[2].base.acFlags) {} // Needed for matching
- acFlags = this->colCylinder[2].base.acFlags;
+ if (this->colliderCylinders[2].base.acFlags) {} // Needed for matching
+ acFlags = this->colliderCylinders[2].base.acFlags;
if (!!(acFlags & AC_HIT) == 0) {
return 0;
} else {
- this->colCylinder[2].base.acFlags &= ~AC_HIT;
+ this->colliderCylinders[2].base.acFlags &= ~AC_HIT;
this->invincibilityTimer = 8;
if ((this->swayTimer == 0) && (this->hitTimer == 0) && (this->stunTimer == 0)) {
this->swayTimer = 60;
@@ -497,14 +509,14 @@ s32 EnSsh_CheckHitFront(EnSsh* this) {
}
s32 EnSsh_CheckHitBack(EnSsh* this, PlayState* play) {
- ColliderCylinder* cyl = &this->colCylinder[0];
+ ColliderCylinder* cyl = &this->colliderCylinders[0];
s32 hit = false;
if (cyl->base.acFlags & AC_HIT) {
cyl->base.acFlags &= ~AC_HIT;
hit = true;
}
- cyl = &this->colCylinder[1];
+ cyl = &this->colliderCylinders[1];
if (cyl->base.acFlags & AC_HIT) {
cyl->base.acFlags &= ~AC_HIT;
hit = true;
@@ -547,19 +559,19 @@ s32 EnSsh_CollisionCheck(EnSsh* this, PlayState* play) {
}
void EnSsh_SetBodyCylinderAC(EnSsh* this, PlayState* play) {
- Collider_UpdateCylinder(&this->actor, &this->colCylinder[0]);
- CollisionCheck_SetAC(play, &play->colChkCtx, &this->colCylinder[0].base);
+ Collider_UpdateCylinder(&this->actor, &this->colliderCylinders[0]);
+ CollisionCheck_SetAC(play, &play->colChkCtx, &this->colliderCylinders[0].base);
}
void EnSsh_SetLegsCylinderAC(EnSsh* this, PlayState* play) {
s16 angleTowardsLink = ABS((s16)(this->actor.yawTowardsPlayer - this->actor.shape.rot.y));
if (angleTowardsLink < 90 * (0x10000 / 360)) {
- Collider_UpdateCylinder(&this->actor, &this->colCylinder[2]);
- CollisionCheck_SetAC(play, &play->colChkCtx, &this->colCylinder[2].base);
+ Collider_UpdateCylinder(&this->actor, &this->colliderCylinders[2]);
+ CollisionCheck_SetAC(play, &play->colChkCtx, &this->colliderCylinders[2].base);
} else {
- Collider_UpdateCylinder(&this->actor, &this->colCylinder[1]);
- CollisionCheck_SetAC(play, &play->colChkCtx, &this->colCylinder[1].base);
+ Collider_UpdateCylinder(&this->actor, &this->colliderCylinders[1]);
+ CollisionCheck_SetAC(play, &play->colChkCtx, &this->colliderCylinders[1].base);
}
}
@@ -582,18 +594,18 @@ s32 EnSsh_SetCylinderOC(EnSsh* this, PlayState* play) {
Matrix_RotateY(BINANG_TO_RAD_ALT(this->initialYaw), MTXMODE_APPLY);
Matrix_MultVec3f(&cyloffsets[i], &cylPos);
Matrix_Pop();
- this->colCylinder[i + 3].dim.pos.x = cylPos.x;
- this->colCylinder[i + 3].dim.pos.y = cylPos.y;
- this->colCylinder[i + 3].dim.pos.z = cylPos.z;
- CollisionCheck_SetOC(play, &play->colChkCtx, &this->colCylinder[i + 3].base);
+ this->colliderCylinders[i + 3].dim.pos.x = cylPos.x;
+ this->colliderCylinders[i + 3].dim.pos.y = cylPos.y;
+ this->colliderCylinders[i + 3].dim.pos.z = cylPos.z;
+ CollisionCheck_SetOC(play, &play->colChkCtx, &this->colliderCylinders[i + 3].base);
}
return 1;
}
void EnSsh_SetColliders(EnSsh* this, PlayState* play) {
if (this->actor.colChkInfo.health == 0) {
- CollisionCheck_SetAT(play, &play->colChkCtx, &this->colSph.base);
- CollisionCheck_SetOC(play, &play->colChkCtx, &this->colSph.base);
+ CollisionCheck_SetAT(play, &play->colChkCtx, &this->colliderJntSph.base);
+ CollisionCheck_SetOC(play, &play->colChkCtx, &this->colliderJntSph.base);
} else {
if (this->hitTimer == 0) {
EnSsh_SetCylinderOC(this, play);
@@ -645,9 +657,9 @@ void EnSsh_Destroy(Actor* thisx, PlayState* play) {
Effect_Delete(play, this->blureIdx);
for (i = 0; i < 6; i++) {
- Collider_DestroyCylinder(play, &this->colCylinder[i]);
+ Collider_DestroyCylinder(play, &this->colliderCylinders[i]);
}
- Collider_DestroyJntSph(play, &this->colSph);
+ Collider_DestroyJntSph(play, &this->colliderJntSph);
}
void EnSsh_Wait(EnSsh* this, PlayState* play) {
@@ -869,7 +881,7 @@ s32 EnSsh_OverrideLimbDraw(PlayState* play, s32 limbIndex, Gfx** dList, Vec3f* p
void EnSsh_PostLimbDraw(PlayState* play, s32 limbIndex, Gfx** dList, Vec3s* rot, void* thisx) {
EnSsh* this = (EnSsh*)thisx;
- Collider_UpdateSpheres(limbIndex, &this->colSph);
+ Collider_UpdateSpheres(limbIndex, &this->colliderJntSph);
}
void EnSsh_Draw(Actor* thisx, PlayState* play) {
diff --git a/src/overlays/actors/ovl_En_Ssh/z_en_ssh.h b/src/overlays/actors/ovl_En_Ssh/z_en_ssh.h
index 3060fb6fb..741770cec 100644
--- a/src/overlays/actors/ovl_En_Ssh/z_en_ssh.h
+++ b/src/overlays/actors/ovl_En_Ssh/z_en_ssh.h
@@ -2,11 +2,11 @@
#define Z_EN_SSH_H
#include "ultra64.h"
-#include "global.h"
+#include "z64actor.h"
struct EnSsh;
-typedef void (*EnSshActionFunc)(struct EnSsh*, PlayState*);
+typedef void (*EnSshActionFunc)(struct EnSsh*, struct PlayState*);
typedef struct EnSsh {
/* 0x0000 */ Actor actor;
@@ -14,9 +14,9 @@ typedef struct EnSsh {
/* 0x0190 */ Vec3s jointTable[30];
/* 0x0244 */ Vec3s morphTable[30];
/* 0x02F8 */ EnSshActionFunc actionFunc;
- /* 0x02FC */ ColliderCylinder colCylinder[6];
- /* 0x04C4 */ ColliderJntSph colSph;
- /* 0x04E4 */ ColliderJntSphElement colSphElements[1];
+ /* 0x02FC */ ColliderCylinder colliderCylinders[6];
+ /* 0x04C4 */ ColliderJntSph colliderJntSph;
+ /* 0x04E4 */ ColliderJntSphElement colliderJntSphElements[1];
/* 0x0524 */ s16 initialYaw;
/* 0x0526 */ s16 maxTurnRate;
/* 0x0528 */ s16 unkTimer;
diff --git a/src/overlays/actors/ovl_En_St/z_en_st.c b/src/overlays/actors/ovl_En_St/z_en_st.c
index 347680b3f..3b36545db 100644
--- a/src/overlays/actors/ovl_En_St/z_en_st.c
+++ b/src/overlays/actors/ovl_En_St/z_en_st.c
@@ -295,58 +295,58 @@ void EnSt_InitColliders(EnSt* this, PlayState* play) {
s32 pad;
for (i = 0; i < ARRAY_COUNT(cylinders); i++) {
- Collider_InitCylinder(play, &this->colCylinder[i]);
- Collider_SetCylinder(play, &this->colCylinder[i], &this->actor, cylinders[i]);
+ Collider_InitCylinder(play, &this->colliderCylinders[i]);
+ Collider_SetCylinder(play, &this->colliderCylinders[i], &this->actor, cylinders[i]);
}
- this->colCylinder[0].elem.acDmgInfo.dmgFlags =
+ this->colliderCylinders[0].elem.acDmgInfo.dmgFlags =
DMG_MAGIC_FIRE | DMG_ARROW | DMG_HOOKSHOT | DMG_HAMMER_SWING | DMG_BOOMERANG | DMG_EXPLOSIVE | DMG_DEKU_NUT;
- this->colCylinder[1].elem.acDmgInfo.dmgFlags =
+ this->colliderCylinders[1].elem.acDmgInfo.dmgFlags =
DMG_DEFAULT &
~(DMG_MAGIC_FIRE | DMG_ARROW | DMG_HOOKSHOT | DMG_HAMMER_SWING | DMG_BOOMERANG | DMG_EXPLOSIVE | DMG_DEKU_NUT) &
~(DMG_MAGIC_LIGHT | DMG_MAGIC_ICE);
- this->colCylinder[2].base.colMaterial = COL_MATERIAL_METAL;
- this->colCylinder[2].elem.acElemFlags = ACELEM_ON | ACELEM_HOOKABLE | ACELEM_NO_AT_INFO;
- this->colCylinder[2].elem.elemMaterial = ELEM_MATERIAL_UNK2;
- this->colCylinder[2].elem.acDmgInfo.dmgFlags =
+ this->colliderCylinders[2].base.colMaterial = COL_MATERIAL_METAL;
+ this->colliderCylinders[2].elem.acElemFlags = ACELEM_ON | ACELEM_HOOKABLE | ACELEM_NO_AT_INFO;
+ this->colliderCylinders[2].elem.elemMaterial = ELEM_MATERIAL_UNK2;
+ this->colliderCylinders[2].elem.acDmgInfo.dmgFlags =
DMG_DEFAULT &
~(DMG_MAGIC_FIRE | DMG_ARROW | DMG_HOOKSHOT | DMG_HAMMER_SWING | DMG_BOOMERANG | DMG_EXPLOSIVE | DMG_DEKU_NUT);
CollisionCheck_SetInfo2(&this->actor.colChkInfo, DamageTable_Get(2), &sColChkInit);
- Collider_InitJntSph(play, &this->colSph);
- Collider_SetJntSph(play, &this->colSph, &this->actor, &sJntSphInit, this->colSphItems);
+ Collider_InitJntSph(play, &this->colliderJntSph);
+ Collider_SetJntSph(play, &this->colliderJntSph, &this->actor, &sJntSphInit, this->colliderJntSphElements);
}
void EnSt_CheckBodyStickHit(EnSt* this, PlayState* play) {
- ColliderElement* bodyElem = &this->colCylinder[0].elem;
+ ColliderElement* bodyElem = &this->colliderCylinders[0].elem;
Player* player = GET_PLAYER(play);
if (player->unk_860 != 0) {
bodyElem->acDmgInfo.dmgFlags |= DMG_DEKU_STICK;
- this->colCylinder[1].elem.acDmgInfo.dmgFlags &= ~DMG_DEKU_STICK;
- this->colCylinder[2].elem.acDmgInfo.dmgFlags &= ~DMG_DEKU_STICK;
+ this->colliderCylinders[1].elem.acDmgInfo.dmgFlags &= ~DMG_DEKU_STICK;
+ this->colliderCylinders[2].elem.acDmgInfo.dmgFlags &= ~DMG_DEKU_STICK;
} else {
bodyElem->acDmgInfo.dmgFlags &= ~DMG_DEKU_STICK;
- this->colCylinder[1].elem.acDmgInfo.dmgFlags |= DMG_DEKU_STICK;
- this->colCylinder[2].elem.acDmgInfo.dmgFlags |= DMG_DEKU_STICK;
+ this->colliderCylinders[1].elem.acDmgInfo.dmgFlags |= DMG_DEKU_STICK;
+ this->colliderCylinders[2].elem.acDmgInfo.dmgFlags |= DMG_DEKU_STICK;
}
}
void EnSt_SetBodyCylinderAC(EnSt* this, PlayState* play) {
- Collider_UpdateCylinder(&this->actor, &this->colCylinder[0]);
- CollisionCheck_SetAC(play, &play->colChkCtx, &this->colCylinder[0].base);
+ Collider_UpdateCylinder(&this->actor, &this->colliderCylinders[0]);
+ CollisionCheck_SetAC(play, &play->colChkCtx, &this->colliderCylinders[0].base);
}
void EnSt_SetLegsCylinderAC(EnSt* this, PlayState* play) {
s16 angleTowardsLink = ABS((s16)(this->actor.yawTowardsPlayer - this->actor.shape.rot.y));
if (angleTowardsLink < 0x3FFC) {
- Collider_UpdateCylinder(&this->actor, &this->colCylinder[2]);
- CollisionCheck_SetAC(play, &play->colChkCtx, &this->colCylinder[2].base);
+ Collider_UpdateCylinder(&this->actor, &this->colliderCylinders[2]);
+ CollisionCheck_SetAC(play, &play->colChkCtx, &this->colliderCylinders[2].base);
} else {
- Collider_UpdateCylinder(&this->actor, &this->colCylinder[1]);
- CollisionCheck_SetAC(play, &play->colChkCtx, &this->colCylinder[1].base);
+ Collider_UpdateCylinder(&this->actor, &this->colliderCylinders[1]);
+ CollisionCheck_SetAC(play, &play->colChkCtx, &this->colliderCylinders[1].base);
}
}
@@ -369,10 +369,10 @@ s32 EnSt_SetCylinderOC(EnSt* this, PlayState* play) {
Matrix_RotateY(BINANG_TO_RAD_ALT(this->initialYaw), MTXMODE_APPLY);
Matrix_MultVec3f(&cyloffsets[i], &cylPos);
Matrix_Pop();
- this->colCylinder[i + 3].dim.pos.x = cylPos.x;
- this->colCylinder[i + 3].dim.pos.y = cylPos.y;
- this->colCylinder[i + 3].dim.pos.z = cylPos.z;
- CollisionCheck_SetOC(play, &play->colChkCtx, &this->colCylinder[i + 3].base);
+ this->colliderCylinders[i + 3].dim.pos.x = cylPos.x;
+ this->colliderCylinders[i + 3].dim.pos.y = cylPos.y;
+ this->colliderCylinders[i + 3].dim.pos.z = cylPos.z;
+ CollisionCheck_SetOC(play, &play->colChkCtx, &this->colliderCylinders[i + 3].base);
}
return true;
@@ -400,10 +400,10 @@ s32 EnSt_CheckHitPlayer(EnSt* this, PlayState* play) {
s32 i;
for (i = 0, hit = 0; i < 3; i++) {
- if (((this->colCylinder[i + 3].base.ocFlags2 & OC2_HIT_PLAYER) != 0) == 0) {
+ if (((this->colliderCylinders[i + 3].base.ocFlags2 & OC2_HIT_PLAYER) != 0) == 0) {
continue;
}
- this->colCylinder[i + 3].base.ocFlags2 &= ~OC2_HIT_PLAYER;
+ this->colliderCylinders[i + 3].base.ocFlags2 &= ~OC2_HIT_PLAYER;
hit = true;
}
@@ -423,13 +423,13 @@ s32 EnSt_CheckHitPlayer(EnSt* this, PlayState* play) {
}
s32 EnSt_CheckHitFrontside(EnSt* this) {
- u8 acFlags = this->colCylinder[2].base.acFlags;
+ u8 acFlags = this->colliderCylinders[2].base.acFlags;
if (!!(acFlags & AC_HIT) == 0) {
// not hit
return false;
} else {
- this->colCylinder[2].base.acFlags &= ~AC_HIT;
+ this->colliderCylinders[2].base.acFlags &= ~AC_HIT;
this->invulnerableTimer = 8;
this->playSwayFlag = 0;
this->swayTimer = 60;
@@ -438,7 +438,7 @@ s32 EnSt_CheckHitFrontside(EnSt* this) {
}
s32 EnSt_CheckHitBackside(EnSt* this, PlayState* play) {
- ColliderCylinder* cyl = &this->colCylinder[0];
+ ColliderCylinder* cyl = &this->colliderCylinders[0];
s32 flags = 0; // damage flags from colliders 0 and 1
s32 hit = false;
@@ -448,7 +448,7 @@ s32 EnSt_CheckHitBackside(EnSt* this, PlayState* play) {
flags |= cyl->elem.acHitElem->atDmgInfo.dmgFlags;
}
- cyl = &this->colCylinder[1];
+ cyl = &this->colliderCylinders[1];
if (cyl->base.acFlags & AC_HIT) {
cyl->base.acFlags &= ~AC_HIT;
hit = true;
@@ -533,21 +533,21 @@ void EnSt_SetColliderScale(EnSt* this) {
scaleAmount = 1.4f;
}
- radius = this->colSph.elements[0].dim.modelSphere.radius;
+ radius = this->colliderJntSph.elements[0].dim.modelSphere.radius;
radius *= scaleAmount;
- this->colSph.elements[0].dim.modelSphere.radius = radius;
+ this->colliderJntSph.elements[0].dim.modelSphere.radius = radius;
for (i = 0; i < 6; i++) {
- yShift = this->colCylinder[i].dim.yShift;
- radius = this->colCylinder[i].dim.radius;
- height = this->colCylinder[i].dim.height;
+ yShift = this->colliderCylinders[i].dim.yShift;
+ radius = this->colliderCylinders[i].dim.radius;
+ height = this->colliderCylinders[i].dim.height;
yShift *= scaleAmount;
radius *= scaleAmount;
height *= scaleAmount;
- this->colCylinder[i].dim.yShift = yShift;
- this->colCylinder[i].dim.radius = radius;
- this->colCylinder[i].dim.height = height;
+ this->colliderCylinders[i].dim.yShift = yShift;
+ this->colliderCylinders[i].dim.radius = radius;
+ this->colliderCylinders[i].dim.height = height;
}
Actor_SetScale(&this->actor, 0.04f * scaleAmount);
this->colliderScale = scaleAmount;
@@ -828,9 +828,9 @@ void EnSt_Destroy(Actor* thisx, PlayState* play) {
Effect_Delete(play, this->blureIdx);
for (i = 0; i < 6; i++) {
- Collider_DestroyCylinder(play, &this->colCylinder[i]);
+ Collider_DestroyCylinder(play, &this->colliderCylinders[i]);
}
- Collider_DestroyJntSph(play, &this->colSph);
+ Collider_DestroyJntSph(play, &this->colliderJntSph);
}
void EnSt_WaitOnCeiling(EnSt* this, PlayState* play) {
@@ -1097,7 +1097,7 @@ s32 EnSt_OverrideLimbDraw(PlayState* play, s32 limbIndex, Gfx** dListP, Vec3f* p
void EnSt_PostLimbDraw(PlayState* play, s32 limbIndex, Gfx** dListP, Vec3s* rot, void* thisx) {
EnSt* this = (EnSt*)thisx;
- Collider_UpdateSpheres(limbIndex, &this->colSph);
+ Collider_UpdateSpheres(limbIndex, &this->colliderJntSph);
}
void EnSt_Draw(Actor* thisx, PlayState* play) {
diff --git a/src/overlays/actors/ovl_En_St/z_en_st.h b/src/overlays/actors/ovl_En_St/z_en_st.h
index f2c070ab8..08e9e8bd8 100644
--- a/src/overlays/actors/ovl_En_St/z_en_st.h
+++ b/src/overlays/actors/ovl_En_St/z_en_st.h
@@ -12,9 +12,9 @@ typedef struct EnSt {
/* 0x0000 */ Actor actor;
/* 0x014C */ SkelAnime skelAnime;
/* 0x0190 */ EnStActionFunc actionFunc;
- /* 0x0194 */ ColliderCylinder colCylinder[6];
- /* 0x035C */ ColliderJntSph colSph;
- /* 0x037C */ ColliderJntSphElement colSphItems[1];
+ /* 0x0194 */ ColliderCylinder colliderCylinders[6];
+ /* 0x035C */ ColliderJntSph colliderJntSph;
+ /* 0x037C */ ColliderJntSphElement colliderJntSphElements[1];
/* 0x03BC */ s16 initialYaw;
/* 0x03BE */ s16 deathYawTarget;
/* 0x03C0 */ s16 groundBounces;
diff --git a/src/overlays/actors/ovl_En_Sth/z_en_sth.c b/src/overlays/actors/ovl_En_Sth/z_en_sth.c
index ac1065181..2535b0325 100644
--- a/src/overlays/actors/ovl_En_Sth/z_en_sth.c
+++ b/src/overlays/actors/ovl_En_Sth/z_en_sth.c
@@ -4,8 +4,17 @@
* Description: Uncursed House of Skulltula People
*/
-#include "terminal.h"
#include "z_en_sth.h"
+
+#include "gfx.h"
+#include "gfx_setupdl.h"
+#include "segmented_address.h"
+#include "sys_matrix.h"
+#include "terminal.h"
+#include "z_lib.h"
+#include "z64play.h"
+#include "z64save.h"
+
#include "assets/objects/object_ahg/object_ahg.h"
#include "assets/objects/object_boj/object_boj.h"
diff --git a/src/overlays/actors/ovl_En_Sth/z_en_sth.h b/src/overlays/actors/ovl_En_Sth/z_en_sth.h
index 9408c542d..a135fea2a 100644
--- a/src/overlays/actors/ovl_En_Sth/z_en_sth.h
+++ b/src/overlays/actors/ovl_En_Sth/z_en_sth.h
@@ -2,11 +2,11 @@
#define Z_EN_STH_H
#include "ultra64.h"
-#include "global.h"
+#include "z64actor.h"
struct EnSth;
-typedef void (*EnSthActionFunc)(struct EnSth*, PlayState*);
+typedef void (*EnSthActionFunc)(struct EnSth*, struct PlayState*);
typedef struct EnSth {
/* 0x0000 */ Actor actor;
diff --git a/src/overlays/actors/ovl_En_Stream/z_en_stream.c b/src/overlays/actors/ovl_En_Stream/z_en_stream.c
index dc7304839..118328e79 100644
--- a/src/overlays/actors/ovl_En_Stream/z_en_stream.c
+++ b/src/overlays/actors/ovl_En_Stream/z_en_stream.c
@@ -5,6 +5,17 @@
*/
#include "z_en_stream.h"
+
+#include "libc64/math64.h"
+#include "gfx.h"
+#include "gfx_setupdl.h"
+#include "ichain.h"
+#include "sfx.h"
+#include "sys_matrix.h"
+#include "z_lib.h"
+#include "z64play.h"
+#include "z64player.h"
+
#include "assets/objects/object_stream/object_stream.h"
#define FLAGS ACTOR_FLAG_UPDATE_CULLING_DISABLED
diff --git a/src/overlays/actors/ovl_En_Stream/z_en_stream.h b/src/overlays/actors/ovl_En_Stream/z_en_stream.h
index 199d1c679..0a21d54d8 100644
--- a/src/overlays/actors/ovl_En_Stream/z_en_stream.h
+++ b/src/overlays/actors/ovl_En_Stream/z_en_stream.h
@@ -2,11 +2,11 @@
#define Z_EN_STREAM_H
#include "ultra64.h"
-#include "global.h"
+#include "z64actor.h"
struct EnStream;
-typedef void (*EnStreamActionFunc)(struct EnStream*, PlayState*);
+typedef void (*EnStreamActionFunc)(struct EnStream*, struct PlayState*);
typedef struct EnStream {
/* 0x0000 */ Actor actor;
diff --git a/src/overlays/actors/ovl_En_Sw/z_en_sw.c b/src/overlays/actors/ovl_En_Sw/z_en_sw.c
index bce08a085..8e10154c1 100644
--- a/src/overlays/actors/ovl_En_Sw/z_en_sw.c
+++ b/src/overlays/actors/ovl_En_Sw/z_en_sw.c
@@ -13,6 +13,7 @@
#include "z64effect.h"
#include "z64play.h"
#include "z64player.h"
+#include "z64save.h"
#include "assets/objects/object_st/object_st.h"
@@ -47,7 +48,7 @@ ActorProfile En_Sw_Profile = {
/**/ EnSw_Draw,
};
-static ColliderJntSphElementInit sJntSphItemsInit[1] = {
+static ColliderJntSphElementInit sJntSphElementsInit[1] = {
{
{ ELEM_MATERIAL_UNK0, { 0xFFCFFFFF, 0x00, 0x08 }, { 0xFFC3FFFE, 0x00, 0x00 }, 0x01, 0x05, 0x01 },
{ 2, { { 0, -300, 0 }, 21 }, 100 },
@@ -57,7 +58,7 @@ static ColliderJntSphElementInit sJntSphItemsInit[1] = {
static ColliderJntSphInit sJntSphInit = {
{ COL_MATERIAL_HIT6, 0x11, 0x09, 0x39, 0x10, COLSHAPE_JNTSPH },
1,
- sJntSphItemsInit,
+ sJntSphElementsInit,
};
static CollisionCheckInfoInit2 D_80B0F074 = { 1, 2, 25, 25, MASS_IMMOVABLE };
diff --git a/src/overlays/actors/ovl_En_Syateki_Itm/z_en_syateki_itm.c b/src/overlays/actors/ovl_En_Syateki_Itm/z_en_syateki_itm.c
index ee4023eda..48bab7f43 100644
--- a/src/overlays/actors/ovl_En_Syateki_Itm/z_en_syateki_itm.c
+++ b/src/overlays/actors/ovl_En_Syateki_Itm/z_en_syateki_itm.c
@@ -11,6 +11,7 @@
#include "z64debug_display.h"
#include "z64play.h"
#include "z64player.h"
+#include "z64save.h"
#define FLAGS ACTOR_FLAG_UPDATE_CULLING_DISABLED
diff --git a/src/overlays/actors/ovl_En_Syateki_Man/z_en_syateki_man.c b/src/overlays/actors/ovl_En_Syateki_Man/z_en_syateki_man.c
index b4dfce216..3ddfb5d78 100644
--- a/src/overlays/actors/ovl_En_Syateki_Man/z_en_syateki_man.c
+++ b/src/overlays/actors/ovl_En_Syateki_Man/z_en_syateki_man.c
@@ -11,6 +11,7 @@
#include "terminal.h"
#include "z64play.h"
#include "z64player.h"
+#include "z64save.h"
#include "assets/objects/object_ossan/object_ossan.h"
diff --git a/src/overlays/actors/ovl_En_Syateki_Niw/z_en_syateki_niw.c b/src/overlays/actors/ovl_En_Syateki_Niw/z_en_syateki_niw.c
index a55d23447..01b9c7797 100644
--- a/src/overlays/actors/ovl_En_Syateki_Niw/z_en_syateki_niw.c
+++ b/src/overlays/actors/ovl_En_Syateki_Niw/z_en_syateki_niw.c
@@ -18,8 +18,8 @@
#include "z64effect.h"
#include "z64play.h"
#include "z64player.h"
+#include "z64save.h"
-#include "z64.h"
#include "assets/objects/object_niw/object_niw.h"
#define FLAGS ACTOR_FLAG_UPDATE_CULLING_DISABLED
diff --git a/src/overlays/actors/ovl_En_Ta/z_en_ta.c b/src/overlays/actors/ovl_En_Ta/z_en_ta.c
index bea60cf88..7e13bf367 100644
--- a/src/overlays/actors/ovl_En_Ta/z_en_ta.c
+++ b/src/overlays/actors/ovl_En_Ta/z_en_ta.c
@@ -5,7 +5,26 @@
*/
#include "z_en_ta.h"
+#include "overlays/actors/ovl_En_Niw/z_en_niw.h"
+
+#include "libc64/qrand.h"
+#include "gfx.h"
+#include "gfx_setupdl.h"
+#include "one_point_cutscene.h"
+#include "rand.h"
+#include "segmented_address.h"
+#include "seqcmd.h"
+#include "sequence.h"
+#include "sfx.h"
+#include "sys_matrix.h"
#include "terminal.h"
+#include "z_lib.h"
+#include "z64audio.h"
+#include "z64face_reaction.h"
+#include "z64play.h"
+#include "z64player.h"
+#include "z64save.h"
+
#include "assets/objects/object_ta/object_ta.h"
#define FLAGS (ACTOR_FLAG_ATTENTION_ENABLED | ACTOR_FLAG_FRIENDLY)
diff --git a/src/overlays/actors/ovl_En_Ta/z_en_ta.h b/src/overlays/actors/ovl_En_Ta/z_en_ta.h
index eeab7dc77..d230c2b75 100644
--- a/src/overlays/actors/ovl_En_Ta/z_en_ta.h
+++ b/src/overlays/actors/ovl_En_Ta/z_en_ta.h
@@ -2,13 +2,11 @@
#define Z_EN_TA_H
#include "ultra64.h"
-#include "global.h"
-
-#include "overlays/actors/ovl_En_Niw/z_en_niw.h"
+#include "z64actor.h"
struct EnTa;
-typedef void (*EnTaActionFunc)(struct EnTa*, PlayState*);
+typedef void (*EnTaActionFunc)(struct EnTa*, struct PlayState*);
typedef void (*EnTaBlinkFunc)(struct EnTa*);
typedef void (*EnTaAnimFunc)(struct EnTa*);
@@ -50,7 +48,7 @@ typedef struct EnTa {
/* 0x02B0 */ EnTaBlinkFunc blinkFunc;
/* 0x02B4 */ s16 eyeIndex;
/* 0x02B6 */ s16 blinkTimer;
- /* 0x02B8 */ EnNiw* superCuccos[3];
+ /* 0x02B8 */ struct EnNiw* superCuccos[3];
/* 0x02C4 */ s16 superCuccoTimers[3]; // This is used to time animations and actions for super-cuccos
/* 0x02CA */ u8 lastFoundSuperCuccoIdx;
/* 0x02CC */ s16 timer;
diff --git a/src/overlays/actors/ovl_En_Takara_Man/z_en_takara_man.c b/src/overlays/actors/ovl_En_Takara_Man/z_en_takara_man.c
index bcc60b5f1..6370bef89 100644
--- a/src/overlays/actors/ovl_En_Takara_Man/z_en_takara_man.c
+++ b/src/overlays/actors/ovl_En_Takara_Man/z_en_takara_man.c
@@ -5,8 +5,16 @@
*/
#include "z_en_takara_man.h"
+
+#include "gfx.h"
+#include "gfx_setupdl.h"
+#include "rand.h"
+#include "segmented_address.h"
#include "terminal.h"
#include "versions.h"
+#include "z64play.h"
+#include "z64save.h"
+
#include "assets/objects/object_ts/object_ts.h"
#define FLAGS \
diff --git a/src/overlays/actors/ovl_En_Takara_Man/z_en_takara_man.h b/src/overlays/actors/ovl_En_Takara_Man/z_en_takara_man.h
index 48898909b..e7d51c4b0 100644
--- a/src/overlays/actors/ovl_En_Takara_Man/z_en_takara_man.h
+++ b/src/overlays/actors/ovl_En_Takara_Man/z_en_takara_man.h
@@ -2,11 +2,11 @@
#define Z_EN_TAKARA_MAN_H
#include "ultra64.h"
-#include "global.h"
+#include "z64actor.h"
struct EnTakaraMan;
-typedef void (*EnTakaraManActionFunc)(struct EnTakaraMan*, PlayState*);
+typedef void (*EnTakaraManActionFunc)(struct EnTakaraMan*, struct PlayState*);
typedef struct EnTakaraMan {
/* 0x0000 */ Actor actor;
diff --git a/src/overlays/actors/ovl_En_Tg/z_en_tg.c b/src/overlays/actors/ovl_En_Tg/z_en_tg.c
index 42f32f0eb..1fc830181 100644
--- a/src/overlays/actors/ovl_En_Tg/z_en_tg.c
+++ b/src/overlays/actors/ovl_En_Tg/z_en_tg.c
@@ -5,6 +5,12 @@
*/
#include "z_en_tg.h"
+
+#include "gfx.h"
+#include "sys_matrix.h"
+#include "z64face_reaction.h"
+#include "z64play.h"
+
#include "assets/objects/object_mu/object_mu.h"
#define FLAGS (ACTOR_FLAG_ATTENTION_ENABLED | ACTOR_FLAG_FRIENDLY)
diff --git a/src/overlays/actors/ovl_En_Tg/z_en_tg.h b/src/overlays/actors/ovl_En_Tg/z_en_tg.h
index 4571638d7..b4d9bfe06 100644
--- a/src/overlays/actors/ovl_En_Tg/z_en_tg.h
+++ b/src/overlays/actors/ovl_En_Tg/z_en_tg.h
@@ -2,11 +2,11 @@
#define Z_EN_TG_H
#include "ultra64.h"
-#include "global.h"
+#include "z64actor.h"
struct EnTg;
-typedef void (*EnTgActionFunc)(struct EnTg*, PlayState*);
+typedef void (*EnTgActionFunc)(struct EnTg*, struct PlayState*);
typedef struct EnTg {
/* 0x0000 */ Actor actor;
diff --git a/src/overlays/actors/ovl_En_Tite/z_en_tite.c b/src/overlays/actors/ovl_En_Tite/z_en_tite.c
index ede13c3e7..e2f39597b 100644
--- a/src/overlays/actors/ovl_En_Tite/z_en_tite.c
+++ b/src/overlays/actors/ovl_En_Tite/z_en_tite.c
@@ -205,7 +205,7 @@ void EnTite_Init(Actor* thisx, PlayState* play) {
thisx->colChkInfo.health = 2;
thisx->colChkInfo.mass = MASS_HEAVY;
Collider_InitJntSph(play, &this->collider);
- Collider_SetJntSph(play, &this->collider, thisx, &sJntSphInit, &this->colliderItem);
+ Collider_SetJntSph(play, &this->collider, thisx, &sJntSphInit, this->colliderElements);
this->unk_2DC = UPDBGCHECKINFO_FLAG_0 | UPDBGCHECKINFO_FLAG_2 | UPDBGCHECKINFO_FLAG_3 | UPDBGCHECKINFO_FLAG_4;
if (this->actor.params == TEKTITE_BLUE) {
this->unk_2DC |= UPDBGCHECKINFO_FLAG_6; // Don't use the actor engine's ripple spawning code
diff --git a/src/overlays/actors/ovl_En_Tite/z_en_tite.h b/src/overlays/actors/ovl_En_Tite/z_en_tite.h
index a383e4d11..d4ec9ab8d 100755
--- a/src/overlays/actors/ovl_En_Tite/z_en_tite.h
+++ b/src/overlays/actors/ovl_En_Tite/z_en_tite.h
@@ -28,7 +28,7 @@ typedef struct EnTite {
/* 0x02E3 */ u8 spawnIceTimer;
/* 0x02E4 */ u8 damageEffect;
/* 0x02E8 */ ColliderJntSph collider;
- /* 0x0308 */ ColliderJntSphElement colliderItem;
+ /* 0x0308 */ ColliderJntSphElement colliderElements[1];
/* 0x0348 */ Vec3f frontLeftFootPos;
/* 0x0354 */ Vec3f frontRightFootPos;
/* 0x0360 */ Vec3f backRightFootPos;
diff --git a/src/overlays/actors/ovl_En_Tk/z_en_tk.c b/src/overlays/actors/ovl_En_Tk/z_en_tk.c
index 4696ecbc9..c3d696536 100644
--- a/src/overlays/actors/ovl_En_Tk/z_en_tk.c
+++ b/src/overlays/actors/ovl_En_Tk/z_en_tk.c
@@ -16,9 +16,9 @@
#include "sys_matrix.h"
#include "z_en_item00.h"
#include "z_lib.h"
+#include "z64face_reaction.h"
#include "z64play.h"
-
-#include "global.h"
+#include "z64save.h"
#include "assets/objects/gameplay_keep/gameplay_keep.h"
#include "assets/objects/object_tk/object_tk.h"
diff --git a/src/overlays/actors/ovl_En_Torch/z_en_torch.c b/src/overlays/actors/ovl_En_Torch/z_en_torch.c
index e60e16c0d..6e406c6ba 100644
--- a/src/overlays/actors/ovl_En_Torch/z_en_torch.c
+++ b/src/overlays/actors/ovl_En_Torch/z_en_torch.c
@@ -1,10 +1,14 @@
/*
* File: z_en_torch.c
* Overlay: ovl_En_Torch
- * Description: Spawns a chest with the appropriate contents then unloads. Used in grottos.
+ * Description: Spawns a chest with the appropriate contents then dies. Used in grottos.
*/
#include "z_en_torch.h"
+#include "overlays/actors/ovl_En_Box/z_en_box.h"
+
+#include "z64play.h"
+#include "z64save.h"
#define FLAGS 0
diff --git a/src/overlays/actors/ovl_En_Torch/z_en_torch.h b/src/overlays/actors/ovl_En_Torch/z_en_torch.h
index 78be1fb2d..fc3e2daba 100644
--- a/src/overlays/actors/ovl_En_Torch/z_en_torch.h
+++ b/src/overlays/actors/ovl_En_Torch/z_en_torch.h
@@ -2,7 +2,7 @@
#define Z_EN_TORCH_H
#include "ultra64.h"
-#include "global.h"
+#include "z64actor.h"
struct EnTorch;
diff --git a/src/overlays/actors/ovl_En_Torch2/z_en_torch2.c b/src/overlays/actors/ovl_En_Torch2/z_en_torch2.c
index 3764145d2..a02e9bc3b 100644
--- a/src/overlays/actors/ovl_En_Torch2/z_en_torch2.c
+++ b/src/overlays/actors/ovl_En_Torch2/z_en_torch2.c
@@ -21,8 +21,7 @@
#include "z64effect.h"
#include "z64play.h"
#include "z64player.h"
-
-#include "global.h"
+#include "z64save.h"
#include "assets/objects/object_torch2/object_torch2.h"
diff --git a/src/overlays/actors/ovl_En_Toryo/z_en_toryo.c b/src/overlays/actors/ovl_En_Toryo/z_en_toryo.c
index 5b31c32f8..2ac84162c 100644
--- a/src/overlays/actors/ovl_En_Toryo/z_en_toryo.c
+++ b/src/overlays/actors/ovl_En_Toryo/z_en_toryo.c
@@ -5,6 +5,17 @@
*/
#include "z_en_toryo.h"
+
+#include "gfx.h"
+#include "gfx_setupdl.h"
+#include "sfx.h"
+#include "sys_matrix.h"
+#include "z_lib.h"
+#include "z64face_reaction.h"
+#include "z64play.h"
+#include "z64player.h"
+#include "z64save.h"
+
#include "assets/objects/object_toryo/object_toryo.h"
#define FLAGS (ACTOR_FLAG_ATTENTION_ENABLED | ACTOR_FLAG_FRIENDLY)
diff --git a/src/overlays/actors/ovl_En_Toryo/z_en_toryo.h b/src/overlays/actors/ovl_En_Toryo/z_en_toryo.h
index 769ea637b..f8d04e74a 100644
--- a/src/overlays/actors/ovl_En_Toryo/z_en_toryo.h
+++ b/src/overlays/actors/ovl_En_Toryo/z_en_toryo.h
@@ -2,11 +2,11 @@
#define Z_EN_TORYO_H
#include "ultra64.h"
-#include "global.h"
+#include "z64actor.h"
struct EnToryo;
-typedef void (*EnToryoActionFunc)(struct EnToryo* this, PlayState* play);
+typedef void (*EnToryoActionFunc)(struct EnToryo* this, struct PlayState* play);
typedef struct EnToryo {
/* 0x0000 */ Actor actor;
diff --git a/src/overlays/actors/ovl_En_Tr/z_en_tr.c b/src/overlays/actors/ovl_En_Tr/z_en_tr.c
index 6cd63e00f..3f2672cde 100644
--- a/src/overlays/actors/ovl_En_Tr/z_en_tr.c
+++ b/src/overlays/actors/ovl_En_Tr/z_en_tr.c
@@ -5,6 +5,18 @@
*/
#include "z_en_tr.h"
+
+#include "gfx.h"
+#include "gfx_setupdl.h"
+#include "segmented_address.h"
+#include "sfx.h"
+#include "sys_math.h"
+#include "sys_matrix.h"
+#include "z_lib.h"
+#include "z64effect.h"
+#include "z64play.h"
+#include "z64save.h"
+
#include "assets/objects/object_tr/object_tr.h"
#define FLAGS ACTOR_FLAG_UPDATE_CULLING_DISABLED
diff --git a/src/overlays/actors/ovl_En_Tr/z_en_tr.h b/src/overlays/actors/ovl_En_Tr/z_en_tr.h
index faf45d740..091aa5c52 100644
--- a/src/overlays/actors/ovl_En_Tr/z_en_tr.h
+++ b/src/overlays/actors/ovl_En_Tr/z_en_tr.h
@@ -2,11 +2,11 @@
#define Z_EN_TR_H
#include "ultra64.h"
-#include "global.h"
+#include "z64actor.h"
struct EnTr;
-typedef void (*EnTrActionFunc)(struct EnTr*, PlayState*);
+typedef void (*EnTrActionFunc)(struct EnTr*, struct PlayState*);
typedef enum KotakeKoumeLimb {
/* 0 */ KOTAKE_KOUME_LIMB_NONE,
diff --git a/src/overlays/actors/ovl_En_Trap/z_en_trap.c b/src/overlays/actors/ovl_En_Trap/z_en_trap.c
index 640332ecb..848e6701b 100644
--- a/src/overlays/actors/ovl_En_Trap/z_en_trap.c
+++ b/src/overlays/actors/ovl_En_Trap/z_en_trap.c
@@ -5,6 +5,12 @@
*/
#include "z_en_trap.h"
+
+#include "sfx.h"
+#include "z_lib.h"
+#include "z64effect.h"
+#include "z64play.h"
+
#include "assets/objects/object_trap/object_trap.h"
#define FLAGS ACTOR_FLAG_UPDATE_CULLING_DISABLED
diff --git a/src/overlays/actors/ovl_En_Trap/z_en_trap.h b/src/overlays/actors/ovl_En_Trap/z_en_trap.h
index 6f69707ac..fcd62dd17 100644
--- a/src/overlays/actors/ovl_En_Trap/z_en_trap.h
+++ b/src/overlays/actors/ovl_En_Trap/z_en_trap.h
@@ -2,7 +2,7 @@
#define Z_EN_TRAP_H
#include "ultra64.h"
-#include "global.h"
+#include "z64actor.h"
// Different movement modes (set in params):
#define SPIKETRAP_MODE_LINEAR 0x10
diff --git a/src/overlays/actors/ovl_En_Tubo_Trap/z_en_tubo_trap.c b/src/overlays/actors/ovl_En_Tubo_Trap/z_en_tubo_trap.c
index 57ece9581..d9965bfe1 100644
--- a/src/overlays/actors/ovl_En_Tubo_Trap/z_en_tubo_trap.c
+++ b/src/overlays/actors/ovl_En_Tubo_Trap/z_en_tubo_trap.c
@@ -16,6 +16,7 @@
#include "z64effect.h"
#include "z64play.h"
#include "z64player.h"
+#include "z64save.h"
#include "assets/objects/gameplay_dangeon_keep/gameplay_dangeon_keep.h"
diff --git a/src/overlays/actors/ovl_En_Vase/z_en_vase.c b/src/overlays/actors/ovl_En_Vase/z_en_vase.c
index 986141341..30f8b32b1 100644
--- a/src/overlays/actors/ovl_En_Vase/z_en_vase.c
+++ b/src/overlays/actors/ovl_En_Vase/z_en_vase.c
@@ -5,6 +5,9 @@
*/
#include "z_en_vase.h"
+
+#include "z64play.h"
+
#include "assets/objects/object_vase/object_vase.h"
#define FLAGS ACTOR_FLAG_UPDATE_CULLING_DISABLED
diff --git a/src/overlays/actors/ovl_En_Vase/z_en_vase.h b/src/overlays/actors/ovl_En_Vase/z_en_vase.h
index 57ee0d577..04a8381e2 100644
--- a/src/overlays/actors/ovl_En_Vase/z_en_vase.h
+++ b/src/overlays/actors/ovl_En_Vase/z_en_vase.h
@@ -2,7 +2,7 @@
#define Z_EN_VASE_H
#include "ultra64.h"
-#include "global.h"
+#include "z64actor.h"
struct EnVase;
diff --git a/src/overlays/actors/ovl_En_Vb_Ball/z_en_vb_ball.c b/src/overlays/actors/ovl_En_Vb_Ball/z_en_vb_ball.c
index e31e9ca9a..8791409d0 100644
--- a/src/overlays/actors/ovl_En_Vb_Ball/z_en_vb_ball.c
+++ b/src/overlays/actors/ovl_En_Vb_Ball/z_en_vb_ball.c
@@ -5,9 +5,21 @@
*/
#include "z_en_vb_ball.h"
+#include "overlays/actors/ovl_Boss_Fd/z_boss_fd.h"
+
+#include "libc64/math64.h"
+#include "gfx.h"
+#include "gfx_setupdl.h"
+#include "rand.h"
+#include "segmented_address.h"
+#include "sfx.h"
+#include "sys_matrix.h"
+#include "z_lib.h"
+#include "z64play.h"
+#include "z64player.h"
+
#include "assets/objects/object_fd/object_fd.h"
#include "assets/objects/gameplay_keep/gameplay_keep.h"
-#include "overlays/actors/ovl_Boss_Fd/z_boss_fd.h"
#define FLAGS (ACTOR_FLAG_UPDATE_CULLING_DISABLED | ACTOR_FLAG_DRAW_CULLING_DISABLED)
diff --git a/src/overlays/actors/ovl_En_Vb_Ball/z_en_vb_ball.h b/src/overlays/actors/ovl_En_Vb_Ball/z_en_vb_ball.h
index 8675b440c..e81bc1ac2 100644
--- a/src/overlays/actors/ovl_En_Vb_Ball/z_en_vb_ball.h
+++ b/src/overlays/actors/ovl_En_Vb_Ball/z_en_vb_ball.h
@@ -2,7 +2,7 @@
#define Z_EN_VB_BALL_H
#include "ultra64.h"
-#include "global.h"
+#include "z64actor.h"
struct EnVbBall;
diff --git a/src/overlays/actors/ovl_En_Viewer/z_en_viewer.c b/src/overlays/actors/ovl_En_Viewer/z_en_viewer.c
index c7a231c0a..5db75cbfe 100644
--- a/src/overlays/actors/ovl_En_Viewer/z_en_viewer.c
+++ b/src/overlays/actors/ovl_En_Viewer/z_en_viewer.c
@@ -7,6 +7,23 @@
#include "z_en_viewer.h"
#include "overlays/actors/ovl_Boss_Ganon/z_boss_ganon.h"
#include "overlays/actors/ovl_En_Ganon_Mant/z_en_ganon_mant.h"
+
+#include "libc64/qrand.h"
+#include "gfx.h"
+#include "gfx_setupdl.h"
+#include "ichain.h"
+#include "regs.h"
+#include "segmented_address.h"
+#include "seqcmd.h"
+#include "sequence.h"
+#include "sfx.h"
+#include "sys_matrix.h"
+#include "z_lib.h"
+#include "z64audio.h"
+#include "z64play.h"
+#include "z64save.h"
+#include "z64skin.h"
+
#include "assets/objects/object_zl4/object_zl4.h"
#include "assets/objects/gameplay_keep/gameplay_keep.h"
#include "assets/objects/object_horse_zelda/object_horse_zelda.h"
diff --git a/src/overlays/actors/ovl_En_Viewer/z_en_viewer.h b/src/overlays/actors/ovl_En_Viewer/z_en_viewer.h
index de2bf8ba2..a06435d55 100644
--- a/src/overlays/actors/ovl_En_Viewer/z_en_viewer.h
+++ b/src/overlays/actors/ovl_En_Viewer/z_en_viewer.h
@@ -2,13 +2,14 @@
#define Z_EN_VIEWER_H
#include "ultra64.h"
-#include "global.h"
+#include "z64actor.h"
+#include "z64skin.h"
struct EnViewer;
-typedef void (*EnViewerActionFunc)(struct EnViewer*, PlayState*);
-typedef void (*EnViewerDrawFunc)(struct EnViewer*, PlayState*);
-typedef void (*EnViewerInitAnimFunc)(struct EnViewer*, PlayState*, void*, AnimationHeader*);
+typedef void (*EnViewerActionFunc)(struct EnViewer*, struct PlayState*);
+typedef void (*EnViewerDrawFunc)(struct EnViewer*, struct PlayState*);
+typedef void (*EnViewerInitAnimFunc)(struct EnViewer*, struct PlayState*, void*, AnimationHeader*);
typedef enum EnViewerType {
/* 0 */ ENVIEWER_TYPE_0_HORSE_ZELDA,
diff --git a/src/overlays/actors/ovl_En_Wallmas/z_en_wallmas.c b/src/overlays/actors/ovl_En_Wallmas/z_en_wallmas.c
index ddd3744d5..abb91c80b 100644
--- a/src/overlays/actors/ovl_En_Wallmas/z_en_wallmas.c
+++ b/src/overlays/actors/ovl_En_Wallmas/z_en_wallmas.c
@@ -17,6 +17,7 @@
#include "z64effect.h"
#include "z64play.h"
#include "z64player.h"
+#include "z64save.h"
#include "assets/objects/gameplay_keep/gameplay_keep.h"
#include "assets/objects/object_wallmaster/object_wallmaster.h"
diff --git a/src/overlays/actors/ovl_En_Weather_Tag/z_en_weather_tag.c b/src/overlays/actors/ovl_En_Weather_Tag/z_en_weather_tag.c
index 01d8e160d..38769e773 100644
--- a/src/overlays/actors/ovl_En_Weather_Tag/z_en_weather_tag.c
+++ b/src/overlays/actors/ovl_En_Weather_Tag/z_en_weather_tag.c
@@ -13,6 +13,7 @@
#include "z64debug_display.h"
#include "z64play.h"
#include "z64player.h"
+#include "z64save.h"
#define FLAGS ACTOR_FLAG_UPDATE_CULLING_DISABLED
diff --git a/src/overlays/actors/ovl_En_Weiyer/z_en_weiyer.c b/src/overlays/actors/ovl_En_Weiyer/z_en_weiyer.c
index b312e0fd6..2e1932896 100644
--- a/src/overlays/actors/ovl_En_Weiyer/z_en_weiyer.c
+++ b/src/overlays/actors/ovl_En_Weiyer/z_en_weiyer.c
@@ -17,8 +17,6 @@
#include "z64play.h"
#include "z64player.h"
-#include "global.h"
-
#include "assets/objects/object_ei/object_ei.h"
#define FLAGS (ACTOR_FLAG_ATTENTION_ENABLED | ACTOR_FLAG_HOSTILE)
diff --git a/src/overlays/actors/ovl_En_Wf/z_en_wf.c b/src/overlays/actors/ovl_En_Wf/z_en_wf.c
index e68242cdf..95f1061d6 100644
--- a/src/overlays/actors/ovl_En_Wf/z_en_wf.c
+++ b/src/overlays/actors/ovl_En_Wf/z_en_wf.c
@@ -60,7 +60,7 @@ void EnWf_SetupDie(EnWf* this);
void EnWf_Die(EnWf* this, PlayState* play);
s32 EnWf_DodgeRanged(PlayState* play, EnWf* this);
-static ColliderJntSphElementInit sJntSphItemsInit[4] = {
+static ColliderJntSphElementInit sJntSphElementsInit[4] = {
{
{
ELEM_MATERIAL_UNK0,
@@ -116,8 +116,8 @@ static ColliderJntSphInit sJntSphInit = {
OC2_TYPE_1,
COLSHAPE_JNTSPH,
},
- ARRAY_COUNT(sJntSphItemsInit),
- sJntSphItemsInit,
+ ARRAY_COUNT(sJntSphElementsInit),
+ sJntSphElementsInit,
};
static ColliderCylinderInit sBodyCylinderInit = {
@@ -242,12 +242,12 @@ void EnWf_Init(Actor* thisx, PlayState* play) {
this->eyeIndex = 0;
this->unk_2F4 = 10.0f; // Set and not used
- Collider_InitJntSph(play, &this->colliderSpheres);
- Collider_SetJntSph(play, &this->colliderSpheres, thisx, &sJntSphInit, this->colliderSpheresElements);
- Collider_InitCylinder(play, &this->colliderCylinderBody);
- Collider_SetCylinder(play, &this->colliderCylinderBody, thisx, &sBodyCylinderInit);
- Collider_InitCylinder(play, &this->colliderCylinderTail);
- Collider_SetCylinder(play, &this->colliderCylinderTail, thisx, &sTailCylinderInit);
+ Collider_InitJntSph(play, &this->colliderJntSph);
+ Collider_SetJntSph(play, &this->colliderJntSph, thisx, &sJntSphInit, this->colliderJntSphElements);
+ Collider_InitCylinder(play, &this->bodyColliderCylinder);
+ Collider_SetCylinder(play, &this->bodyColliderCylinder, thisx, &sBodyCylinderInit);
+ Collider_InitCylinder(play, &this->tailColliderCylinder);
+ Collider_SetCylinder(play, &this->tailColliderCylinder, thisx, &sTailCylinderInit);
if (thisx->params == WOLFOS_NORMAL) {
SkelAnime_InitFlex(play, &this->skelAnime, &gWolfosNormalSkel, &gWolfosWaitingAnim, this->jointTable,
@@ -258,8 +258,8 @@ void EnWf_Init(Actor* thisx, PlayState* play) {
SkelAnime_InitFlex(play, &this->skelAnime, &gWolfosWhiteSkel, &gWolfosWaitingAnim, this->jointTable,
this->morphTable, WOLFOS_LIMB_MAX);
Actor_SetScale(thisx, 0.01f);
- this->colliderSpheres.elements[0].base.atDmgInfo.damage =
- this->colliderSpheres.elements[1].base.atDmgInfo.damage = 8;
+ this->colliderJntSph.elements[0].base.atDmgInfo.damage =
+ this->colliderJntSph.elements[1].base.atDmgInfo.damage = 8;
thisx->naviEnemyId = NAVI_ENEMY_WHITE_WOLFOS;
}
@@ -273,9 +273,9 @@ void EnWf_Init(Actor* thisx, PlayState* play) {
void EnWf_Destroy(Actor* thisx, PlayState* play) {
EnWf* this = (EnWf*)thisx;
- Collider_DestroyJntSph(play, &this->colliderSpheres);
- Collider_DestroyCylinder(play, &this->colliderCylinderBody);
- Collider_DestroyCylinder(play, &this->colliderCylinderTail);
+ Collider_DestroyJntSph(play, &this->colliderJntSph);
+ Collider_DestroyCylinder(play, &this->bodyColliderCylinder);
+ Collider_DestroyCylinder(play, &this->tailColliderCylinder);
if ((this->actor.params != WOLFOS_NORMAL) && (this->switchFlag != 0xFF)) {
func_800F5B58();
@@ -733,7 +733,7 @@ void EnWf_RunAroundPlayer(EnWf* this, PlayState* play) {
void EnWf_SetupSlash(EnWf* this) {
Animation_PlayOnce(&this->skelAnime, &gWolfosSlashingAnim);
- this->colliderSpheres.base.atFlags &= ~AT_BOUNCED;
+ this->colliderJntSph.base.atFlags &= ~AT_BOUNCED;
this->actor.shape.rot.y = this->actor.yawTowardsPlayer;
this->action = WOLFOS_ACTION_SLASH;
this->unk_2FA = 0; // Set and not used
@@ -1263,27 +1263,27 @@ void func_80B36F40(EnWf* this, PlayState* play) {
}
void EnWf_UpdateDamage(EnWf* this, PlayState* play) {
- if (this->colliderSpheres.base.acFlags & AC_BOUNCED) {
- this->colliderSpheres.base.acFlags &= ~(AC_HIT | AC_BOUNCED);
- this->colliderCylinderBody.base.acFlags &= ~AC_HIT;
- this->colliderCylinderTail.base.acFlags &= ~AC_HIT;
- } else if ((this->colliderCylinderBody.base.acFlags & AC_HIT) ||
- (this->colliderCylinderTail.base.acFlags & AC_HIT)) {
+ if (this->colliderJntSph.base.acFlags & AC_BOUNCED) {
+ this->colliderJntSph.base.acFlags &= ~(AC_HIT | AC_BOUNCED);
+ this->bodyColliderCylinder.base.acFlags &= ~AC_HIT;
+ this->tailColliderCylinder.base.acFlags &= ~AC_HIT;
+ } else if ((this->bodyColliderCylinder.base.acFlags & AC_HIT) ||
+ (this->tailColliderCylinder.base.acFlags & AC_HIT)) {
if (this->action >= WOLFOS_ACTION_WAIT) {
s16 yawDiff = this->actor.yawTowardsPlayer - this->actor.shape.rot.y;
- if ((!(this->colliderCylinderBody.base.acFlags & AC_HIT) &&
- (this->colliderCylinderTail.base.acFlags & AC_HIT)) ||
+ if ((!(this->bodyColliderCylinder.base.acFlags & AC_HIT) &&
+ (this->tailColliderCylinder.base.acFlags & AC_HIT)) ||
(ABS(yawDiff) > 19000)) {
this->actor.colChkInfo.damage *= 4;
}
- this->colliderCylinderBody.base.acFlags &= ~AC_HIT;
- this->colliderCylinderTail.base.acFlags &= ~AC_HIT;
+ this->bodyColliderCylinder.base.acFlags &= ~AC_HIT;
+ this->tailColliderCylinder.base.acFlags &= ~AC_HIT;
if (this->actor.colChkInfo.damageEffect != ENWF_DMGEFF_ICE_MAGIC) {
this->damageEffect = this->actor.colChkInfo.damageEffect;
- Actor_SetDropFlag(&this->actor, &this->colliderCylinderBody.elem, true);
+ Actor_SetDropFlag(&this->actor, &this->bodyColliderCylinder.elem, true);
#if OOT_VERSION >= PAL_1_0
this->slashStatus = 0;
#endif
@@ -1337,23 +1337,23 @@ void EnWf_Update(Actor* thisx, PlayState* play) {
Math_SmoothStepToS(&this->actor.shape.rot.z, 0, 1, 1000, 0);
}
- CollisionCheck_SetOC(play, &play->colChkCtx, &this->colliderSpheres.base);
+ CollisionCheck_SetOC(play, &play->colChkCtx, &this->colliderJntSph.base);
if (this->action >= WOLFOS_ACTION_WAIT) {
if ((this->actor.colorFilterTimer == 0) || !(this->actor.colorFilterParams & 0x4000)) {
- Collider_UpdateCylinder(&this->actor, &this->colliderCylinderBody);
- CollisionCheck_SetAC(play, &play->colChkCtx, &this->colliderCylinderTail.base);
- CollisionCheck_SetAC(play, &play->colChkCtx, &this->colliderCylinderBody.base);
+ Collider_UpdateCylinder(&this->actor, &this->bodyColliderCylinder);
+ CollisionCheck_SetAC(play, &play->colChkCtx, &this->tailColliderCylinder.base);
+ CollisionCheck_SetAC(play, &play->colChkCtx, &this->bodyColliderCylinder.base);
}
}
if (this->action == WOLFOS_ACTION_BLOCKING) {
- CollisionCheck_SetAC(play, &play->colChkCtx, &this->colliderSpheres.base);
+ CollisionCheck_SetAC(play, &play->colChkCtx, &this->colliderJntSph.base);
}
if (this->slashStatus > 0) {
- if (!(this->colliderSpheres.base.atFlags & AT_BOUNCED)) {
- CollisionCheck_SetAT(play, &play->colChkCtx, &this->colliderSpheres.base);
+ if (!(this->colliderJntSph.base.atFlags & AT_BOUNCED)) {
+ CollisionCheck_SetAT(play, &play->colChkCtx, &this->colliderJntSph.base);
} else {
EnWf_SetupRecoilFromBlockedSlash(this);
}
@@ -1387,16 +1387,16 @@ void EnWf_PostLimbDraw(PlayState* play, s32 limbIndex, Gfx** dList, Vec3s* rot,
EnWf* this = (EnWf*)thisx;
s32 bodyPartIndex = -1;
- Collider_UpdateSpheres(limbIndex, &this->colliderSpheres);
+ Collider_UpdateSpheres(limbIndex, &this->colliderJntSph);
if (limbIndex == WOLFOS_LIMB_TAIL) {
Vec3f colliderPos;
bodyPartIndex = -1;
Matrix_MultVec3f(&colliderVec, &colliderPos);
- this->colliderCylinderTail.dim.pos.x = colliderPos.x;
- this->colliderCylinderTail.dim.pos.y = colliderPos.y;
- this->colliderCylinderTail.dim.pos.z = colliderPos.z;
+ this->tailColliderCylinder.dim.pos.x = colliderPos.x;
+ this->tailColliderCylinder.dim.pos.y = colliderPos.y;
+ this->tailColliderCylinder.dim.pos.z = colliderPos.z;
}
if ((this->fireTimer != 0) || ((this->actor.colorFilterTimer != 0) && (this->actor.colorFilterParams & 0x4000))) {
diff --git a/src/overlays/actors/ovl_En_Wf/z_en_wf.h b/src/overlays/actors/ovl_En_Wf/z_en_wf.h
index 7f38a9549..afc18f7d0 100644
--- a/src/overlays/actors/ovl_En_Wf/z_en_wf.h
+++ b/src/overlays/actors/ovl_En_Wf/z_en_wf.h
@@ -74,10 +74,10 @@ typedef struct EnWf {
/* 0x02FE */ s16 runAngle;
/* 0x0300 */ s16 unk_300; // Set, but ineffectual (see comment in Draw)
/* 0x0302 */ u8 eyeIndex;
- /* 0x0304 */ ColliderJntSph colliderSpheres;
- /* 0x0324 */ ColliderJntSphElement colliderSpheresElements[4];
- /* 0x0424 */ ColliderCylinder colliderCylinderBody;
- /* 0x0470 */ ColliderCylinder colliderCylinderTail;
+ /* 0x0304 */ ColliderJntSph colliderJntSph;
+ /* 0x0324 */ ColliderJntSphElement colliderJntSphElements[4];
+ /* 0x0424 */ ColliderCylinder bodyColliderCylinder;
+ /* 0x0470 */ ColliderCylinder tailColliderCylinder;
/* 0x04BC */ Vec3f unk_4BC;
/* 0x04C8 */ Vec3f unk_4C8;
/* 0x04D4 */ Vec3s unk_4D4;
diff --git a/src/overlays/actors/ovl_En_Wonder_Talk/z_en_wonder_talk.c b/src/overlays/actors/ovl_En_Wonder_Talk/z_en_wonder_talk.c
index a3a726f52..e9b0d7372 100644
--- a/src/overlays/actors/ovl_En_Wonder_Talk/z_en_wonder_talk.c
+++ b/src/overlays/actors/ovl_En_Wonder_Talk/z_en_wonder_talk.c
@@ -10,6 +10,7 @@
#include "terminal.h"
#include "z64debug_display.h"
#include "z64play.h"
+#include "z64save.h"
#define FLAGS (ACTOR_FLAG_ATTENTION_ENABLED | ACTOR_FLAG_FRIENDLY | ACTOR_FLAG_LOCK_ON_DISABLED)
diff --git a/src/overlays/actors/ovl_En_Wonder_Talk2/z_en_wonder_talk2.c b/src/overlays/actors/ovl_En_Wonder_Talk2/z_en_wonder_talk2.c
index e28f160a7..a2ec54cca 100644
--- a/src/overlays/actors/ovl_En_Wonder_Talk2/z_en_wonder_talk2.c
+++ b/src/overlays/actors/ovl_En_Wonder_Talk2/z_en_wonder_talk2.c
@@ -9,6 +9,7 @@
#include "regs.h"
#include "terminal.h"
#include "z64debug_display.h"
+#include "z64item.h"
#include "z64play.h"
#include "z64player.h"
diff --git a/src/overlays/actors/ovl_En_Xc/z_en_xc.c b/src/overlays/actors/ovl_En_Xc/z_en_xc.c
index f9c4cfb63..833973d4e 100644
--- a/src/overlays/actors/ovl_En_Xc/z_en_xc.c
+++ b/src/overlays/actors/ovl_En_Xc/z_en_xc.c
@@ -7,14 +7,30 @@
#include "z_en_xc.h"
#include "overlays/actors/ovl_En_Arrow/z_en_arrow.h"
#include "overlays/actors/ovl_Door_Warp1/z_door_warp1.h"
+
+#include "gfx.h"
+#include "gfx_setupdl.h"
+#include "regs.h"
+#include "segmented_address.h"
+#include "sequence.h"
+#include "sfx.h"
+#include "sys_math3d.h"
+#include "sys_matrix.h"
+#include "terminal.h"
+#include "z_lib.h"
+#include "z64audio.h"
+#include "z64effect.h"
+#include "z64play.h"
+#include "z64save.h"
+#include "z64skin_matrix.h"
+
#include "assets/objects/object_xc/object_xc.h"
#include "assets/scenes/overworld/spot05/spot05_scene.h"
#include "assets/scenes/overworld/spot17/spot17_scene.h"
#include "assets/scenes/indoors/tokinoma/tokinoma_scene.h"
#include "assets/scenes/dungeons/ice_doukutu/ice_doukutu_scene.h"
-#include "terminal.h"
-#pragma increment_block_number "gc-eu:0 gc-eu-mq:0 gc-jp:0 gc-jp-ce:0 gc-jp-mq:0 gc-us:0 gc-us-mq:0 ique-cn:128" \
+#pragma increment_block_number "gc-eu:0 gc-eu-mq:0 gc-jp:0 gc-jp-ce:0 gc-jp-mq:0 gc-us:0 gc-us-mq:0 ique-cn:0" \
"ntsc-1.0:0 ntsc-1.1:0 ntsc-1.2:0 pal-1.0:0 pal-1.1:0"
#define FLAGS ACTOR_FLAG_UPDATE_CULLING_DISABLED
@@ -1396,8 +1412,8 @@ void func_80B3F3D8(void) {
Sfx_PlaySfxCentered2(NA_SE_PL_SKIP);
}
-#pragma increment_block_number "gc-eu:64 gc-eu-mq:64 gc-jp:64 gc-jp-ce:64 gc-jp-mq:64 gc-us:64 gc-us-mq:64" \
- "ique-cn:128 ntsc-1.0:64 ntsc-1.1:64 ntsc-1.2:64 pal-1.0:64 pal-1.1:64"
+#pragma increment_block_number "gc-eu:64 gc-eu-mq:64 gc-jp:64 gc-jp-ce:64 gc-jp-mq:64 gc-us:64 gc-us-mq:64 ique-cn:64" \
+ "ntsc-1.0:64 ntsc-1.1:64 ntsc-1.2:64 pal-1.0:64 pal-1.1:64"
void EnXc_PlayDiveSFX(Vec3f* src, PlayState* play) {
static Vec3f D_80B42DA0;
diff --git a/src/overlays/actors/ovl_En_Xc/z_en_xc.h b/src/overlays/actors/ovl_En_Xc/z_en_xc.h
index c01b98a84..1cc56f68e 100644
--- a/src/overlays/actors/ovl_En_Xc/z_en_xc.h
+++ b/src/overlays/actors/ovl_En_Xc/z_en_xc.h
@@ -2,12 +2,12 @@
#define Z_EN_XC_H
#include "ultra64.h"
-#include "global.h"
+#include "z64actor.h"
struct EnXc;
-typedef void (*EnXcActionFunc)(struct EnXc*, PlayState*);
-typedef void (*EnXcDrawFunc)(struct Actor*, PlayState*);
+typedef void (*EnXcActionFunc)(struct EnXc*, struct PlayState*);
+typedef void (*EnXcDrawFunc)(struct Actor*, struct PlayState*);
typedef enum EnXcType {
/* 0 */ SHEIK_TYPE_0,
diff --git a/src/overlays/actors/ovl_En_Yabusame_Mark/z_en_yabusame_mark.c b/src/overlays/actors/ovl_En_Yabusame_Mark/z_en_yabusame_mark.c
index 4ebd31977..3f4dee1f0 100644
--- a/src/overlays/actors/ovl_En_Yabusame_Mark/z_en_yabusame_mark.c
+++ b/src/overlays/actors/ovl_En_Yabusame_Mark/z_en_yabusame_mark.c
@@ -15,6 +15,7 @@
#include "z64debug_display.h"
#include "z64effect.h"
#include "z64play.h"
+#include "z64save.h"
#define FLAGS 0
diff --git a/src/overlays/actors/ovl_En_Yukabyun/z_en_yukabyun.c b/src/overlays/actors/ovl_En_Yukabyun/z_en_yukabyun.c
index 4a6d3bc39..22d454fb6 100644
--- a/src/overlays/actors/ovl_En_Yukabyun/z_en_yukabyun.c
+++ b/src/overlays/actors/ovl_En_Yukabyun/z_en_yukabyun.c
@@ -5,6 +5,17 @@
*/
#include "z_en_yukabyun.h"
+
+#include "gfx.h"
+#include "gfx_setupdl.h"
+#include "ichain.h"
+#include "segmented_address.h"
+#include "sfx.h"
+#include "sys_matrix.h"
+#include "z_lib.h"
+#include "z64effect.h"
+#include "z64play.h"
+
#include "assets/objects/object_yukabyun/object_yukabyun.h"
#define FLAGS ACTOR_FLAG_UPDATE_CULLING_DISABLED
diff --git a/src/overlays/actors/ovl_En_Yukabyun/z_en_yukabyun.h b/src/overlays/actors/ovl_En_Yukabyun/z_en_yukabyun.h
index 773237fbc..a695fb4c1 100644
--- a/src/overlays/actors/ovl_En_Yukabyun/z_en_yukabyun.h
+++ b/src/overlays/actors/ovl_En_Yukabyun/z_en_yukabyun.h
@@ -2,11 +2,11 @@
#define Z_EN_YUKABYUN_H
#include "ultra64.h"
-#include "global.h"
+#include "z64actor.h"
struct EnYukabyun;
-typedef void (*EnYukabyunActionFunc)(struct EnYukabyun*, PlayState*);
+typedef void (*EnYukabyunActionFunc)(struct EnYukabyun*, struct PlayState*);
typedef struct EnYukabyun {
/* 0x0000 */ Actor actor;
diff --git a/src/overlays/actors/ovl_En_Zf/z_en_zf.c b/src/overlays/actors/ovl_En_Zf/z_en_zf.c
index 41e4055fb..843669b4e 100644
--- a/src/overlays/actors/ovl_En_Zf/z_en_zf.c
+++ b/src/overlays/actors/ovl_En_Zf/z_en_zf.c
@@ -22,8 +22,6 @@
#include "z64play.h"
#include "z64player.h"
-#include "global.h"
-
#include "assets/objects/object_zf/object_zf.h"
#define FLAGS (ACTOR_FLAG_ATTENTION_ENABLED | ACTOR_FLAG_HOSTILE | ACTOR_FLAG_UPDATE_CULLING_DISABLED)
diff --git a/src/overlays/actors/ovl_En_Zl1/z_en_zl1.c b/src/overlays/actors/ovl_En_Zl1/z_en_zl1.c
index 8a01936ff..5c60653b4 100644
--- a/src/overlays/actors/ovl_En_Zl1/z_en_zl1.c
+++ b/src/overlays/actors/ovl_En_Zl1/z_en_zl1.c
@@ -5,6 +5,20 @@
*/
#include "z_en_zl1.h"
+
+#include "gfx.h"
+#include "gfx_setupdl.h"
+#include "letterbox.h"
+#include "segmented_address.h"
+#include "sequence.h"
+#include "sfx.h"
+#include "sys_matrix.h"
+#include "z_lib.h"
+#include "z64audio.h"
+#include "z64play.h"
+#include "z64player.h"
+#include "z64save.h"
+
#include "assets/objects/object_zl1/object_zl1.h"
#define FLAGS (ACTOR_FLAG_ATTENTION_ENABLED | ACTOR_FLAG_FRIENDLY | ACTOR_FLAG_UPDATE_CULLING_DISABLED)
diff --git a/src/overlays/actors/ovl_En_Zl1/z_en_zl1.h b/src/overlays/actors/ovl_En_Zl1/z_en_zl1.h
index 4b9f2984e..ada133581 100644
--- a/src/overlays/actors/ovl_En_Zl1/z_en_zl1.h
+++ b/src/overlays/actors/ovl_En_Zl1/z_en_zl1.h
@@ -2,11 +2,11 @@
#define Z_EN_ZL1_H
#include "ultra64.h"
-#include "global.h"
+#include "z64actor.h"
struct EnZl1;
-typedef void (*EnZl1ActionFunc)(struct EnZl1*, PlayState*);
+typedef void (*EnZl1ActionFunc)(struct EnZl1*, struct PlayState*);
typedef struct EnZl1 {
/* 0x0000 */ Actor actor;
diff --git a/src/overlays/actors/ovl_En_Zl1/z_en_zl1_camera_data.inc.c b/src/overlays/actors/ovl_En_Zl1/z_en_zl1_camera_data.inc.c
index fb4776673..f6fac8940 100644
--- a/src/overlays/actors/ovl_En_Zl1/z_en_zl1_camera_data.inc.c
+++ b/src/overlays/actors/ovl_En_Zl1/z_en_zl1_camera_data.inc.c
@@ -1,4 +1,3 @@
-#include "z_en_zl1.h"
#include "z64cutscene_commands.h"
static CutsceneCameraDirection D_80B4D5C0[] = {
diff --git a/src/overlays/actors/ovl_En_Zl1/z_en_zl1_cutscene_data.c b/src/overlays/actors/ovl_En_Zl1/z_en_zl1_cutscene_data.c
index 6c268600e..4a8622cbb 100644
--- a/src/overlays/actors/ovl_En_Zl1/z_en_zl1_cutscene_data.c
+++ b/src/overlays/actors/ovl_En_Zl1/z_en_zl1_cutscene_data.c
@@ -1,5 +1,6 @@
-#include "z_en_zl1.h"
+#include "sequence.h"
#include "z64cutscene_commands.h"
+#include "z64player.h"
// clang-format off
CutsceneData gTriforceCreationStartCs[] = {
diff --git a/src/overlays/actors/ovl_En_Zl2/z_en_zl2.c b/src/overlays/actors/ovl_En_Zl2/z_en_zl2.c
index cab2a0eeb..e88530391 100644
--- a/src/overlays/actors/ovl_En_Zl2/z_en_zl2.c
+++ b/src/overlays/actors/ovl_En_Zl2/z_en_zl2.c
@@ -5,11 +5,26 @@
*/
#include "z_en_zl2.h"
-#include "terminal.h"
-
-#include "z64frame_advance.h"
-
#include "overlays/actors/ovl_Door_Warp1/z_door_warp1.h"
+
+#include "libc64/math64.h"
+#include "gfx.h"
+#include "gfx_setupdl.h"
+#include "regs.h"
+#include "segmented_address.h"
+#include "sfx.h"
+#include "sys_matrix.h"
+#include "terminal.h"
+#include "z_lib.h"
+#include "z64frame_advance.h"
+#include "z64play.h"
+#include "z64player.h"
+#include "z64save.h"
+
+#if PLATFORM_N64
+#include "global.h"
+#endif
+
#include "assets/objects/object_zl2/object_zl2.h"
#include "assets/objects/object_zl2_anime1/object_zl2_anime1.h"
diff --git a/src/overlays/actors/ovl_En_Zl2/z_en_zl2.h b/src/overlays/actors/ovl_En_Zl2/z_en_zl2.h
index c477ea57e..4bd0730de 100644
--- a/src/overlays/actors/ovl_En_Zl2/z_en_zl2.h
+++ b/src/overlays/actors/ovl_En_Zl2/z_en_zl2.h
@@ -2,12 +2,12 @@
#define Z_EN_ZL2_H
#include "ultra64.h"
-#include "global.h"
+#include "z64actor.h"
struct EnZl2;
-typedef void (*EnZl2ActionFunc)(struct EnZl2*, PlayState*);
-typedef void (*EnZl2DrawFunc)(struct EnZl2*, PlayState*);
+typedef void (*EnZl2ActionFunc)(struct EnZl2*, struct PlayState*);
+typedef void (*EnZl2DrawFunc)(struct EnZl2*, struct PlayState*);
typedef struct EnZl2 {
/* 0x0000 */ Actor actor;
diff --git a/src/overlays/actors/ovl_En_Zl3/z_en_zl3.c b/src/overlays/actors/ovl_En_Zl3/z_en_zl3.c
index cfa96518f..11f0861dc 100644
--- a/src/overlays/actors/ovl_En_Zl3/z_en_zl3.c
+++ b/src/overlays/actors/ovl_En_Zl3/z_en_zl3.c
@@ -25,8 +25,7 @@
#include "z64frame_advance.h"
#include "z64play.h"
#include "z64player.h"
-
-#include "global.h"
+#include "z64save.h"
#include "overlays/actors/ovl_En_Encount2/z_en_encount2.h"
#include "overlays/actors/ovl_Door_Warp1/z_door_warp1.h"
diff --git a/src/overlays/actors/ovl_En_Zl4/z_en_zl4.c b/src/overlays/actors/ovl_En_Zl4/z_en_zl4.c
index e3b8a51af..a18efd4ba 100644
--- a/src/overlays/actors/ovl_En_Zl4/z_en_zl4.c
+++ b/src/overlays/actors/ovl_En_Zl4/z_en_zl4.c
@@ -5,6 +5,23 @@
*/
#include "z_en_zl4.h"
+
+#include "attributes.h"
+#include "gfx.h"
+#include "gfx_setupdl.h"
+#include "letterbox.h"
+#include "rumble.h"
+#include "segmented_address.h"
+#include "sequence.h"
+#include "sfx.h"
+#include "sys_matrix.h"
+#include "z_lib.h"
+#include "z64audio.h"
+#include "z64face_reaction.h"
+#include "z64play.h"
+#include "z64player.h"
+#include "z64save.h"
+
#include "assets/objects/object_zl4/object_zl4.h"
#include "assets/scenes/indoors/nakaniwa/nakaniwa_scene.h"
diff --git a/src/overlays/actors/ovl_En_Zl4/z_en_zl4.h b/src/overlays/actors/ovl_En_Zl4/z_en_zl4.h
index 8710cc9cf..b371092e0 100644
--- a/src/overlays/actors/ovl_En_Zl4/z_en_zl4.h
+++ b/src/overlays/actors/ovl_En_Zl4/z_en_zl4.h
@@ -2,12 +2,12 @@
#define Z_EN_ZL4_H
#include "ultra64.h"
-#include "global.h"
+#include "z64actor.h"
struct EnZl4;
-typedef void (*EnZl4ActionFunc)(struct EnZl4*, PlayState*);
-typedef void (*EnZl4DrawFunc)(struct EnZl4*, PlayState*);
+typedef void (*EnZl4ActionFunc)(struct EnZl4*, struct PlayState*);
+typedef void (*EnZl4DrawFunc)(struct EnZl4*, struct PlayState*);
typedef struct EnZl4 {
/* 0x0000 */ Actor actor;
diff --git a/src/overlays/actors/ovl_En_Zl4/z_en_zl4_cutscene_data.inc.c b/src/overlays/actors/ovl_En_Zl4/z_en_zl4_cutscene_data.inc.c
index 3ad3b996b..933f7e0aa 100644
--- a/src/overlays/actors/ovl_En_Zl4/z_en_zl4_cutscene_data.inc.c
+++ b/src/overlays/actors/ovl_En_Zl4/z_en_zl4_cutscene_data.inc.c
@@ -1,4 +1,4 @@
-#include "z_en_zl4.h"
+#include "z64cutscene_commands.h"
static CutsceneCameraDirection sCamDirections[] = {
{ { -490.0f, 120.0f, 0.0f }, { -440.0f, 117.0f, 0.0f }, 0, 45 },
diff --git a/src/overlays/actors/ovl_En_Zo/z_en_zo.c b/src/overlays/actors/ovl_En_Zo/z_en_zo.c
index 6eb051e47..5332ab678 100644
--- a/src/overlays/actors/ovl_En_Zo/z_en_zo.c
+++ b/src/overlays/actors/ovl_En_Zo/z_en_zo.c
@@ -5,6 +5,19 @@
*/
#include "z_en_zo.h"
+
+#include "libc64/qrand.h"
+#include "gfx.h"
+#include "gfx_setupdl.h"
+#include "segmented_address.h"
+#include "sfx.h"
+#include "sys_matrix.h"
+#include "z_lib.h"
+#include "z64face_reaction.h"
+#include "z64play.h"
+#include "z64player.h"
+#include "z64save.h"
+
#include "assets/objects/object_zo/object_zo.h"
#define FLAGS (ACTOR_FLAG_ATTENTION_ENABLED | ACTOR_FLAG_FRIENDLY)
diff --git a/src/overlays/actors/ovl_En_Zo/z_en_zo.h b/src/overlays/actors/ovl_En_Zo/z_en_zo.h
index 4d7a02ddf..5f26a2023 100644
--- a/src/overlays/actors/ovl_En_Zo/z_en_zo.h
+++ b/src/overlays/actors/ovl_En_Zo/z_en_zo.h
@@ -2,7 +2,7 @@
#define Z_EN_ZO_H
#include "ultra64.h"
-#include "global.h"
+#include "z64actor.h"
struct EnZo;
@@ -19,7 +19,7 @@ typedef struct EnZoEffect {
/* 0x2C */ Vec3f vec; // Usage specific
} EnZoEffect; // size = 0x38
-typedef void (*EnZoActionFunc)(struct EnZo*, PlayState*);
+typedef void (*EnZoActionFunc)(struct EnZo*, struct PlayState*);
typedef struct EnZo {
/* 0x0000 */ Actor actor;
diff --git a/src/overlays/actors/ovl_En_fHG/z_en_fhg.c b/src/overlays/actors/ovl_En_fHG/z_en_fhg.c
index bce528552..1818bea85 100644
--- a/src/overlays/actors/ovl_En_fHG/z_en_fhg.c
+++ b/src/overlays/actors/ovl_En_fHG/z_en_fhg.c
@@ -5,11 +5,27 @@
*/
#include "z_en_fhg.h"
-#include "assets/objects/object_fhg/object_fhg.h"
#include "overlays/actors/ovl_Door_Shutter/z_door_shutter.h"
#include "overlays/actors/ovl_Boss_Ganondrof/z_boss_ganondrof.h"
#include "overlays/actors/ovl_En_Fhg_Fire/z_en_fhg_fire.h"
+#include "libc64/qrand.h"
+#include "attributes.h"
+#include "gfx.h"
+#include "gfx_setupdl.h"
+#include "ichain.h"
+#include "segmented_address.h"
+#include "seqcmd.h"
+#include "sequence.h"
+#include "sfx.h"
+#include "z_lib.h"
+#include "z64play.h"
+#include "z64player.h"
+#include "z64save.h"
+#include "z64skin.h"
+
+#include "assets/objects/object_fhg/object_fhg.h"
+
#define FLAGS ACTOR_FLAG_UPDATE_CULLING_DISABLED
typedef struct EnfHGPainting {
diff --git a/src/overlays/actors/ovl_En_fHG/z_en_fhg.h b/src/overlays/actors/ovl_En_fHG/z_en_fhg.h
index 5432f8234..dca6eeb82 100644
--- a/src/overlays/actors/ovl_En_fHG/z_en_fhg.h
+++ b/src/overlays/actors/ovl_En_fHG/z_en_fhg.h
@@ -2,11 +2,12 @@
#define Z_EN_FHG_H
#include "ultra64.h"
-#include "global.h"
+#include "z64actor.h"
+#include "z64skin.h"
struct EnfHG;
-typedef void (*EnfHGActionFunc)(struct EnfHG*, PlayState*);
+typedef void (*EnfHGActionFunc)(struct EnfHG*, struct PlayState*);
typedef enum EnfHGSignal {
/* 0 */ FHG_NO_SIGNAL,
diff --git a/src/overlays/actors/ovl_End_Title/z_end_title.c b/src/overlays/actors/ovl_End_Title/z_end_title.c
index c886a1d43..7cca73d85 100644
--- a/src/overlays/actors/ovl_End_Title/z_end_title.c
+++ b/src/overlays/actors/ovl_End_Title/z_end_title.c
@@ -5,7 +5,13 @@
*/
#include "z_end_title.h"
+
+#include "gfx.h"
+#include "gfx_setupdl.h"
+#include "sys_matrix.h"
#include "versions.h"
+#include "z64play.h"
+#include "z64player.h"
#define FLAGS (ACTOR_FLAG_UPDATE_CULLING_DISABLED | ACTOR_FLAG_DRAW_CULLING_DISABLED)
diff --git a/src/overlays/actors/ovl_End_Title/z_end_title.h b/src/overlays/actors/ovl_End_Title/z_end_title.h
index 9897c0fbf..cd29ff507 100644
--- a/src/overlays/actors/ovl_End_Title/z_end_title.h
+++ b/src/overlays/actors/ovl_End_Title/z_end_title.h
@@ -2,7 +2,7 @@
#define Z_END_TITLE_H
#include "ultra64.h"
-#include "global.h"
+#include "z64actor.h"
struct EndTitle;
diff --git a/src/overlays/actors/ovl_Fishing/z_fishing.c b/src/overlays/actors/ovl_Fishing/z_fishing.c
index 203418793..1ec716f8c 100644
--- a/src/overlays/actors/ovl_Fishing/z_fishing.c
+++ b/src/overlays/actors/ovl_Fishing/z_fishing.c
@@ -26,17 +26,18 @@
#include "sys_matrix.h"
#include "terminal.h"
#include "versions.h"
+#include "z_lib.h"
#include "z64audio.h"
#include "z64play.h"
#include "z64player.h"
+#include "z64save.h"
#include "z64skin_matrix.h"
-#include "z_lib.h"
#if PLATFORM_N64
#include "cic6105.h"
#endif
-#pragma increment_block_number "gc-eu:170 gc-eu-mq:170 gc-jp:170 gc-jp-ce:170 gc-jp-mq:170 gc-us:170 gc-us-mq:170" \
- "ntsc-1.0:121 ntsc-1.1:121 ntsc-1.2:121 pal-1.0:121 pal-1.1:121"
+#pragma increment_block_number "gc-eu:128 gc-eu-mq:128 gc-jp:128 gc-jp-ce:128 gc-jp-mq:128 gc-us:128 gc-us-mq:128" \
+ "ntsc-1.0:0 ntsc-1.1:0 ntsc-1.2:0 pal-1.0:0 pal-1.1:0"
#define FLAGS ACTOR_FLAG_UPDATE_CULLING_DISABLED
diff --git a/src/overlays/actors/ovl_Item_B_Heart/z_item_b_heart.c b/src/overlays/actors/ovl_Item_B_Heart/z_item_b_heart.c
index da8ddad52..a690bfa73 100644
--- a/src/overlays/actors/ovl_Item_B_Heart/z_item_b_heart.c
+++ b/src/overlays/actors/ovl_Item_B_Heart/z_item_b_heart.c
@@ -5,6 +5,15 @@
*/
#include "z_item_b_heart.h"
+
+#include "gfx.h"
+#include "gfx_setupdl.h"
+#include "ichain.h"
+#include "sys_matrix.h"
+#include "z_lib.h"
+#include "z64item.h"
+#include "z64play.h"
+
#include "assets/objects/object_gi_hearts/object_gi_hearts.h"
#define FLAGS 0
diff --git a/src/overlays/actors/ovl_Item_B_Heart/z_item_b_heart.h b/src/overlays/actors/ovl_Item_B_Heart/z_item_b_heart.h
index 432a7ef49..ef92f86b8 100644
--- a/src/overlays/actors/ovl_Item_B_Heart/z_item_b_heart.h
+++ b/src/overlays/actors/ovl_Item_B_Heart/z_item_b_heart.h
@@ -2,7 +2,7 @@
#define Z_ITEM_B_HEART_H
#include "ultra64.h"
-#include "global.h"
+#include "z64actor.h"
struct ItemBHeart;
diff --git a/src/overlays/actors/ovl_Item_Etcetera/z_item_etcetera.c b/src/overlays/actors/ovl_Item_Etcetera/z_item_etcetera.c
index 04028bff7..e0e0e88d8 100644
--- a/src/overlays/actors/ovl_Item_Etcetera/z_item_etcetera.c
+++ b/src/overlays/actors/ovl_Item_Etcetera/z_item_etcetera.c
@@ -12,6 +12,7 @@
#include "z64draw.h"
#include "z64effect.h"
#include "z64play.h"
+#include "z64save.h"
#define FLAGS ACTOR_FLAG_UPDATE_CULLING_DISABLED
diff --git a/src/overlays/actors/ovl_Item_Ocarina/z_item_ocarina.c b/src/overlays/actors/ovl_Item_Ocarina/z_item_ocarina.c
index 61d19aee5..fa4f500c8 100644
--- a/src/overlays/actors/ovl_Item_Ocarina/z_item_ocarina.c
+++ b/src/overlays/actors/ovl_Item_Ocarina/z_item_ocarina.c
@@ -12,6 +12,7 @@
#include "z64draw.h"
#include "z64effect.h"
#include "z64play.h"
+#include "z64save.h"
#include "assets/scenes/overworld/spot00/spot00_scene.h"
diff --git a/src/overlays/actors/ovl_Item_Shield/z_item_shield.c b/src/overlays/actors/ovl_Item_Shield/z_item_shield.c
index 560314ce2..b990a8331 100644
--- a/src/overlays/actors/ovl_Item_Shield/z_item_shield.c
+++ b/src/overlays/actors/ovl_Item_Shield/z_item_shield.c
@@ -4,8 +4,21 @@
* Description: Deku Shield
*/
-#include "terminal.h"
#include "z_item_shield.h"
+
+#include "gfx.h"
+#include "gfx_setupdl.h"
+#include "rand.h"
+#include "segmented_address.h"
+#include "sys_math.h"
+#include "sys_matrix.h"
+#include "terminal.h"
+#include "z_lib.h"
+#include "z64effect.h"
+#include "z64item.h"
+#include "z64play.h"
+#include "z64player.h"
+
#include "assets/objects/object_link_child/object_link_child.h"
#define FLAGS ACTOR_FLAG_UPDATE_CULLING_DISABLED
diff --git a/src/overlays/actors/ovl_Item_Shield/z_item_shield.h b/src/overlays/actors/ovl_Item_Shield/z_item_shield.h
index c7984f4a4..564170e46 100644
--- a/src/overlays/actors/ovl_Item_Shield/z_item_shield.h
+++ b/src/overlays/actors/ovl_Item_Shield/z_item_shield.h
@@ -2,11 +2,11 @@
#define Z_ITEM_SHIELD_H
#include "ultra64.h"
-#include "global.h"
+#include "z64actor.h"
struct ItemShield;
-typedef void (*ItemShieldActionFunc)(struct ItemShield*, PlayState*);
+typedef void (*ItemShieldActionFunc)(struct ItemShield*, struct PlayState*);
typedef struct ItemShield {
/* 0x0000 */ Actor actor;
diff --git a/src/overlays/actors/ovl_Magic_Dark/z_magic_dark.c b/src/overlays/actors/ovl_Magic_Dark/z_magic_dark.c
index d809a82eb..0dfabfee4 100644
--- a/src/overlays/actors/ovl_Magic_Dark/z_magic_dark.c
+++ b/src/overlays/actors/ovl_Magic_Dark/z_magic_dark.c
@@ -5,6 +5,16 @@
*/
#include "z_magic_dark.h"
+
+#include "gfx.h"
+#include "gfx_setupdl.h"
+#include "sfx.h"
+#include "sys_matrix.h"
+#include "z_lib.h"
+#include "z64play.h"
+#include "z64player.h"
+#include "z64save.h"
+
#include "assets/objects/gameplay_keep/gameplay_keep.h"
#define FLAGS (ACTOR_FLAG_UPDATE_CULLING_DISABLED | ACTOR_FLAG_UPDATE_DURING_OCARINA)
diff --git a/src/overlays/actors/ovl_Magic_Dark/z_magic_dark.h b/src/overlays/actors/ovl_Magic_Dark/z_magic_dark.h
index 3d7ef8229..59344baff 100644
--- a/src/overlays/actors/ovl_Magic_Dark/z_magic_dark.h
+++ b/src/overlays/actors/ovl_Magic_Dark/z_magic_dark.h
@@ -2,7 +2,7 @@
#define Z_MAGIC_DARK_H
#include "ultra64.h"
-#include "global.h"
+#include "z64actor.h"
struct MagicDark;
diff --git a/src/overlays/actors/ovl_Magic_Fire/z_magic_fire.c b/src/overlays/actors/ovl_Magic_Fire/z_magic_fire.c
index ede5f3691..f93ded2f0 100644
--- a/src/overlays/actors/ovl_Magic_Fire/z_magic_fire.c
+++ b/src/overlays/actors/ovl_Magic_Fire/z_magic_fire.c
@@ -6,6 +6,15 @@
#include "z_magic_fire.h"
+#include "gfx.h"
+#include "gfx_setupdl.h"
+#include "ichain.h"
+#include "sfx.h"
+#include "sys_matrix.h"
+#include "z_lib.h"
+#include "z64play.h"
+#include "z64player.h"
+
#define FLAGS (ACTOR_FLAG_UPDATE_CULLING_DISABLED | ACTOR_FLAG_UPDATE_DURING_OCARINA)
void MagicFire_Init(Actor* thisx, PlayState* play);
diff --git a/src/overlays/actors/ovl_Magic_Fire/z_magic_fire.h b/src/overlays/actors/ovl_Magic_Fire/z_magic_fire.h
index 4a9cb5188..ae953c0d3 100644
--- a/src/overlays/actors/ovl_Magic_Fire/z_magic_fire.h
+++ b/src/overlays/actors/ovl_Magic_Fire/z_magic_fire.h
@@ -2,7 +2,7 @@
#define Z_MAGIC_FIRE_H
#include "ultra64.h"
-#include "global.h"
+#include "z64actor.h"
struct MagicFire;
diff --git a/src/overlays/actors/ovl_Magic_Wind/z_magic_wind.c b/src/overlays/actors/ovl_Magic_Wind/z_magic_wind.c
index 0694e0712..2872bdc70 100644
--- a/src/overlays/actors/ovl_Magic_Wind/z_magic_wind.c
+++ b/src/overlays/actors/ovl_Magic_Wind/z_magic_wind.c
@@ -6,6 +6,14 @@
#include "z_magic_wind.h"
+#include "libu64/debug.h"
+#include "gfx.h"
+#include "gfx_setupdl.h"
+#include "sfx.h"
+#include "z64curve.h"
+#include "z64play.h"
+#include "z64player.h"
+
#define FLAGS (ACTOR_FLAG_UPDATE_CULLING_DISABLED | ACTOR_FLAG_UPDATE_DURING_OCARINA)
void MagicWind_Init(Actor* thisx, PlayState* play);
diff --git a/src/overlays/actors/ovl_Magic_Wind/z_magic_wind.h b/src/overlays/actors/ovl_Magic_Wind/z_magic_wind.h
index e9521f700..b7ba93c26 100644
--- a/src/overlays/actors/ovl_Magic_Wind/z_magic_wind.h
+++ b/src/overlays/actors/ovl_Magic_Wind/z_magic_wind.h
@@ -2,11 +2,12 @@
#define Z_MAGIC_WIND_H
#include "ultra64.h"
-#include "global.h"
+#include "z64actor.h"
+#include "z64curve.h"
struct MagicWind;
-typedef void (*MagicWindFunc)(struct MagicWind* this, PlayState* play);
+typedef void (*MagicWindFunc)(struct MagicWind* this, struct PlayState* play);
typedef struct MagicWind {
/* 0x0000 */ Actor actor;
diff --git a/src/overlays/actors/ovl_Mir_Ray/z_mir_ray.c b/src/overlays/actors/ovl_Mir_Ray/z_mir_ray.c
index 8fd7f63d0..1dc67c448 100644
--- a/src/overlays/actors/ovl_Mir_Ray/z_mir_ray.c
+++ b/src/overlays/actors/ovl_Mir_Ray/z_mir_ray.c
@@ -131,10 +131,11 @@ void MirRay_SetupCollider(MirRay* this) {
colliderOffset.x = (this->poolPt.x - this->sourcePt.x) * dataEntry->unk_10;
colliderOffset.y = (this->poolPt.y - this->sourcePt.y) * dataEntry->unk_10;
colliderOffset.z = (this->poolPt.z - this->sourcePt.z) * dataEntry->unk_10;
- this->colliderSph.elements[0].dim.worldSphere.center.x = colliderOffset.x + this->sourcePt.x;
- this->colliderSph.elements[0].dim.worldSphere.center.y = colliderOffset.y + this->sourcePt.y;
- this->colliderSph.elements[0].dim.worldSphere.center.z = colliderOffset.z + this->sourcePt.z;
- this->colliderSph.elements[0].dim.worldSphere.radius = dataEntry->unk_14 * this->colliderSph.elements->dim.scale;
+ this->colliderJntSph.elements[0].dim.worldSphere.center.x = colliderOffset.x + this->sourcePt.x;
+ this->colliderJntSph.elements[0].dim.worldSphere.center.y = colliderOffset.y + this->sourcePt.y;
+ this->colliderJntSph.elements[0].dim.worldSphere.center.z = colliderOffset.z + this->sourcePt.z;
+ this->colliderJntSph.elements[0].dim.worldSphere.radius =
+ dataEntry->unk_14 * this->colliderJntSph.elements->dim.scale;
}
// Set up a light point between source point and reflection point. Reflection point is the pool point (for windows) or
@@ -221,8 +222,8 @@ void MirRay_Init(Actor* thisx, PlayState* play) {
this->shieldCorners[5].y = -800.0f;
if (PARAMS_GET_NOSHIFT(dataEntry->params, 1, 1)) {
- Collider_InitJntSph(play, &this->colliderSph);
- Collider_SetJntSph(play, &this->colliderSph, &this->actor, &sJntSphInit, &this->colliderSphItem);
+ Collider_InitJntSph(play, &this->colliderJntSph);
+ Collider_SetJntSph(play, &this->colliderJntSph, &this->actor, &sJntSphInit, this->colliderJntSphElements);
if (!PARAMS_GET_NOSHIFT(dataEntry->params, 2, 1)) { // Beams not from mirrors
MirRay_SetupCollider(this);
}
@@ -243,7 +244,7 @@ void MirRay_Destroy(Actor* thisx, PlayState* play) {
LightContext_RemoveLight(play, &play->lightCtx, this->lightNode);
if (sMirRayData[this->actor.params].params & 2) {
- Collider_DestroyJntSph(play, &this->colliderSph);
+ Collider_DestroyJntSph(play, &this->colliderJntSph);
}
Collider_DestroyQuad(play, &this->shieldRay);
@@ -261,7 +262,7 @@ void MirRay_Update(Actor* thisx, PlayState* play) {
if (sMirRayData[this->actor.params].params & 4) { // Beams from mirrors
MirRay_SetupCollider(this);
}
- CollisionCheck_SetAT(play, &play->colChkCtx, &this->colliderSph.base);
+ CollisionCheck_SetAT(play, &play->colChkCtx, &this->colliderJntSph.base);
}
if (this->reflectIntensity > 0.0f) {
CollisionCheck_SetAT(play, &play->colChkCtx, &this->shieldRay.base);
diff --git a/src/overlays/actors/ovl_Mir_Ray/z_mir_ray.h b/src/overlays/actors/ovl_Mir_Ray/z_mir_ray.h
index 652516ec1..245cf1007 100644
--- a/src/overlays/actors/ovl_Mir_Ray/z_mir_ray.h
+++ b/src/overlays/actors/ovl_Mir_Ray/z_mir_ray.h
@@ -29,8 +29,8 @@ typedef struct MirRayShieldReflection {
typedef struct MirRay {
/* 0x0000 */ Actor actor;
- /* 0x014C */ ColliderJntSph colliderSph;
- /* 0x016C */ ColliderJntSphElement colliderSphItem;
+ /* 0x014C */ ColliderJntSph colliderJntSph;
+ /* 0x016C */ ColliderJntSphElement colliderJntSphElements[1];
/* 0x01AC */ ColliderQuad shieldRay;
/* 0x022C */ f32 reflectIntensity; // Reflection occurs if it is positive, brightness depends on it
/* 0x0230 */ Vec3f shieldCorners[6];
diff --git a/src/overlays/actors/ovl_Obj_Bean/z_obj_bean.c b/src/overlays/actors/ovl_Obj_Bean/z_obj_bean.c
index 0ce75f8cf..f2837d848 100644
--- a/src/overlays/actors/ovl_Obj_Bean/z_obj_bean.c
+++ b/src/overlays/actors/ovl_Obj_Bean/z_obj_bean.c
@@ -17,10 +17,10 @@
#include "terminal.h"
#include "z_en_item00.h"
#include "z_lib.h"
+#include "z64cutscene_flags.h"
#include "z64effect.h"
#include "z64play.h"
-
-#include "global.h"
+#include "z64save.h"
#include "assets/objects/gameplay_keep/gameplay_keep.h"
#include "assets/objects/object_mamenoki/object_mamenoki.h"
diff --git a/src/overlays/actors/ovl_Obj_Blockstop/z_obj_blockstop.c b/src/overlays/actors/ovl_Obj_Blockstop/z_obj_blockstop.c
index cb7cba62c..8f24b7e64 100644
--- a/src/overlays/actors/ovl_Obj_Blockstop/z_obj_blockstop.c
+++ b/src/overlays/actors/ovl_Obj_Blockstop/z_obj_blockstop.c
@@ -7,6 +7,10 @@
#include "z_obj_blockstop.h"
#include "overlays/actors/ovl_Obj_Oshihiki/z_obj_oshihiki.h"
+#include "sfx.h"
+#include "z_lib.h"
+#include "z64play.h"
+
#define FLAGS 0
void ObjBlockstop_Init(Actor* thisx, PlayState* play);
diff --git a/src/overlays/actors/ovl_Obj_Blockstop/z_obj_blockstop.h b/src/overlays/actors/ovl_Obj_Blockstop/z_obj_blockstop.h
index f6ff149e9..e0159e0f9 100644
--- a/src/overlays/actors/ovl_Obj_Blockstop/z_obj_blockstop.h
+++ b/src/overlays/actors/ovl_Obj_Blockstop/z_obj_blockstop.h
@@ -2,7 +2,7 @@
#define Z_OBJ_BLOCKSTOP_H
#include "ultra64.h"
-#include "global.h"
+#include "z64actor.h"
struct ObjBlockstop;
diff --git a/src/overlays/actors/ovl_Obj_Bombiwa/z_obj_bombiwa.c b/src/overlays/actors/ovl_Obj_Bombiwa/z_obj_bombiwa.c
index 68e1687aa..9563d5d2b 100644
--- a/src/overlays/actors/ovl_Obj_Bombiwa/z_obj_bombiwa.c
+++ b/src/overlays/actors/ovl_Obj_Bombiwa/z_obj_bombiwa.c
@@ -6,6 +6,15 @@
#include "z_obj_bombiwa.h"
#include "overlays/effects/ovl_Effect_Ss_Kakera/z_eff_ss_kakera.h"
+
+#include "libc64/qrand.h"
+#include "ichain.h"
+#include "rand.h"
+#include "sfx.h"
+#include "z_lib.h"
+#include "z64effect.h"
+#include "z64play.h"
+
#include "assets/objects/object_bombiwa/object_bombiwa.h"
#define FLAGS 0
diff --git a/src/overlays/actors/ovl_Obj_Bombiwa/z_obj_bombiwa.h b/src/overlays/actors/ovl_Obj_Bombiwa/z_obj_bombiwa.h
index 33597276b..9c5c38d12 100644
--- a/src/overlays/actors/ovl_Obj_Bombiwa/z_obj_bombiwa.h
+++ b/src/overlays/actors/ovl_Obj_Bombiwa/z_obj_bombiwa.h
@@ -2,7 +2,7 @@
#define Z_OBJ_BOMBIWA_H
#include "ultra64.h"
-#include "global.h"
+#include "z64actor.h"
struct ObjBombiwa;
diff --git a/src/overlays/actors/ovl_Obj_Dekujr/z_obj_dekujr.c b/src/overlays/actors/ovl_Obj_Dekujr/z_obj_dekujr.c
index 3a0d603aa..2c77570a4 100644
--- a/src/overlays/actors/ovl_Obj_Dekujr/z_obj_dekujr.c
+++ b/src/overlays/actors/ovl_Obj_Dekujr/z_obj_dekujr.c
@@ -5,6 +5,14 @@
*/
#include "z_obj_dekujr.h"
+
+#include "gfx.h"
+#include "gfx_setupdl.h"
+#include "sfx.h"
+#include "sys_matrix.h"
+#include "z64play.h"
+#include "z64save.h"
+
#include "assets/objects/object_dekujr/object_dekujr.h"
#define FLAGS (ACTOR_FLAG_ATTENTION_ENABLED | ACTOR_FLAG_FRIENDLY)
diff --git a/src/overlays/actors/ovl_Obj_Dekujr/z_obj_dekujr.h b/src/overlays/actors/ovl_Obj_Dekujr/z_obj_dekujr.h
index 88818776a..68b483f8d 100644
--- a/src/overlays/actors/ovl_Obj_Dekujr/z_obj_dekujr.h
+++ b/src/overlays/actors/ovl_Obj_Dekujr/z_obj_dekujr.h
@@ -2,7 +2,7 @@
#define Z_OBJ_DEKUJR_H
#include "ultra64.h"
-#include "global.h"
+#include "z64actor.h"
struct ObjDekujr;
diff --git a/src/overlays/actors/ovl_Obj_Elevator/z_obj_elevator.c b/src/overlays/actors/ovl_Obj_Elevator/z_obj_elevator.c
index 411d3e2ad..fd9d335b6 100644
--- a/src/overlays/actors/ovl_Obj_Elevator/z_obj_elevator.c
+++ b/src/overlays/actors/ovl_Obj_Elevator/z_obj_elevator.c
@@ -5,6 +5,12 @@
*/
#include "z_obj_elevator.h"
+
+#include "ichain.h"
+#include "sfx.h"
+#include "z_lib.h"
+#include "z64play.h"
+
#include "assets/objects/object_d_elevator/object_d_elevator.h"
#define FLAGS 0
diff --git a/src/overlays/actors/ovl_Obj_Elevator/z_obj_elevator.h b/src/overlays/actors/ovl_Obj_Elevator/z_obj_elevator.h
index e77d04a9a..e6b8d4b6d 100644
--- a/src/overlays/actors/ovl_Obj_Elevator/z_obj_elevator.h
+++ b/src/overlays/actors/ovl_Obj_Elevator/z_obj_elevator.h
@@ -2,11 +2,11 @@
#define Z_OBJ_ELEVATOR_H
#include "ultra64.h"
-#include "global.h"
+#include "z64actor.h"
struct ObjElevator;
-typedef void (*ObjElevatorActionFunc)(struct ObjElevator*, PlayState*);
+typedef void (*ObjElevatorActionFunc)(struct ObjElevator*, struct PlayState*);
typedef struct ObjElevator {
/* 0x0000 */ DynaPolyActor dyna;
diff --git a/src/overlays/actors/ovl_Obj_Hamishi/z_obj_hamishi.c b/src/overlays/actors/ovl_Obj_Hamishi/z_obj_hamishi.c
index 3f45341e3..f7ec91ca0 100644
--- a/src/overlays/actors/ovl_Obj_Hamishi/z_obj_hamishi.c
+++ b/src/overlays/actors/ovl_Obj_Hamishi/z_obj_hamishi.c
@@ -5,6 +5,18 @@
*/
#include "z_obj_hamishi.h"
+
+#include "libc64/qrand.h"
+#include "gfx.h"
+#include "gfx_setupdl.h"
+#include "ichain.h"
+#include "rand.h"
+#include "sfx.h"
+#include "sys_matrix.h"
+#include "z_lib.h"
+#include "z64effect.h"
+#include "z64play.h"
+
#include "assets/objects/gameplay_field_keep/gameplay_field_keep.h"
#define FLAGS 0
diff --git a/src/overlays/actors/ovl_Obj_Hamishi/z_obj_hamishi.h b/src/overlays/actors/ovl_Obj_Hamishi/z_obj_hamishi.h
index a897177f6..8a2256bf0 100644
--- a/src/overlays/actors/ovl_Obj_Hamishi/z_obj_hamishi.h
+++ b/src/overlays/actors/ovl_Obj_Hamishi/z_obj_hamishi.h
@@ -2,7 +2,7 @@
#define Z_OBJ_HAMISHI_H
#include "ultra64.h"
-#include "global.h"
+#include "z64actor.h"
struct ObjHamishi;
diff --git a/src/overlays/actors/ovl_Obj_Hana/z_obj_hana.c b/src/overlays/actors/ovl_Obj_Hana/z_obj_hana.c
index badd99186..f1f800006 100644
--- a/src/overlays/actors/ovl_Obj_Hana/z_obj_hana.c
+++ b/src/overlays/actors/ovl_Obj_Hana/z_obj_hana.c
@@ -5,6 +5,11 @@
*/
#include "z_obj_hana.h"
+
+#include "ichain.h"
+#include "z64play.h"
+#include "z64save.h"
+
#include "assets/objects/gameplay_field_keep/gameplay_field_keep.h"
#define FLAGS 0
diff --git a/src/overlays/actors/ovl_Obj_Hana/z_obj_hana.h b/src/overlays/actors/ovl_Obj_Hana/z_obj_hana.h
index 7fdd3bfa8..69c08b4cb 100644
--- a/src/overlays/actors/ovl_Obj_Hana/z_obj_hana.h
+++ b/src/overlays/actors/ovl_Obj_Hana/z_obj_hana.h
@@ -2,7 +2,7 @@
#define Z_OBJ_HANA_H
#include "ultra64.h"
-#include "global.h"
+#include "z64actor.h"
struct ObjHana;
diff --git a/src/overlays/actors/ovl_Obj_Hsblock/z_obj_hsblock.c b/src/overlays/actors/ovl_Obj_Hsblock/z_obj_hsblock.c
index d94607767..e76c10465 100644
--- a/src/overlays/actors/ovl_Obj_Hsblock/z_obj_hsblock.c
+++ b/src/overlays/actors/ovl_Obj_Hsblock/z_obj_hsblock.c
@@ -5,6 +5,15 @@
*/
#include "z_obj_hsblock.h"
+
+#include "gfx.h"
+#include "gfx_setupdl.h"
+#include "ichain.h"
+#include "regs.h"
+#include "sys_matrix.h"
+#include "z_lib.h"
+#include "z64play.h"
+
#include "assets/objects/object_d_hsblock/object_d_hsblock.h"
#define FLAGS 0
diff --git a/src/overlays/actors/ovl_Obj_Hsblock/z_obj_hsblock.h b/src/overlays/actors/ovl_Obj_Hsblock/z_obj_hsblock.h
index 6548ca9b9..299ba7d3d 100644
--- a/src/overlays/actors/ovl_Obj_Hsblock/z_obj_hsblock.h
+++ b/src/overlays/actors/ovl_Obj_Hsblock/z_obj_hsblock.h
@@ -2,11 +2,11 @@
#define Z_OBJ_HSBLOCK_H
#include "ultra64.h"
-#include "global.h"
+#include "z64actor.h"
struct ObjHsblock;
-typedef void (*ObjHsblockActionFunc)(struct ObjHsblock*, PlayState*);
+typedef void (*ObjHsblockActionFunc)(struct ObjHsblock*, struct PlayState*);
typedef struct ObjHsblock {
/* 0x0000 */ DynaPolyActor dyna;
diff --git a/src/overlays/actors/ovl_Obj_Ice_Poly/z_obj_ice_poly.c b/src/overlays/actors/ovl_Obj_Ice_Poly/z_obj_ice_poly.c
index 23b1728fc..71ff43d27 100644
--- a/src/overlays/actors/ovl_Obj_Ice_Poly/z_obj_ice_poly.c
+++ b/src/overlays/actors/ovl_Obj_Ice_Poly/z_obj_ice_poly.c
@@ -5,6 +5,17 @@
*/
#include "z_obj_ice_poly.h"
+
+#include "libc64/qrand.h"
+#include "gfx.h"
+#include "gfx_setupdl.h"
+#include "one_point_cutscene.h"
+#include "sfx.h"
+#include "sys_matrix.h"
+#include "z_lib.h"
+#include "z64effect.h"
+#include "z64play.h"
+
#include "assets/objects/gameplay_keep/gameplay_keep.h"
#define FLAGS ACTOR_FLAG_UPDATE_CULLING_DISABLED
@@ -85,18 +96,18 @@ void ObjIcePoly_Init(Actor* thisx, PlayState* play) {
}
Actor_SetScale(thisx, sScale[thisx->params]);
thisx->world.pos.y = sOffsetY[thisx->params] + thisx->home.pos.y;
- Collider_InitCylinder(play, &this->colliderIce);
- Collider_SetCylinder(play, &this->colliderIce, thisx, &sCylinderInitIce);
- Collider_InitCylinder(play, &this->colliderHard);
- Collider_SetCylinder(play, &this->colliderHard, thisx, &sCylinderInitHard);
- Collider_UpdateCylinder(thisx, &this->colliderIce);
- Collider_UpdateCylinder(thisx, &this->colliderHard);
+ Collider_InitCylinder(play, &this->iceCollider);
+ Collider_SetCylinder(play, &this->iceCollider, thisx, &sCylinderInitIce);
+ Collider_InitCylinder(play, &this->hardCollider);
+ Collider_SetCylinder(play, &this->hardCollider, thisx, &sCylinderInitHard);
+ Collider_UpdateCylinder(thisx, &this->iceCollider);
+ Collider_UpdateCylinder(thisx, &this->hardCollider);
thisx->colChkInfo.mass = MASS_IMMOVABLE;
this->alpha = 255;
- this->colliderIce.dim.radius *= thisx->scale.x;
- this->colliderIce.dim.height *= thisx->scale.y;
- this->colliderHard.dim.radius *= thisx->scale.x;
- this->colliderHard.dim.height *= thisx->scale.y;
+ this->iceCollider.dim.radius *= thisx->scale.x;
+ this->iceCollider.dim.height *= thisx->scale.y;
+ this->hardCollider.dim.radius *= thisx->scale.x;
+ this->hardCollider.dim.height *= thisx->scale.y;
Actor_SetFocus(thisx, thisx->scale.y * 30.0f);
this->actionFunc = ObjIcePoly_Idle;
}
@@ -106,8 +117,8 @@ void ObjIcePoly_Destroy(Actor* thisx, PlayState* play) {
ObjIcePoly* this = (ObjIcePoly*)thisx;
if ((this->actor.params >= 0) && (this->actor.params < 3)) {
- Collider_DestroyCylinder(play, &this->colliderIce);
- Collider_DestroyCylinder(play, &this->colliderHard);
+ Collider_DestroyCylinder(play, &this->iceCollider);
+ Collider_DestroyCylinder(play, &this->hardCollider);
}
}
@@ -116,17 +127,17 @@ void ObjIcePoly_Idle(ObjIcePoly* this, PlayState* play) {
s32 pad;
Vec3f pos;
- if (this->colliderIce.base.acFlags & AC_HIT) {
- this->meltTimer = -this->colliderIce.elem.acHitElem->atDmgInfo.damage;
+ if (this->iceCollider.base.acFlags & AC_HIT) {
+ this->meltTimer = -this->iceCollider.elem.acHitElem->atDmgInfo.damage;
this->actor.focus.rot.y = this->actor.yawTowardsPlayer;
OnePointCutscene_Init(play, 5120, 40, &this->actor, CAM_ID_MAIN);
this->actionFunc = ObjIcePoly_Melt;
} else if (this->actor.parent != NULL) {
this->actor.parent->freezeTimer = 40;
- CollisionCheck_SetAT(play, &play->colChkCtx, &this->colliderIce.base);
- CollisionCheck_SetAC(play, &play->colChkCtx, &this->colliderIce.base);
- CollisionCheck_SetOC(play, &play->colChkCtx, &this->colliderIce.base);
- CollisionCheck_SetAC(play, &play->colChkCtx, &this->colliderHard.base);
+ CollisionCheck_SetAT(play, &play->colChkCtx, &this->iceCollider.base);
+ CollisionCheck_SetAC(play, &play->colChkCtx, &this->iceCollider.base);
+ CollisionCheck_SetOC(play, &play->colChkCtx, &this->iceCollider.base);
+ CollisionCheck_SetAC(play, &play->colChkCtx, &this->hardCollider.base);
} else {
Actor_Kill(&this->actor);
}
diff --git a/src/overlays/actors/ovl_Obj_Ice_Poly/z_obj_ice_poly.h b/src/overlays/actors/ovl_Obj_Ice_Poly/z_obj_ice_poly.h
index 8ebbe8d12..c6a56d16f 100644
--- a/src/overlays/actors/ovl_Obj_Ice_Poly/z_obj_ice_poly.h
+++ b/src/overlays/actors/ovl_Obj_Ice_Poly/z_obj_ice_poly.h
@@ -2,11 +2,11 @@
#define Z_OBJ_ICE_POLY_H
#include "ultra64.h"
-#include "global.h"
+#include "z64actor.h"
struct ObjIcePoly;
-typedef void (*ObjIcePolyActionFunc)(struct ObjIcePoly*, PlayState*);
+typedef void (*ObjIcePolyActionFunc)(struct ObjIcePoly*, struct PlayState*);
typedef struct ObjIcePoly {
/* 0x0000 */ Actor actor;
@@ -14,8 +14,8 @@ typedef struct ObjIcePoly {
/* 0x0150 */ u8 alpha;
/* 0x0151 */ u8 unk_151; // Unused. Probably intended to be a switch flag.
/* 0x0152 */ s16 meltTimer;
- /* 0x0154 */ ColliderCylinder colliderIce;
- /* 0x01A0 */ ColliderCylinder colliderHard;
+ /* 0x0154 */ ColliderCylinder iceCollider;
+ /* 0x01A0 */ ColliderCylinder hardCollider;
} ObjIcePoly; // size = 0x01EC
#endif
diff --git a/src/overlays/actors/ovl_Obj_Lift/z_obj_lift.c b/src/overlays/actors/ovl_Obj_Lift/z_obj_lift.c
index e13352a5a..1545430f1 100644
--- a/src/overlays/actors/ovl_Obj_Lift/z_obj_lift.c
+++ b/src/overlays/actors/ovl_Obj_Lift/z_obj_lift.c
@@ -5,9 +5,17 @@
*/
#include "z_obj_lift.h"
-#include "assets/objects/object_d_lift/object_d_lift.h"
#include "overlays/effects/ovl_Effect_Ss_Kakera/z_eff_ss_kakera.h"
+
+#include "libc64/qrand.h"
+#include "ichain.h"
#include "quake.h"
+#include "sfx.h"
+#include "z_lib.h"
+#include "z64effect.h"
+#include "z64play.h"
+
+#include "assets/objects/object_d_lift/object_d_lift.h"
#define FLAGS ACTOR_FLAG_UPDATE_CULLING_DISABLED
diff --git a/src/overlays/actors/ovl_Obj_Lift/z_obj_lift.h b/src/overlays/actors/ovl_Obj_Lift/z_obj_lift.h
index 6ca27ddda..e3f217b93 100644
--- a/src/overlays/actors/ovl_Obj_Lift/z_obj_lift.h
+++ b/src/overlays/actors/ovl_Obj_Lift/z_obj_lift.h
@@ -2,11 +2,11 @@
#define Z_OBJ_LIFT_H
#include "ultra64.h"
-#include "global.h"
+#include "z64actor.h"
struct ObjLift;
-typedef void (*ObjLiftActionFunc)(struct ObjLift*, PlayState*);
+typedef void (*ObjLiftActionFunc)(struct ObjLift*, struct PlayState*);
typedef struct ObjLift {
/* 0x0000 */ DynaPolyActor dyna;
diff --git a/src/overlays/actors/ovl_Obj_Lightswitch/z_obj_lightswitch.c b/src/overlays/actors/ovl_Obj_Lightswitch/z_obj_lightswitch.c
index 24bcb06a6..a433834d6 100644
--- a/src/overlays/actors/ovl_Obj_Lightswitch/z_obj_lightswitch.c
+++ b/src/overlays/actors/ovl_Obj_Lightswitch/z_obj_lightswitch.c
@@ -5,8 +5,21 @@
*/
#include "z_obj_lightswitch.h"
-#include "terminal.h"
#include "overlays/actors/ovl_Obj_Oshihiki/z_obj_oshihiki.h"
+
+#include "libc64/qrand.h"
+#include "gfx.h"
+#include "gfx_setupdl.h"
+#include "ichain.h"
+#include "one_point_cutscene.h"
+#include "segmented_address.h"
+#include "sfx.h"
+#include "sys_matrix.h"
+#include "terminal.h"
+#include "z_lib.h"
+#include "z64effect.h"
+#include "z64play.h"
+
#include "assets/objects/object_lightswitch/object_lightswitch.h"
#define FLAGS ACTOR_FLAG_UPDATE_CULLING_DISABLED
@@ -47,7 +60,7 @@ ActorProfile Obj_Lightswitch_Profile = {
/**/ ObjLightswitch_Draw,
};
-static ColliderJntSphElementInit sColliderJntSphElementInit[] = {
+static ColliderJntSphElementInit sColliderJntSphElementsInit[] = {
{
{
ELEM_MATERIAL_UNK0,
@@ -70,7 +83,7 @@ static ColliderJntSphInit sColliderJntSphInit = {
COLSHAPE_JNTSPH,
},
1,
- sColliderJntSphElementInit,
+ sColliderJntSphElementsInit,
};
static CollisionCheckInfoInit sColChkInfoInit = { 0, 12, 60, MASS_IMMOVABLE };
diff --git a/src/overlays/actors/ovl_Obj_Lightswitch/z_obj_lightswitch.h b/src/overlays/actors/ovl_Obj_Lightswitch/z_obj_lightswitch.h
index 54b7e162f..7f0834a24 100644
--- a/src/overlays/actors/ovl_Obj_Lightswitch/z_obj_lightswitch.h
+++ b/src/overlays/actors/ovl_Obj_Lightswitch/z_obj_lightswitch.h
@@ -2,11 +2,11 @@
#define Z_OBJ_LIGHTSWITCH_H
#include "ultra64.h"
-#include "global.h"
+#include "z64actor.h"
struct ObjLightswitch;
-typedef void (*ObjLightswitchActionFunc)(struct ObjLightswitch*, PlayState*);
+typedef void (*ObjLightswitchActionFunc)(struct ObjLightswitch*, struct PlayState*);
typedef enum ObjLightswitch_Type {
/* 0 */ OBJLIGHTSWITCH_TYPE_STAY_ON, // doesn't turn off unless the switch flag is cleared some other way
diff --git a/src/overlays/actors/ovl_Obj_Makekinsuta/z_obj_makekinsuta.c b/src/overlays/actors/ovl_Obj_Makekinsuta/z_obj_makekinsuta.c
index 7ac997ae6..93c4b9cdf 100644
--- a/src/overlays/actors/ovl_Obj_Makekinsuta/z_obj_makekinsuta.c
+++ b/src/overlays/actors/ovl_Obj_Makekinsuta/z_obj_makekinsuta.c
@@ -5,8 +5,10 @@
*/
#include "z_obj_makekinsuta.h"
-#include "global.h"
+
#include "terminal.h"
+#include "z64play.h"
+#include "z64player.h"
#define FLAGS ACTOR_FLAG_UPDATE_CULLING_DISABLED
diff --git a/src/overlays/actors/ovl_Obj_Makeoshihiki/z_obj_makeoshihiki.c b/src/overlays/actors/ovl_Obj_Makeoshihiki/z_obj_makeoshihiki.c
index 3ea20567e..5004472a5 100644
--- a/src/overlays/actors/ovl_Obj_Makeoshihiki/z_obj_makeoshihiki.c
+++ b/src/overlays/actors/ovl_Obj_Makeoshihiki/z_obj_makeoshihiki.c
@@ -6,7 +6,13 @@
#include "z_obj_makeoshihiki.h"
#include "overlays/actors/ovl_Obj_Oshihiki/z_obj_oshihiki.h"
+
+#include "sfx.h"
+#include "sys_math3d.h"
+#include "sys_matrix.h"
#include "terminal.h"
+#include "z_lib.h"
+#include "z64play.h"
#define FLAGS ACTOR_FLAG_DRAW_CULLING_DISABLED
diff --git a/src/overlays/actors/ovl_Obj_Makeoshihiki/z_obj_makeoshihiki.h b/src/overlays/actors/ovl_Obj_Makeoshihiki/z_obj_makeoshihiki.h
index 16dc3ba47..84938f578 100644
--- a/src/overlays/actors/ovl_Obj_Makeoshihiki/z_obj_makeoshihiki.h
+++ b/src/overlays/actors/ovl_Obj_Makeoshihiki/z_obj_makeoshihiki.h
@@ -2,7 +2,7 @@
#define Z_OBJ_MAKEOSHIHIKI_H
#include "ultra64.h"
-#include "global.h"
+#include "z64actor.h"
struct ObjMakeoshihiki;
diff --git a/src/overlays/actors/ovl_Obj_Mure2/z_obj_mure2.c b/src/overlays/actors/ovl_Obj_Mure2/z_obj_mure2.c
index bcdb0558e..ecffdfbe7 100644
--- a/src/overlays/actors/ovl_Obj_Mure2/z_obj_mure2.c
+++ b/src/overlays/actors/ovl_Obj_Mure2/z_obj_mure2.c
@@ -6,6 +6,11 @@
#include "z_obj_mure2.h"
+#include "ichain.h"
+#include "sys_math3d.h"
+#include "z_lib.h"
+#include "z64play.h"
+
#define FLAGS 0
typedef void (*ObjMure2SetPosFunc)(Vec3f* vec, ObjMure2* this);
diff --git a/src/overlays/actors/ovl_Obj_Mure2/z_obj_mure2.h b/src/overlays/actors/ovl_Obj_Mure2/z_obj_mure2.h
index a197e9f7b..8643d477e 100644
--- a/src/overlays/actors/ovl_Obj_Mure2/z_obj_mure2.h
+++ b/src/overlays/actors/ovl_Obj_Mure2/z_obj_mure2.h
@@ -2,11 +2,11 @@
#define Z_OBJ_MURE2_H
#include "ultra64.h"
-#include "global.h"
+#include "z64actor.h"
struct ObjMure2;
-typedef void (*ObjMure2ActionFunc)(struct ObjMure2*, PlayState*);
+typedef void (*ObjMure2ActionFunc)(struct ObjMure2*, struct PlayState*);
typedef struct ObjMure2 {
/* 0x0000 */ Actor actor;
diff --git a/src/overlays/actors/ovl_Obj_Oshihiki/z_obj_oshihiki.c b/src/overlays/actors/ovl_Obj_Oshihiki/z_obj_oshihiki.c
index ed9d39e3d..729c55332 100644
--- a/src/overlays/actors/ovl_Obj_Oshihiki/z_obj_oshihiki.c
+++ b/src/overlays/actors/ovl_Obj_Oshihiki/z_obj_oshihiki.c
@@ -6,6 +6,18 @@
#include "z_obj_oshihiki.h"
#include "overlays/actors/ovl_Obj_Switch/z_obj_switch.h"
+
+#include "gfx.h"
+#include "gfx_setupdl.h"
+#include "ichain.h"
+#include "regs.h"
+#include "segmented_address.h"
+#include "sfx.h"
+#include "sys_matrix.h"
+#include "z_lib.h"
+#include "z64play.h"
+#include "z64player.h"
+
#include "assets/objects/gameplay_dangeon_keep/gameplay_dangeon_keep.h"
#define FLAGS ACTOR_FLAG_UPDATE_CULLING_DISABLED
diff --git a/src/overlays/actors/ovl_Obj_Oshihiki/z_obj_oshihiki.h b/src/overlays/actors/ovl_Obj_Oshihiki/z_obj_oshihiki.h
index 90dce5ca4..265ba4691 100644
--- a/src/overlays/actors/ovl_Obj_Oshihiki/z_obj_oshihiki.h
+++ b/src/overlays/actors/ovl_Obj_Oshihiki/z_obj_oshihiki.h
@@ -2,7 +2,7 @@
#define Z_OBJ_OSHIHIKI_H
#include "ultra64.h"
-#include "global.h"
+#include "z64actor.h"
struct ObjOshihiki;
@@ -27,7 +27,7 @@ typedef enum PushBlockType {
#define PUSHBLOCK_SETUP_FALL (1 << 7)
#define PUSHBLOCK_MOVE_UNDER (1 << 8)
-typedef void (*ObjOshihikiActionFunc)(struct ObjOshihiki*, PlayState*);
+typedef void (*ObjOshihikiActionFunc)(struct ObjOshihiki*, struct PlayState*);
typedef struct ObjOshihiki {
/* 0x0000 */ DynaPolyActor dyna;
@@ -40,7 +40,7 @@ typedef struct ObjOshihiki {
/* 0x0178 */ f32 pushDist;
/* 0x017C */ f32 direction;
/* 0x0180 */ s32 floorBgIds[5];
- /* 0x0194 */ CollisionPoly* floorPolys[5];
+ /* 0x0194 */ struct CollisionPoly* floorPolys[5];
/* 0x01A8 */ f32 floorHeights[5];
/* 0x01BC */ s16 highestFloor;
/* 0x01BE */ u8 cantMove;
diff --git a/src/overlays/actors/ovl_Obj_Roomtimer/z_obj_roomtimer.c b/src/overlays/actors/ovl_Obj_Roomtimer/z_obj_roomtimer.c
index 8ed5e8558..6eca37968 100644
--- a/src/overlays/actors/ovl_Obj_Roomtimer/z_obj_roomtimer.c
+++ b/src/overlays/actors/ovl_Obj_Roomtimer/z_obj_roomtimer.c
@@ -6,6 +6,11 @@
#include "z_obj_roomtimer.h"
+#include "sfx.h"
+#include "z_lib.h"
+#include "z64play.h"
+#include "z64save.h"
+
#define FLAGS ACTOR_FLAG_UPDATE_CULLING_DISABLED
void ObjRoomtimer_Init(Actor* thisx, PlayState* play);
diff --git a/src/overlays/actors/ovl_Obj_Roomtimer/z_obj_roomtimer.h b/src/overlays/actors/ovl_Obj_Roomtimer/z_obj_roomtimer.h
index 2f1b08d9c..ee8e74eaa 100644
--- a/src/overlays/actors/ovl_Obj_Roomtimer/z_obj_roomtimer.h
+++ b/src/overlays/actors/ovl_Obj_Roomtimer/z_obj_roomtimer.h
@@ -2,12 +2,11 @@
#define Z_OBJ_ROOMTIMER_H
#include "ultra64.h"
-#include "global.h"
-#include "z64.h"
+#include "z64actor.h"
struct ObjRoomtimer;
-typedef void (*ObjRoomtimerActionFunc)(struct ObjRoomtimer*, PlayState*);
+typedef void (*ObjRoomtimerActionFunc)(struct ObjRoomtimer*, struct PlayState*);
typedef struct ObjRoomtimer {
/* 0x0000 */ Actor actor;
diff --git a/src/overlays/actors/ovl_Obj_Switch/z_obj_switch.c b/src/overlays/actors/ovl_Obj_Switch/z_obj_switch.c
index 1df623a71..9556f8c31 100644
--- a/src/overlays/actors/ovl_Obj_Switch/z_obj_switch.c
+++ b/src/overlays/actors/ovl_Obj_Switch/z_obj_switch.c
@@ -5,8 +5,21 @@
*/
#include "z_obj_switch.h"
-#include "assets/objects/gameplay_dangeon_keep/gameplay_dangeon_keep.h"
+
+#include "gfx.h"
+#include "gfx_setupdl.h"
+#include "ichain.h"
+#include "one_point_cutscene.h"
+#include "rumble.h"
+#include "segmented_address.h"
+#include "sfx.h"
+#include "sys_matrix.h"
#include "terminal.h"
+#include "z_lib.h"
+#include "z64play.h"
+#include "z64player.h"
+
+#include "assets/objects/gameplay_dangeon_keep/gameplay_dangeon_keep.h"
#define FLAGS ACTOR_FLAG_UPDATE_CULLING_DISABLED
@@ -147,7 +160,7 @@ static ColliderTrisInit sEyeTrisInit = {
sEyeTrisElementsInit,
};
-static ColliderJntSphElementInit sCrystalJntSphElementInit[1] = {
+static ColliderJntSphElementInit sCrystalJntSphElementsInit[1] = {
{
{
ELEM_MATERIAL_UNK0,
@@ -170,8 +183,8 @@ static ColliderJntSphInit sCrystalJntSphInit = {
OC2_TYPE_2,
COLSHAPE_JNTSPH,
},
- ARRAY_COUNT(sCrystalJntSphElementInit),
- sCrystalJntSphElementInit,
+ ARRAY_COUNT(sCrystalJntSphElementsInit),
+ sCrystalJntSphElementsInit,
};
static InitChainEntry sInitChain[] = {
@@ -210,10 +223,10 @@ void ObjSwitch_InitDynaPoly(ObjSwitch* this, PlayState* play, CollisionHeader* c
}
void ObjSwitch_InitJntSphCollider(ObjSwitch* this, PlayState* play, ColliderJntSphInit* colliderJntSphInit) {
- ColliderJntSph* colliderJntSph = &this->jntSph.col;
+ ColliderJntSph* colliderJntSph = &this->jntSph.collider;
Collider_InitJntSph(play, colliderJntSph);
- Collider_SetJntSph(play, colliderJntSph, &this->dyna.actor, colliderJntSphInit, this->jntSph.elements);
+ Collider_SetJntSph(play, colliderJntSph, &this->dyna.actor, colliderJntSphInit, this->jntSph.colliderElements);
Matrix_SetTranslateRotateYXZ(this->dyna.actor.world.pos.x,
this->dyna.actor.world.pos.y +
this->dyna.actor.shape.yOffset * this->dyna.actor.scale.y,
@@ -223,13 +236,13 @@ void ObjSwitch_InitJntSphCollider(ObjSwitch* this, PlayState* play, ColliderJntS
}
void ObjSwitch_InitTrisCollider(ObjSwitch* this, PlayState* play, ColliderTrisInit* colliderTrisInit) {
- ColliderTris* colliderTris = &this->tris.col;
+ ColliderTris* colliderTris = &this->tris.collider;
s32 i;
s32 j;
Vec3f pos[3];
Collider_InitTris(play, colliderTris);
- Collider_SetTris(play, colliderTris, &this->dyna.actor, colliderTrisInit, this->tris.elements);
+ Collider_SetTris(play, colliderTris, &this->dyna.actor, colliderTrisInit, this->tris.colliderElements);
for (i = 0; i < 2; i++) {
for (j = 0; j < 3; j++) {
@@ -368,12 +381,12 @@ void ObjSwitch_Destroy(Actor* thisx, PlayState* play) {
switch (OBJSWITCH_TYPE(&this->dyna.actor)) {
case OBJSWITCH_TYPE_FLOOR_RUSTY:
case OBJSWITCH_TYPE_EYE:
- Collider_DestroyTris(play, &this->tris.col);
+ Collider_DestroyTris(play, &this->tris.collider);
break;
case OBJSWITCH_TYPE_CRYSTAL:
case OBJSWITCH_TYPE_CRYSTAL_TARGETABLE:
- Collider_DestroyJntSph(play, &this->jntSph.col);
+ Collider_DestroyJntSph(play, &this->jntSph.collider);
break;
}
}
@@ -385,12 +398,12 @@ void ObjSwitch_FloorUpInit(ObjSwitch* this) {
void ObjSwitch_FloorUp(ObjSwitch* this, PlayState* play) {
if (OBJSWITCH_TYPE(&this->dyna.actor) == OBJSWITCH_TYPE_FLOOR_RUSTY) {
- if (this->tris.col.base.acFlags & AC_HIT) {
+ if (this->tris.collider.base.acFlags & AC_HIT) {
ObjSwitch_FloorPressInit(this);
ObjSwitch_SetOn(this, play);
- this->tris.col.base.acFlags &= ~AC_HIT;
+ this->tris.collider.base.acFlags &= ~AC_HIT;
} else {
- CollisionCheck_SetAC(play, &play->colChkCtx, &this->tris.col.base);
+ CollisionCheck_SetAC(play, &play->colChkCtx, &this->tris.collider.base);
}
} else {
switch (OBJSWITCH_SUBTYPE(&this->dyna.actor)) {
@@ -509,8 +522,8 @@ s32 ObjSwitch_EyeIsHit(ObjSwitch* this) {
Actor* collidingActor;
s16 yawDiff;
- if ((this->tris.col.base.acFlags & AC_HIT) && !(this->prevColFlags & AC_HIT)) {
- collidingActor = this->tris.col.base.ac;
+ if ((this->tris.collider.base.acFlags & AC_HIT) && !(this->prevColFlags & AC_HIT)) {
+ collidingActor = this->tris.collider.base.ac;
if (collidingActor != NULL) {
yawDiff = collidingActor->world.rot.y - this->dyna.actor.shape.rot.y;
if (ABS(yawDiff) > 0x5000) {
@@ -613,7 +626,7 @@ void ObjSwitch_CrystalOffInit(ObjSwitch* this) {
void ObjSwitch_CrystalOff(ObjSwitch* this, PlayState* play) {
switch (OBJSWITCH_SUBTYPE(&this->dyna.actor)) {
case OBJSWITCH_SUBTYPE_ONCE:
- if ((this->jntSph.col.base.acFlags & AC_HIT) && this->disableAcTimer <= 0) {
+ if ((this->jntSph.collider.base.acFlags & AC_HIT) && this->disableAcTimer <= 0) {
this->disableAcTimer = 10;
ObjSwitch_SetOn(this, play);
ObjSwitch_CrystalTurnOnInit(this);
@@ -621,7 +634,7 @@ void ObjSwitch_CrystalOff(ObjSwitch* this, PlayState* play) {
break;
case OBJSWITCH_SUBTYPE_SYNC:
- if (((this->jntSph.col.base.acFlags & AC_HIT) && this->disableAcTimer <= 0) ||
+ if (((this->jntSph.collider.base.acFlags & AC_HIT) && this->disableAcTimer <= 0) ||
Flags_GetSwitch(play, OBJSWITCH_SWITCH_FLAG(&this->dyna.actor))) {
this->disableAcTimer = 10;
@@ -631,7 +644,7 @@ void ObjSwitch_CrystalOff(ObjSwitch* this, PlayState* play) {
break;
case OBJSWITCH_SUBTYPE_TOGGLE:
- if ((this->jntSph.col.base.acFlags & AC_HIT) && !(this->prevColFlags & AC_HIT) &&
+ if ((this->jntSph.collider.base.acFlags & AC_HIT) && !(this->prevColFlags & AC_HIT) &&
this->disableAcTimer <= 0) {
this->disableAcTimer = 10;
ObjSwitch_SetOn(this, play);
@@ -675,7 +688,7 @@ void ObjSwitch_CrystalOn(ObjSwitch* this, PlayState* play) {
break;
case OBJSWITCH_SUBTYPE_TOGGLE:
- if ((this->jntSph.col.base.acFlags & AC_HIT) && !(this->prevColFlags & AC_HIT) &&
+ if ((this->jntSph.collider.base.acFlags & AC_HIT) && !(this->prevColFlags & AC_HIT) &&
this->disableAcTimer <= 0) {
this->disableAcTimer = 10;
ObjSwitch_CrystalTurnOffInit(this);
@@ -719,9 +732,9 @@ void ObjSwitch_Update(Actor* thisx, PlayState* play) {
break;
case OBJSWITCH_TYPE_EYE:
- this->prevColFlags = this->tris.col.base.acFlags;
- this->tris.col.base.acFlags &= ~AC_HIT;
- CollisionCheck_SetAC(play, &play->colChkCtx, &this->tris.col.base);
+ this->prevColFlags = this->tris.collider.base.acFlags;
+ this->tris.collider.base.acFlags &= ~AC_HIT;
+ CollisionCheck_SetAC(play, &play->colChkCtx, &this->tris.collider.base);
break;
case OBJSWITCH_TYPE_CRYSTAL:
@@ -729,12 +742,12 @@ void ObjSwitch_Update(Actor* thisx, PlayState* play) {
if (!Player_InCsMode(play) && this->disableAcTimer > 0) {
this->disableAcTimer--;
}
- this->prevColFlags = this->jntSph.col.base.acFlags;
- this->jntSph.col.base.acFlags &= ~AC_HIT;
+ this->prevColFlags = this->jntSph.collider.base.acFlags;
+ this->jntSph.collider.base.acFlags &= ~AC_HIT;
if (this->disableAcTimer <= 0) {
- CollisionCheck_SetAC(play, &play->colChkCtx, &this->jntSph.col.base);
+ CollisionCheck_SetAC(play, &play->colChkCtx, &this->jntSph.collider.base);
}
- CollisionCheck_SetOC(play, &play->colChkCtx, &this->jntSph.col.base);
+ CollisionCheck_SetOC(play, &play->colChkCtx, &this->jntSph.collider.base);
break;
}
}
diff --git a/src/overlays/actors/ovl_Obj_Switch/z_obj_switch.h b/src/overlays/actors/ovl_Obj_Switch/z_obj_switch.h
index 9e6475eb2..b4d3ae8b2 100644
--- a/src/overlays/actors/ovl_Obj_Switch/z_obj_switch.h
+++ b/src/overlays/actors/ovl_Obj_Switch/z_obj_switch.h
@@ -2,12 +2,12 @@
#define Z_OBJ_SWITCH_H
#include "ultra64.h"
-#include "global.h"
+#include "z64actor.h"
struct ObjSwitch;
-typedef void (*ObjSwitchActionFunc)(struct ObjSwitch*, PlayState*);
-typedef void (*ObjSwitchDrawFunc)(Actor*, PlayState*);
+typedef void (*ObjSwitchActionFunc)(struct ObjSwitch*, struct PlayState*);
+typedef void (*ObjSwitchDrawFunc)(Actor*, struct PlayState*);
typedef enum ObjSwitchType {
/* 0 */ OBJSWITCH_TYPE_FLOOR,
@@ -26,13 +26,13 @@ typedef enum ObjSwitchSubType {
} ObjSwitchSubType;
typedef struct ObjSwitchJntSph {
- /* 0x00 */ ColliderJntSph col;
- /* 0x20 */ ColliderJntSphElement elements[1];
+ /* 0x00 */ ColliderJntSph collider;
+ /* 0x20 */ ColliderJntSphElement colliderElements[1];
} ObjSwitchJntSph;
typedef struct ObjSwitchTris {
- /* 0x00 */ ColliderTris col;
- /* 0x20 */ ColliderTrisElement elements[2];
+ /* 0x00 */ ColliderTris collider;
+ /* 0x20 */ ColliderTrisElement colliderElements[2];
} ObjSwitchTris;
typedef struct ObjSwitch {
diff --git a/src/overlays/actors/ovl_Obj_Syokudai/z_obj_syokudai.c b/src/overlays/actors/ovl_Obj_Syokudai/z_obj_syokudai.c
index acdf87414..a189fe434 100644
--- a/src/overlays/actors/ovl_Obj_Syokudai/z_obj_syokudai.c
+++ b/src/overlays/actors/ovl_Obj_Syokudai/z_obj_syokudai.c
@@ -97,12 +97,12 @@ void ObjSyokudai_Init(Actor* thisx, PlayState* play) {
Actor_ProcessInitChain(&this->actor, sInitChain);
ActorShape_Init(&this->actor.shape, 0.0f, NULL, 0.0f);
- Collider_InitCylinder(play, &this->colliderStand);
- Collider_SetCylinder(play, &this->colliderStand, &this->actor, &sCylInitStand);
- this->colliderStand.base.colMaterial = sColMaterialsStand[PARAMS_GET_NOMASK(this->actor.params, 12)];
+ Collider_InitCylinder(play, &this->standCollider);
+ Collider_SetCylinder(play, &this->standCollider, &this->actor, &sCylInitStand);
+ this->standCollider.base.colMaterial = sColMaterialsStand[PARAMS_GET_NOMASK(this->actor.params, 12)];
- Collider_InitCylinder(play, &this->colliderFlame);
- Collider_SetCylinder(play, &this->colliderFlame, &this->actor, &sCylInitFlame);
+ Collider_InitCylinder(play, &this->flameCollider);
+ Collider_SetCylinder(play, &this->flameCollider, &this->actor, &sCylInitFlame);
this->actor.colChkInfo.mass = MASS_IMMOVABLE;
@@ -124,8 +124,8 @@ void ObjSyokudai_Destroy(Actor* thisx, PlayState* play) {
s32 pad;
ObjSyokudai* this = (ObjSyokudai*)thisx;
- Collider_DestroyCylinder(play, &this->colliderStand);
- Collider_DestroyCylinder(play, &this->colliderFlame);
+ Collider_DestroyCylinder(play, &this->standCollider);
+ Collider_DestroyCylinder(play, &this->flameCollider);
LightContext_RemoveLight(play, &play->lightCtx, this->lightNode);
}
@@ -182,8 +182,8 @@ void ObjSyokudai_Update(Actor* thisx, PlayState* play2) {
this->litTimer = 20;
}
}
- if (this->colliderFlame.base.acFlags & AC_HIT) {
- dmgFlags = this->colliderFlame.elem.acHitElem->atDmgInfo.dmgFlags;
+ if (this->flameCollider.base.acFlags & AC_HIT) {
+ dmgFlags = this->flameCollider.elem.acHitElem->atDmgInfo.dmgFlags;
if (dmgFlags & (DMG_FIRE | DMG_ARROW_NORMAL)) {
interactionType = 1;
}
@@ -206,7 +206,7 @@ void ObjSyokudai_Update(Actor* thisx, PlayState* play2) {
player->unk_860 = 200;
}
} else if (dmgFlags & DMG_ARROW_NORMAL) {
- arrow = (EnArrow*)this->colliderFlame.base.ac;
+ arrow = (EnArrow*)this->flameCollider.base.ac;
if ((arrow->actor.update != NULL) && (arrow->actor.id == ACTOR_EN_ARROW)) {
arrow->actor.params = 0;
arrow->collider.elem.atDmgInfo.dmgFlags = DMG_ARROW_FIRE;
@@ -243,12 +243,12 @@ void ObjSyokudai_Update(Actor* thisx, PlayState* play2) {
}
}
- Collider_UpdateCylinder(&this->actor, &this->colliderStand);
- CollisionCheck_SetOC(play, &play->colChkCtx, &this->colliderStand.base);
- CollisionCheck_SetAC(play, &play->colChkCtx, &this->colliderStand.base);
+ Collider_UpdateCylinder(&this->actor, &this->standCollider);
+ CollisionCheck_SetOC(play, &play->colChkCtx, &this->standCollider.base);
+ CollisionCheck_SetAC(play, &play->colChkCtx, &this->standCollider.base);
- Collider_UpdateCylinder(&this->actor, &this->colliderFlame);
- CollisionCheck_SetAC(play, &play->colChkCtx, &this->colliderFlame.base);
+ Collider_UpdateCylinder(&this->actor, &this->flameCollider);
+ CollisionCheck_SetAC(play, &play->colChkCtx, &this->flameCollider.base);
if (this->litTimer > 0) {
this->litTimer--;
diff --git a/src/overlays/actors/ovl_Obj_Syokudai/z_obj_syokudai.h b/src/overlays/actors/ovl_Obj_Syokudai/z_obj_syokudai.h
index 795e855ae..4dee2ba67 100644
--- a/src/overlays/actors/ovl_Obj_Syokudai/z_obj_syokudai.h
+++ b/src/overlays/actors/ovl_Obj_Syokudai/z_obj_syokudai.h
@@ -9,8 +9,8 @@ struct ObjSyokudai;
typedef struct ObjSyokudai {
/* 0x0000 */ Actor actor;
- /* 0x014C */ ColliderCylinder colliderStand;
- /* 0x0198 */ ColliderCylinder colliderFlame;
+ /* 0x014C */ ColliderCylinder standCollider;
+ /* 0x0198 */ ColliderCylinder flameCollider;
/* 0x01E4 */ s16 litTimer;
/* 0x01E6 */ u8 flameTexScroll;
/* 0x01E8 */ LightNode* lightNode;
diff --git a/src/overlays/actors/ovl_Obj_Timeblock/z_obj_timeblock.c b/src/overlays/actors/ovl_Obj_Timeblock/z_obj_timeblock.c
index bc231076c..fdd18ef60 100644
--- a/src/overlays/actors/ovl_Obj_Timeblock/z_obj_timeblock.c
+++ b/src/overlays/actors/ovl_Obj_Timeblock/z_obj_timeblock.c
@@ -5,6 +5,19 @@
*/
#include "z_obj_timeblock.h"
+
+#include "gfx.h"
+#include "gfx_setupdl.h"
+#include "ichain.h"
+#include "one_point_cutscene.h"
+#include "sfx.h"
+#include "sys_matrix.h"
+#include "z_lib.h"
+#include "z64ocarina.h"
+#include "z64play.h"
+#include "z64player.h"
+#include "z64save.h"
+
#include "assets/objects/object_timeblock/object_timeblock.h"
#define FLAGS \
diff --git a/src/overlays/actors/ovl_Obj_Timeblock/z_obj_timeblock.h b/src/overlays/actors/ovl_Obj_Timeblock/z_obj_timeblock.h
index 9bd393b19..966f47449 100644
--- a/src/overlays/actors/ovl_Obj_Timeblock/z_obj_timeblock.h
+++ b/src/overlays/actors/ovl_Obj_Timeblock/z_obj_timeblock.h
@@ -2,12 +2,12 @@
#define Z_OBJ_TIMEBLOCK_H
#include "ultra64.h"
-#include "global.h"
+#include "z64actor.h"
struct ObjTimeblock;
-typedef s32 (*ObjTimeblockSongObserverFunc)(struct ObjTimeblock*, PlayState*);
-typedef void (*ObjTimeblockActionFunc)(struct ObjTimeblock*, PlayState*);
+typedef s32 (*ObjTimeblockSongObserverFunc)(struct ObjTimeblock*, struct PlayState*);
+typedef void (*ObjTimeblockActionFunc)(struct ObjTimeblock*, struct PlayState*);
typedef struct ObjTimeblock {
/* 0x0000 */ DynaPolyActor dyna;
diff --git a/src/overlays/actors/ovl_Obj_Tsubo/z_obj_tsubo.c b/src/overlays/actors/ovl_Obj_Tsubo/z_obj_tsubo.c
index 057d660ab..2f4cc15c7 100644
--- a/src/overlays/actors/ovl_Obj_Tsubo/z_obj_tsubo.c
+++ b/src/overlays/actors/ovl_Obj_Tsubo/z_obj_tsubo.c
@@ -13,6 +13,7 @@
#include "z_en_item00.h"
#include "z_lib.h"
#include "z64effect.h"
+#include "z64item.h"
#include "z64play.h"
#include "z64player.h"
diff --git a/src/overlays/actors/ovl_Obj_Warp2block/z_obj_warp2block.c b/src/overlays/actors/ovl_Obj_Warp2block/z_obj_warp2block.c
index 94c661847..aed6b65e7 100644
--- a/src/overlays/actors/ovl_Obj_Warp2block/z_obj_warp2block.c
+++ b/src/overlays/actors/ovl_Obj_Warp2block/z_obj_warp2block.c
@@ -5,8 +5,21 @@
*/
#include "z_obj_warp2block.h"
-#include "assets/objects/object_timeblock/object_timeblock.h"
+
+#include "gfx.h"
+#include "gfx_setupdl.h"
+#include "ichain.h"
+#include "one_point_cutscene.h"
+#include "sfx.h"
+#include "sys_math3d.h"
+#include "sys_matrix.h"
#include "terminal.h"
+#include "z_lib.h"
+#include "z64ocarina.h"
+#include "z64play.h"
+#include "z64player.h"
+
+#include "assets/objects/object_timeblock/object_timeblock.h"
#define FLAGS \
(ACTOR_FLAG_ATTENTION_ENABLED | ACTOR_FLAG_UPDATE_CULLING_DISABLED | ACTOR_FLAG_UPDATE_DURING_OCARINA | \
diff --git a/src/overlays/actors/ovl_Obj_Warp2block/z_obj_warp2block.h b/src/overlays/actors/ovl_Obj_Warp2block/z_obj_warp2block.h
index 3e09d976c..8f22398db 100644
--- a/src/overlays/actors/ovl_Obj_Warp2block/z_obj_warp2block.h
+++ b/src/overlays/actors/ovl_Obj_Warp2block/z_obj_warp2block.h
@@ -2,12 +2,12 @@
#define Z_OBJ_WARP2BLOCK_H
#include "ultra64.h"
-#include "global.h"
+#include "z64actor.h"
struct ObjWarp2block;
-typedef void (*ObjWarp2blockActionFunc)(struct ObjWarp2block*, PlayState*);
-typedef s32 (*ObjWarp2blockFunc168)(struct ObjWarp2block*, PlayState*);
+typedef void (*ObjWarp2blockActionFunc)(struct ObjWarp2block*, struct PlayState*);
+typedef s32 (*ObjWarp2blockFunc168)(struct ObjWarp2block*, struct PlayState*);
typedef struct ObjWarp2block {
/* 0x0000 */ DynaPolyActor dyna;
diff --git a/src/overlays/actors/ovl_Object_Kankyo/z_object_kankyo.c b/src/overlays/actors/ovl_Object_Kankyo/z_object_kankyo.c
index d3f126b1e..d66f7bcf0 100644
--- a/src/overlays/actors/ovl_Object_Kankyo/z_object_kankyo.c
+++ b/src/overlays/actors/ovl_Object_Kankyo/z_object_kankyo.c
@@ -5,6 +5,21 @@
*/
#include "z_object_kankyo.h"
+
+#include "libc64/qrand.h"
+#include "gfx.h"
+#include "gfx_setupdl.h"
+#include "segmented_address.h"
+#include "sequence.h"
+#include "sfx.h"
+#include "sys_math3d.h"
+#include "sys_matrix.h"
+#include "z_lib.h"
+#include "z64audio.h"
+#include "z64play.h"
+#include "z64player.h"
+#include "z64save.h"
+
#include "assets/objects/object_demo_kekkai/object_demo_kekkai.h"
#include "assets/objects/gameplay_keep/gameplay_keep.h"
#include "assets/objects/object_spot02_objects/object_spot02_objects.h"
diff --git a/src/overlays/actors/ovl_Object_Kankyo/z_object_kankyo.h b/src/overlays/actors/ovl_Object_Kankyo/z_object_kankyo.h
index 4449fa013..40307f5e9 100644
--- a/src/overlays/actors/ovl_Object_Kankyo/z_object_kankyo.h
+++ b/src/overlays/actors/ovl_Object_Kankyo/z_object_kankyo.h
@@ -2,11 +2,11 @@
#define Z_OBJECT_KANKYO_H
#include "ultra64.h"
-#include "global.h"
+#include "z64actor.h"
struct ObjectKankyo;
-typedef void (*ObjectKankyoActionFunc)(struct ObjectKankyo*, PlayState*);
+typedef void (*ObjectKankyoActionFunc)(struct ObjectKankyo*, struct PlayState*);
typedef struct ObjectKankyoEffect {
/* 0x00 */ u8 state;
diff --git a/src/overlays/actors/ovl_Oceff_Spot/z_oceff_spot.c b/src/overlays/actors/ovl_Oceff_Spot/z_oceff_spot.c
index 5aeb61031..c9d6470d6 100644
--- a/src/overlays/actors/ovl_Oceff_Spot/z_oceff_spot.c
+++ b/src/overlays/actors/ovl_Oceff_Spot/z_oceff_spot.c
@@ -5,7 +5,19 @@
*/
#include "z_oceff_spot.h"
+
+#include "gfx.h"
+#include "gfx_setupdl.h"
+#include "ichain.h"
+#include "regs.h"
+#include "sys_matrix.h"
#include "terminal.h"
+#include "z_lib.h"
+#include "z64light.h"
+#include "z64ocarina.h"
+#include "z64play.h"
+#include "z64player.h"
+#include "z64save.h"
#define FLAGS (ACTOR_FLAG_UPDATE_CULLING_DISABLED | ACTOR_FLAG_UPDATE_DURING_OCARINA)
diff --git a/src/overlays/actors/ovl_Oceff_Spot/z_oceff_spot.h b/src/overlays/actors/ovl_Oceff_Spot/z_oceff_spot.h
index a96f1878a..222c977fc 100644
--- a/src/overlays/actors/ovl_Oceff_Spot/z_oceff_spot.h
+++ b/src/overlays/actors/ovl_Oceff_Spot/z_oceff_spot.h
@@ -2,11 +2,12 @@
#define Z_OCEFF_SPOT_H
#include "ultra64.h"
-#include "global.h"
+#include "z64actor.h"
+#include "z64light.h"
struct OceffSpot;
-typedef void (*OceffSpotActionFunc)(struct OceffSpot*, PlayState*);
+typedef void (*OceffSpotActionFunc)(struct OceffSpot*, struct PlayState*);
typedef struct OceffSpot {
/* 0x0000 */ Actor actor;
diff --git a/src/overlays/actors/ovl_Oceff_Storm/z_oceff_storm.c b/src/overlays/actors/ovl_Oceff_Storm/z_oceff_storm.c
index 18ea2231d..5e236c86f 100644
--- a/src/overlays/actors/ovl_Oceff_Storm/z_oceff_storm.c
+++ b/src/overlays/actors/ovl_Oceff_Storm/z_oceff_storm.c
@@ -11,8 +11,7 @@
#include "sys_matrix.h"
#include "z64play.h"
#include "z64player.h"
-
-#include "global.h"
+#include "z64save.h"
#define FLAGS (ACTOR_FLAG_UPDATE_CULLING_DISABLED | ACTOR_FLAG_DRAW_CULLING_DISABLED | ACTOR_FLAG_UPDATE_DURING_OCARINA)
diff --git a/src/overlays/actors/ovl_Oceff_Wipe/z_oceff_wipe.c b/src/overlays/actors/ovl_Oceff_Wipe/z_oceff_wipe.c
index f9b14bc7d..011b11206 100644
--- a/src/overlays/actors/ovl_Oceff_Wipe/z_oceff_wipe.c
+++ b/src/overlays/actors/ovl_Oceff_Wipe/z_oceff_wipe.c
@@ -5,7 +5,15 @@
*/
#include "z_oceff_wipe.h"
+
+#include "gfx.h"
+#include "gfx_setupdl.h"
+#include "sys_matrix.h"
#include "terminal.h"
+#include "z_lib.h"
+#include "z64play.h"
+#include "z64player.h"
+#include "z64save.h"
#define FLAGS (ACTOR_FLAG_UPDATE_CULLING_DISABLED | ACTOR_FLAG_UPDATE_DURING_OCARINA)
diff --git a/src/overlays/actors/ovl_Oceff_Wipe/z_oceff_wipe.h b/src/overlays/actors/ovl_Oceff_Wipe/z_oceff_wipe.h
index 9e5131737..65a18468a 100644
--- a/src/overlays/actors/ovl_Oceff_Wipe/z_oceff_wipe.h
+++ b/src/overlays/actors/ovl_Oceff_Wipe/z_oceff_wipe.h
@@ -2,7 +2,7 @@
#define Z_OCEFF_WIPE_H
#include "ultra64.h"
-#include "global.h"
+#include "z64actor.h"
typedef enum OceffWipeType {
/* 0x00 */ OCEFF_WIPE_ZL,
diff --git a/src/overlays/actors/ovl_Oceff_Wipe2/z_oceff_wipe2.c b/src/overlays/actors/ovl_Oceff_Wipe2/z_oceff_wipe2.c
index 9e3b03a8f..5885dd0ac 100644
--- a/src/overlays/actors/ovl_Oceff_Wipe2/z_oceff_wipe2.c
+++ b/src/overlays/actors/ovl_Oceff_Wipe2/z_oceff_wipe2.c
@@ -5,7 +5,15 @@
*/
#include "z_oceff_wipe2.h"
+
+#include "gfx.h"
+#include "gfx_setupdl.h"
+#include "sys_matrix.h"
#include "terminal.h"
+#include "z_lib.h"
+#include "z64play.h"
+#include "z64player.h"
+#include "z64save.h"
#define FLAGS (ACTOR_FLAG_UPDATE_CULLING_DISABLED | ACTOR_FLAG_UPDATE_DURING_OCARINA)
diff --git a/src/overlays/actors/ovl_Oceff_Wipe2/z_oceff_wipe2.h b/src/overlays/actors/ovl_Oceff_Wipe2/z_oceff_wipe2.h
index c7f9c7b87..6276bb33c 100644
--- a/src/overlays/actors/ovl_Oceff_Wipe2/z_oceff_wipe2.h
+++ b/src/overlays/actors/ovl_Oceff_Wipe2/z_oceff_wipe2.h
@@ -2,7 +2,7 @@
#define Z_OCEFF_WIPE2_H
#include "ultra64.h"
-#include "global.h"
+#include "z64actor.h"
struct OceffWipe2;
diff --git a/src/overlays/actors/ovl_Oceff_Wipe3/z_oceff_wipe3.c b/src/overlays/actors/ovl_Oceff_Wipe3/z_oceff_wipe3.c
index 757e9b116..580d2cfec 100644
--- a/src/overlays/actors/ovl_Oceff_Wipe3/z_oceff_wipe3.c
+++ b/src/overlays/actors/ovl_Oceff_Wipe3/z_oceff_wipe3.c
@@ -5,7 +5,15 @@
*/
#include "z_oceff_wipe3.h"
+
+#include "gfx.h"
+#include "gfx_setupdl.h"
+#include "sys_matrix.h"
#include "terminal.h"
+#include "z_lib.h"
+#include "z64play.h"
+#include "z64player.h"
+#include "z64save.h"
#define FLAGS (ACTOR_FLAG_UPDATE_CULLING_DISABLED | ACTOR_FLAG_UPDATE_DURING_OCARINA)
diff --git a/src/overlays/actors/ovl_Oceff_Wipe3/z_oceff_wipe3.h b/src/overlays/actors/ovl_Oceff_Wipe3/z_oceff_wipe3.h
index a5bc2bbe4..5e6abb045 100644
--- a/src/overlays/actors/ovl_Oceff_Wipe3/z_oceff_wipe3.h
+++ b/src/overlays/actors/ovl_Oceff_Wipe3/z_oceff_wipe3.h
@@ -2,7 +2,7 @@
#define Z_OCEFF_WIPE3_H
#include "ultra64.h"
-#include "global.h"
+#include "z64actor.h"
struct OceffWipe3;
diff --git a/src/overlays/actors/ovl_Oceff_Wipe4/z_oceff_wipe4.c b/src/overlays/actors/ovl_Oceff_Wipe4/z_oceff_wipe4.c
index 9ad0dbf68..7263cd16f 100644
--- a/src/overlays/actors/ovl_Oceff_Wipe4/z_oceff_wipe4.c
+++ b/src/overlays/actors/ovl_Oceff_Wipe4/z_oceff_wipe4.c
@@ -5,7 +5,13 @@
*/
#include "z_oceff_wipe4.h"
+
+#include "gfx.h"
+#include "gfx_setupdl.h"
+#include "sys_matrix.h"
#include "terminal.h"
+#include "z_lib.h"
+#include "z64play.h"
#define FLAGS (ACTOR_FLAG_UPDATE_CULLING_DISABLED | ACTOR_FLAG_UPDATE_DURING_OCARINA)
diff --git a/src/overlays/actors/ovl_Oceff_Wipe4/z_oceff_wipe4.h b/src/overlays/actors/ovl_Oceff_Wipe4/z_oceff_wipe4.h
index 3986c1fce..bd82ddc7c 100644
--- a/src/overlays/actors/ovl_Oceff_Wipe4/z_oceff_wipe4.h
+++ b/src/overlays/actors/ovl_Oceff_Wipe4/z_oceff_wipe4.h
@@ -2,7 +2,7 @@
#define Z_OCEFF_WIPE4_H
#include "ultra64.h"
-#include "global.h"
+#include "z64actor.h"
typedef enum OceffWipe4Type {
/* 0x00 */ OCEFF_WIPE4_SCARECROWS,
diff --git a/src/overlays/actors/ovl_Shot_Sun/z_shot_sun.c b/src/overlays/actors/ovl_Shot_Sun/z_shot_sun.c
index 20d506b59..de537e434 100644
--- a/src/overlays/actors/ovl_Shot_Sun/z_shot_sun.c
+++ b/src/overlays/actors/ovl_Shot_Sun/z_shot_sun.c
@@ -19,6 +19,7 @@
#include "z64ocarina.h"
#include "z64play.h"
#include "z64player.h"
+#include "z64save.h"
#include "assets/scenes/overworld/spot06/spot06_scene.h"
diff --git a/src/overlays/actors/ovl_player_actor/z_player.c b/src/overlays/actors/ovl_player_actor/z_player.c
index fbb688b17..0d9141fb7 100644
--- a/src/overlays/actors/ovl_player_actor/z_player.c
+++ b/src/overlays/actors/ovl_player_actor/z_player.c
@@ -40,13 +40,14 @@
#include "z_lib.h"
#include "zelda_arena.h"
#include "z64audio.h"
+#include "z64debug.h"
#include "z64effect.h"
+#include "z64lifemeter.h"
#include "z64ocarina.h"
#include "z64play.h"
+#include "z64save.h"
#include "z64skin_matrix.h"
-#include "global.h"
-
#include "assets/objects/gameplay_keep/gameplay_keep.h"
#include "assets/objects/object_link_child/object_link_child.h"
@@ -361,21 +362,21 @@ void Player_Action_CsAction(Player* this, PlayState* play);
// .bss part 1
-#pragma increment_block_number "gc-eu:128 gc-eu-mq:128 gc-jp:128 gc-jp-ce:128 gc-jp-mq:128 gc-us:128 gc-us-mq:128" \
- "ique-cn:128 ntsc-1.0:64 ntsc-1.1:64 ntsc-1.2:64 pal-1.0:64 pal-1.1:64"
+#pragma increment_block_number "gc-eu:0 gc-eu-mq:0 gc-jp:0 gc-jp-ce:0 gc-jp-mq:0 gc-us:0 gc-us-mq:0 ique-cn:0" \
+ "ntsc-1.0:0 ntsc-1.1:0 ntsc-1.2:0 pal-1.0:0 pal-1.1:0"
static s32 D_80858AA0;
// TODO: There's probably a way to match BSS ordering with less padding by spreading the variables out and moving
// data around. It would be easier if we had more options for controlling BSS ordering in debug.
-#pragma increment_block_number "gc-eu:192 gc-eu-mq:192 gc-jp:128 gc-jp-ce:128 gc-jp-mq:128 gc-us:128 gc-us-mq:128" \
- "ique-cn:128 ntsc-1.0:192 ntsc-1.1:192 ntsc-1.2:192 pal-1.0:192 pal-1.1:192"
+#pragma increment_block_number "gc-eu:224 gc-eu-mq:224 gc-jp:192 gc-jp-ce:192 gc-jp-mq:192 gc-us:192 gc-us-mq:192" \
+ "ique-cn:192 ntsc-1.0:192 ntsc-1.1:192 ntsc-1.2:192 pal-1.0:192 pal-1.1:192"
static s32 sSavedCurrentMask;
static Vec3f sInteractWallCheckResult;
static Input* sControlInput;
-#pragma increment_block_number "gc-eu:160 gc-eu-mq:160 gc-jp:192 gc-jp-ce:192 gc-jp-mq:192 gc-us:192 gc-us-mq:192" \
+#pragma increment_block_number "gc-eu:192 gc-eu-mq:192 gc-jp:192 gc-jp-ce:192 gc-jp-mq:192 gc-us:192 gc-us-mq:192" \
"ique-cn:192 ntsc-1.0:128 ntsc-1.1:128 ntsc-1.2:128 pal-1.0:128 pal-1.1:128"
// .data
diff --git a/src/overlays/effects/ovl_Effect_Ss_Dead_Dd/z_eff_ss_dead_dd.c b/src/overlays/effects/ovl_Effect_Ss_Dead_Dd/z_eff_ss_dead_dd.c
index c6e2803bb..0b3ef078e 100644
--- a/src/overlays/effects/ovl_Effect_Ss_Dead_Dd/z_eff_ss_dead_dd.c
+++ b/src/overlays/effects/ovl_Effect_Ss_Dead_Dd/z_eff_ss_dead_dd.c
@@ -6,14 +6,13 @@
#include "z_eff_ss_dead_dd.h"
+#include "libc64/qrand.h"
#include "gfx.h"
#include "gfx_setupdl.h"
#include "z64effect.h"
#include "z64play.h"
#include "z64skin_matrix.h"
-#include "global.h"
-
#include "assets/objects/gameplay_keep/gameplay_keep.h"
#define rScale regs[0]
diff --git a/src/overlays/effects/ovl_Effect_Ss_Fhg_Flash/z_eff_ss_fhg_flash.c b/src/overlays/effects/ovl_Effect_Ss_Fhg_Flash/z_eff_ss_fhg_flash.c
index c4ab53469..3bdadb99f 100644
--- a/src/overlays/effects/ovl_Effect_Ss_Fhg_Flash/z_eff_ss_fhg_flash.c
+++ b/src/overlays/effects/ovl_Effect_Ss_Fhg_Flash/z_eff_ss_fhg_flash.c
@@ -6,6 +6,18 @@
#include "z_eff_ss_fhg_flash.h"
#include "overlays/actors/ovl_Boss_Ganondrof/z_boss_ganondrof.h"
+
+#include "libc64/qrand.h"
+#include "gfx.h"
+#include "gfx_setupdl.h"
+#include "rand.h"
+#include "segmented_address.h"
+#include "sys_matrix.h"
+#include "z64effect.h"
+#include "z64play.h"
+#include "z64player.h"
+#include "z64skin.h"
+
#include "assets/objects/object_fhg/object_fhg.h"
#define rAlpha regs[0]
diff --git a/src/overlays/effects/ovl_Effect_Ss_HitMark/z_eff_ss_hitmark.c b/src/overlays/effects/ovl_Effect_Ss_HitMark/z_eff_ss_hitmark.c
index 0dbb0ca19..ca195cfa8 100644
--- a/src/overlays/effects/ovl_Effect_Ss_HitMark/z_eff_ss_hitmark.c
+++ b/src/overlays/effects/ovl_Effect_Ss_HitMark/z_eff_ss_hitmark.c
@@ -5,7 +5,15 @@
*/
#include "z_eff_ss_hitmark.h"
-#include "global.h"
+
+#include "gfx.h"
+#include "gfx_setupdl.h"
+#include "segmented_address.h"
+#include "sys_matrix.h"
+#include "z64effect.h"
+#include "z64play.h"
+#include "z64skin_matrix.h"
+
#include "assets/objects/gameplay_keep/gameplay_keep.h"
#define rTexIndex regs[0]
diff --git a/src/overlays/effects/ovl_Effect_Ss_Stick/z_eff_ss_stick.c b/src/overlays/effects/ovl_Effect_Ss_Stick/z_eff_ss_stick.c
index f78855692..520f8af02 100644
--- a/src/overlays/effects/ovl_Effect_Ss_Stick/z_eff_ss_stick.c
+++ b/src/overlays/effects/ovl_Effect_Ss_Stick/z_eff_ss_stick.c
@@ -13,6 +13,7 @@
#include "z64effect.h"
#include "z64play.h"
#include "z64player.h"
+#include "z64save.h"
#include "assets/objects/object_link_boy/object_link_boy.h"
#include "assets/objects/object_link_child/object_link_child.h"
diff --git a/src/overlays/gamestates/ovl_file_choose/file_select.h b/src/overlays/gamestates/ovl_file_choose/file_select.h
index 2946a3935..ae41c4dce 100644
--- a/src/overlays/gamestates/ovl_file_choose/file_select.h
+++ b/src/overlays/gamestates/ovl_file_choose/file_select.h
@@ -155,13 +155,6 @@ typedef enum SettingIndex {
/* */ FS_SETTING_MAX
} SettingIndex;
-typedef enum AudioOption {
- /* 0 */ FS_AUDIO_STEREO,
- /* 1 */ FS_AUDIO_MONO,
- /* 2 */ FS_AUDIO_HEADSET,
- /* 3 */ FS_AUDIO_SURROUND
-} AudioOption;
-
typedef enum CharPage {
/* 0 */ FS_CHAR_PAGE_HIRA,
/* 1 */ FS_CHAR_PAGE_KATA,
diff --git a/src/overlays/gamestates/ovl_file_choose/z_file_choose.c b/src/overlays/gamestates/ovl_file_choose/z_file_choose.c
index 8b5b18436..2a561d919 100644
--- a/src/overlays/gamestates/ovl_file_choose/z_file_choose.c
+++ b/src/overlays/gamestates/ovl_file_choose/z_file_choose.c
@@ -20,6 +20,7 @@
#include "z64save.h"
#include "z64skybox.h"
#include "z64sram.h"
+#include "z64ss_sram.h"
#include "z64view.h"
#include "global.h"
@@ -744,12 +745,12 @@ void FileSelect_PulsateCursor(GameState* thisx) {
SsSram_ReadWrite(OS_K1_TO_PHYSICAL(0xA8000000), sramCtx->readBuff, 3, OS_WRITE);
PRINTF("1:read_buff[]=%x, %x, %x, %x\n", sramCtx->readBuff[SRAM_HEADER_SOUND],
- sramCtx->readBuff[SRAM_HEADER_ZTARGET], sramCtx->readBuff[SRAM_HEADER_LANGUAGE],
+ sramCtx->readBuff[SRAM_HEADER_Z_TARGET], sramCtx->readBuff[SRAM_HEADER_LANGUAGE],
sramCtx->readBuff[SRAM_HEADER_MAGIC]);
SsSram_ReadWrite(OS_K1_TO_PHYSICAL(0xA8000000), sramCtx->readBuff, SRAM_SIZE, OS_READ);
PRINTF("read_buff[]=%x, %x, %x, %x\n", sramCtx->readBuff[SRAM_HEADER_SOUND],
- sramCtx->readBuff[SRAM_HEADER_ZTARGET], sramCtx->readBuff[SRAM_HEADER_LANGUAGE],
+ sramCtx->readBuff[SRAM_HEADER_Z_TARGET], sramCtx->readBuff[SRAM_HEADER_LANGUAGE],
sramCtx->readBuff[SRAM_HEADER_MAGIC]);
} else if (CHECK_BTN_ALL(debugInput->press.button, BTN_DUP)) {
sramCtx->readBuff[SRAM_HEADER_LANGUAGE] = gSaveContext.language = LANGUAGE_GER;
@@ -757,11 +758,11 @@ void FileSelect_PulsateCursor(GameState* thisx) {
SsSram_ReadWrite(OS_K1_TO_PHYSICAL(0xA8000000), sramCtx->readBuff, 3, OS_WRITE);
PRINTF("1:read_buff[]=%x, %x, %x, %x\n", sramCtx->readBuff[SRAM_HEADER_SOUND],
- sramCtx->readBuff[SRAM_HEADER_ZTARGET], sramCtx->readBuff[SRAM_HEADER_LANGUAGE],
+ sramCtx->readBuff[SRAM_HEADER_Z_TARGET], sramCtx->readBuff[SRAM_HEADER_LANGUAGE],
sramCtx->readBuff[SRAM_HEADER_MAGIC]);
SsSram_ReadWrite(OS_K1_TO_PHYSICAL(0xA8000000), sramCtx->readBuff, SRAM_SIZE, OS_READ);
PRINTF("read_buff[]=%x, %x, %x, %x\n", sramCtx->readBuff[SRAM_HEADER_SOUND],
- sramCtx->readBuff[SRAM_HEADER_ZTARGET], sramCtx->readBuff[SRAM_HEADER_LANGUAGE],
+ sramCtx->readBuff[SRAM_HEADER_Z_TARGET], sramCtx->readBuff[SRAM_HEADER_LANGUAGE],
sramCtx->readBuff[SRAM_HEADER_MAGIC]);
} else if (CHECK_BTN_ALL(debugInput->press.button, BTN_DRIGHT)) {
sramCtx->readBuff[SRAM_HEADER_LANGUAGE] = gSaveContext.language = LANGUAGE_FRA;
@@ -769,12 +770,12 @@ void FileSelect_PulsateCursor(GameState* thisx) {
SsSram_ReadWrite(OS_K1_TO_PHYSICAL(0xA8000000), sramCtx->readBuff, 3, OS_WRITE);
PRINTF("1:read_buff[]=%x, %x, %x, %x\n", sramCtx->readBuff[SRAM_HEADER_SOUND],
- sramCtx->readBuff[SRAM_HEADER_ZTARGET], sramCtx->readBuff[SRAM_HEADER_LANGUAGE],
+ sramCtx->readBuff[SRAM_HEADER_Z_TARGET], sramCtx->readBuff[SRAM_HEADER_LANGUAGE],
sramCtx->readBuff[SRAM_HEADER_MAGIC]);
SsSram_ReadWrite(OS_K1_TO_PHYSICAL(0xA8000000), sramCtx->readBuff, SRAM_SIZE, OS_READ);
PRINTF("read_buff[]=%x, %x, %x, %x\n", sramCtx->readBuff[SRAM_HEADER_SOUND],
- sramCtx->readBuff[SRAM_HEADER_ZTARGET], sramCtx->readBuff[SRAM_HEADER_LANGUAGE],
+ sramCtx->readBuff[SRAM_HEADER_Z_TARGET], sramCtx->readBuff[SRAM_HEADER_LANGUAGE],
sramCtx->readBuff[SRAM_HEADER_MAGIC]);
}
#endif
diff --git a/src/overlays/gamestates/ovl_file_choose/z_file_nameset.c b/src/overlays/gamestates/ovl_file_choose/z_file_nameset.c
index c22f822cd..b1b22c074 100644
--- a/src/overlays/gamestates/ovl_file_choose/z_file_nameset.c
+++ b/src/overlays/gamestates/ovl_file_choose/z_file_nameset.c
@@ -1353,7 +1353,7 @@ void FileSelect_UpdateOptionsMenu(GameState* thisx) {
Audio_PlaySfxGeneral(NA_SE_SY_FSEL_DECIDE_L, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale,
&gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb);
this->configMode = CM_OPTIONS_TO_MAIN;
- sramCtx->readBuff[0] = gSaveContext.audioSetting;
+ sramCtx->readBuff[0] = gSaveContext.soundSetting;
sramCtx->readBuff[1] = gSaveContext.zTargetSetting;
#if OOT_PAL_N64
sramCtx->readBuff[2] = gSaveContext.language;
@@ -1363,11 +1363,11 @@ void FileSelect_UpdateOptionsMenu(GameState* thisx) {
PRINTF_COLOR_YELLOW();
PRINTF("sram->read_buff[2] = J_N = %x\n", sramCtx->readBuff[2]);
PRINTF("sram->read_buff[2] = J_N = %x\n", &sramCtx->readBuff[2]);
- PRINTF("Na_SetSoundOutputMode = %d\n", gSaveContext.audioSetting);
- PRINTF("Na_SetSoundOutputMode = %d\n", gSaveContext.audioSetting);
- PRINTF("Na_SetSoundOutputMode = %d\n", gSaveContext.audioSetting);
+ PRINTF("Na_SetSoundOutputMode = %d\n", gSaveContext.soundSetting);
+ PRINTF("Na_SetSoundOutputMode = %d\n", gSaveContext.soundSetting);
+ PRINTF("Na_SetSoundOutputMode = %d\n", gSaveContext.soundSetting);
PRINTF_RST();
- func_800F6700(gSaveContext.audioSetting);
+ Audio_SetSoundMode(gSaveContext.soundSetting);
PRINTF("終了\n");
return;
}
@@ -1377,11 +1377,11 @@ void FileSelect_UpdateOptionsMenu(GameState* thisx) {
&gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb);
if (sSelectedSetting == FS_SETTING_AUDIO) {
- gSaveContext.audioSetting--;
+ gSaveContext.soundSetting--;
// because audio setting is unsigned, can't check for < 0
- if (gSaveContext.audioSetting > 0xF0) {
- gSaveContext.audioSetting = FS_AUDIO_SURROUND;
+ if (gSaveContext.soundSetting > 0xF0) {
+ gSaveContext.soundSetting = SOUND_SETTING_SURROUND;
}
} else {
#if !OOT_PAL_N64
@@ -1402,10 +1402,10 @@ void FileSelect_UpdateOptionsMenu(GameState* thisx) {
&gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb);
if (sSelectedSetting == FS_SETTING_AUDIO) {
- gSaveContext.audioSetting++;
+ gSaveContext.soundSetting++;
- if (gSaveContext.audioSetting > FS_AUDIO_SURROUND) {
- gSaveContext.audioSetting = FS_AUDIO_STEREO;
+ if (gSaveContext.soundSetting > SOUND_SETTING_SURROUND) {
+ gSaveContext.soundSetting = SOUND_SETTING_STEREO;
}
} else {
#if !OOT_PAL_N64
@@ -1719,7 +1719,7 @@ void FileSelect_DrawOptionsImpl(GameState* thisx) {
for (i = 0, vtx = 0; i < 4; i++, vtx += 4) {
gDPPipeSync(POLY_OPA_DISP++);
- if (i == gSaveContext.audioSetting) {
+ if (i == gSaveContext.soundSetting) {
if (sSelectedSetting == FS_SETTING_AUDIO) {
gDPSetPrimColor(POLY_OPA_DISP++, 0, 0, cursorPrimRed, cursorPrimGreen, cursorPrimBlue,
this->titleAlpha[0]);
diff --git a/src/overlays/gamestates/ovl_opening/z_opening.c b/src/overlays/gamestates/ovl_opening/z_opening.c
index 4d9495121..171f3d728 100644
--- a/src/overlays/gamestates/ovl_opening/z_opening.c
+++ b/src/overlays/gamestates/ovl_opening/z_opening.c
@@ -5,6 +5,8 @@
*/
#include "global.h"
+#include "z64save.h"
+#include "z64sram.h"
void TitleSetup_SetupTitleScreen(TitleSetupState* this) {
gSaveContext.gameMode = GAMEMODE_TITLE_SCREEN;
diff --git a/src/overlays/gamestates/ovl_select/z_select.c b/src/overlays/gamestates/ovl_select/z_select.c
index ddf5b3368..fb92a4d96 100644
--- a/src/overlays/gamestates/ovl_select/z_select.c
+++ b/src/overlays/gamestates/ovl_select/z_select.c
@@ -4,8 +4,6 @@
* Description: Debug Scene Select Menu
*/
#include "ultra64.h"
-#include "global.h"
-#include "terminal.h"
#include "alloca.h"
#include "z_select.h"
diff --git a/src/overlays/gamestates/ovl_select/z_select.h b/src/overlays/gamestates/ovl_select/z_select.h
index 1a59aef1e..ffe12d43b 100644
--- a/src/overlays/gamestates/ovl_select/z_select.h
+++ b/src/overlays/gamestates/ovl_select/z_select.h
@@ -2,6 +2,16 @@
#define Z_SELECT_H
#include "config.h"
+#if PLATFORM_N64
+#include "n64dd.h"
+#endif
+#include "seqcmd.h"
+#include "sequence.h"
+#include "terminal.h"
+#include "z64save.h"
+#include "z64sram.h"
+
+#include "global.h"
void MapSelect_Init(GameState* thisx);
void MapSelect_Main(GameState* thisx);
diff --git a/src/overlays/gamestates/ovl_title/z_title.c b/src/overlays/gamestates/ovl_title/z_title.c
index 2ce0c8d08..c5a1b84ca 100644
--- a/src/overlays/gamestates/ovl_title/z_title.c
+++ b/src/overlays/gamestates/ovl_title/z_title.c
@@ -13,6 +13,7 @@
#include "cic6105.h"
#include "n64dd.h"
#endif
+#include "z64save.h"
#include "assets/textures/nintendo_rogo_static/nintendo_rogo_static.h"
diff --git a/src/overlays/misc/ovl_kaleido_scope/z_kaleido_collect.c b/src/overlays/misc/ovl_kaleido_scope/z_kaleido_collect.c
index c32cf6599..f4fbabc14 100644
--- a/src/overlays/misc/ovl_kaleido_scope/z_kaleido_collect.c
+++ b/src/overlays/misc/ovl_kaleido_scope/z_kaleido_collect.c
@@ -1,4 +1,7 @@
#include "z_kaleido_scope.h"
+
+#include "z64save.h"
+
#include "assets/textures/parameter_static/parameter_static.h"
#include "assets/textures/icon_item_static/icon_item_static.h"
diff --git a/src/overlays/misc/ovl_kaleido_scope/z_kaleido_debug.c b/src/overlays/misc/ovl_kaleido_scope/z_kaleido_debug.c
index 555d518e3..6fa0ebc17 100644
--- a/src/overlays/misc/ovl_kaleido_scope/z_kaleido_debug.c
+++ b/src/overlays/misc/ovl_kaleido_scope/z_kaleido_debug.c
@@ -1,4 +1,7 @@
#include "z_kaleido_scope.h"
+
+#include "z64save.h"
+
#include "assets/textures/parameter_static/parameter_static.h"
// Positions of each input section in the editor
diff --git a/src/overlays/misc/ovl_kaleido_scope/z_kaleido_equipment.c b/src/overlays/misc/ovl_kaleido_scope/z_kaleido_equipment.c
index e633b06e2..0ac596023 100644
--- a/src/overlays/misc/ovl_kaleido_scope/z_kaleido_equipment.c
+++ b/src/overlays/misc/ovl_kaleido_scope/z_kaleido_equipment.c
@@ -1,4 +1,7 @@
#include "z_kaleido_scope.h"
+
+#include "z64save.h"
+
#include "assets/textures/icon_item_static/icon_item_static.h"
#include "assets/textures/parameter_static/parameter_static.h"
diff --git a/src/overlays/misc/ovl_kaleido_scope/z_kaleido_item.c b/src/overlays/misc/ovl_kaleido_scope/z_kaleido_item.c
index a49feffb7..35a21a31e 100644
--- a/src/overlays/misc/ovl_kaleido_scope/z_kaleido_item.c
+++ b/src/overlays/misc/ovl_kaleido_scope/z_kaleido_item.c
@@ -1,4 +1,7 @@
#include "z_kaleido_scope.h"
+
+#include "z64save.h"
+
#include "assets/textures/parameter_static/parameter_static.h"
u8 gAmmoItems[] = {
diff --git a/src/overlays/misc/ovl_kaleido_scope/z_kaleido_map.c b/src/overlays/misc/ovl_kaleido_scope/z_kaleido_map.c
index 232e7ae3f..ccd2bcee9 100644
--- a/src/overlays/misc/ovl_kaleido_scope/z_kaleido_map.c
+++ b/src/overlays/misc/ovl_kaleido_scope/z_kaleido_map.c
@@ -1,5 +1,9 @@
#include "z_kaleido_scope.h"
+#include "sys_ucode.h"
#include "versions.h"
+#include "z64play.h"
+#include "z64save.h"
+
#include "assets/textures/icon_item_24_static/icon_item_24_static.h"
#if OOT_NTSC
#include "assets/textures/icon_item_jpn_static/icon_item_jpn_static.h"
diff --git a/src/overlays/misc/ovl_kaleido_scope/z_kaleido_scope.c b/src/overlays/misc/ovl_kaleido_scope/z_kaleido_scope.c
index 65145e9f9..4675406c2 100644
--- a/src/overlays/misc/ovl_kaleido_scope/z_kaleido_scope.c
+++ b/src/overlays/misc/ovl_kaleido_scope/z_kaleido_scope.c
@@ -1,7 +1,12 @@
+#include "z_kaleido_scope.h"
#if PLATFORM_N64
#include "n64dd.h"
#endif
-#include "z_kaleido_scope.h"
+#include "seqcmd.h"
+#include "terminal.h"
+#include "versions.h"
+#include "z64save.h"
+
#include "assets/textures/icon_item_static/icon_item_static.h"
#include "assets/textures/icon_item_24_static/icon_item_24_static.h"
#if OOT_NTSC
@@ -13,8 +18,6 @@
#include "assets/textures/icon_item_fra_static/icon_item_fra_static.h"
#endif
#include "assets/textures/icon_item_gameover_static/icon_item_gameover_static.h"
-#include "terminal.h"
-#include "versions.h"
#pragma increment_block_number "gc-eu:128 gc-eu-mq:128 ntsc-1.0:128 ntsc-1.1:128 ntsc-1.2:128 pal-1.0:128 pal-1.1:128"
diff --git a/src/overlays/misc/ovl_kaleido_scope/z_kaleido_scope.h b/src/overlays/misc/ovl_kaleido_scope/z_kaleido_scope.h
index a574196ba..80ae404dc 100644
--- a/src/overlays/misc/ovl_kaleido_scope/z_kaleido_scope.h
+++ b/src/overlays/misc/ovl_kaleido_scope/z_kaleido_scope.h
@@ -3,6 +3,7 @@
#include "ultra64.h"
#include "global.h"
+#include "z64inventory.h"
extern u8 gAmmoItems[];
extern s16 gVtxPageMapWorldQuadsWidth[];
diff --git a/tools/.gitignore b/tools/.gitignore
index dfde978af..8df690318 100644
--- a/tools/.gitignore
+++ b/tools/.gitignore
@@ -1,5 +1,6 @@
# Output files
*.exe
+bin2c
elf2rom
makeromfs
mkdmadata
diff --git a/tools/Makefile b/tools/Makefile
index 28c7b7c2d..7db062979 100644
--- a/tools/Makefile
+++ b/tools/Makefile
@@ -1,7 +1,7 @@
MAKEFLAGS += --no-builtin-rules --no-print-directory
-CFLAGS := -Wall -Wextra -pedantic -std=c99 -g -O2
-PROGRAMS := elf2rom makeromfs mkdmadata mkldscript preprocess_pragmas reloc_prereq
+CFLAGS := -Wall -Wextra -pedantic -std=gnu99 -g -O2
+PROGRAMS := bin2c elf2rom makeromfs mkdmadata mkldscript preprocess_pragmas reloc_prereq vtxdis
UNAME_S := $(shell uname -s)
ifeq ($(UNAME_S),Linux)
@@ -56,6 +56,8 @@ endif
$(V)$(MAKE) -C audio
$(call print_no_args,Building com-plugin...)
$(V)$(MAKE) -C com-plugin
+ $(call print_no_args,Building assets tools...)
+ $(V)$(MAKE) -C assets
clean:
$(V)$(RM) $(PROGRAMS) $(addsuffix .exe,$(PROGRAMS))
@@ -70,13 +72,16 @@ endif
$(V)rm Flips/flips
$(V)$(MAKE) -C audio clean
$(V)$(MAKE) -C com-plugin clean
+ $(V)$(MAKE) -C assets clean
distclean: clean
$(V)$(MAKE) -C audio distclean
+ $(V)$(MAKE) -C assets distclean
.PHONY: all clean distclean
elf2rom_SOURCES := elf2rom.c elf32.c n64chksum.c util.c
+bin2c_SOURCES := bin2c.c
makeromfs_SOURCES := makeromfs.c n64chksum.c util.c
mkdmadata_SOURCES := mkdmadata.c spec.c util.c
mkldscript_SOURCES := mkldscript.c spec.c util.c
diff --git a/tools/assets/Makefile b/tools/assets/Makefile
new file mode 100644
index 000000000..d445d3879
--- /dev/null
+++ b/tools/assets/Makefile
@@ -0,0 +1,10 @@
+all:
+ $(MAKE) -C n64texconv
+
+clean:
+ $(MAKE) -C n64texconv clean
+
+distclean: clean
+ $(MAKE) -C n64texconv distclean
+
+.PHONY: all clean distclean
diff --git a/tools/assets/n64texconv/.clang-format b/tools/assets/n64texconv/.clang-format
new file mode 100644
index 000000000..20dda610d
--- /dev/null
+++ b/tools/assets/n64texconv/.clang-format
@@ -0,0 +1,29 @@
+IndentWidth: 4
+Language: Cpp
+UseTab: Never
+ColumnLimit: 120
+PointerAlignment: Right
+BreakBeforeBraces: Linux
+AlwaysBreakAfterReturnType: TopLevel
+AlignArrayOfStructures: Left
+SpaceAfterCStyleCast: false
+SpaceBeforeParens: ControlStatementsExceptControlMacros
+Cpp11BracedListStyle: false
+IndentCaseLabels: true
+BinPackArguments: true
+BinPackParameters: true
+AlignAfterOpenBracket: Align
+AlignOperands: true
+BreakBeforeTernaryOperators: true
+BreakBeforeBinaryOperators: None
+AllowShortBlocksOnASingleLine: true
+AllowShortIfStatementsOnASingleLine: false
+AllowShortLoopsOnASingleLine: false
+AllowShortCaseLabelsOnASingleLine: false
+AllowShortFunctionsOnASingleLine: false
+AllowShortEnumsOnASingleLine: false
+AlignEscapedNewlines: Left
+AlignTrailingComments: true
+SortIncludes: false
+AlignConsecutiveMacros: Consecutive
+ForEachMacros: ['LL_FOREACH']
diff --git a/tools/assets/n64texconv/.gitignore b/tools/assets/n64texconv/.gitignore
new file mode 100644
index 000000000..084dd7fab
--- /dev/null
+++ b/tools/assets/n64texconv/.gitignore
@@ -0,0 +1,10 @@
+build/
+
+libn64texconv.a
+libn64texconv.dll
+libn64texconv.so
+n64texconv
+
+# Tests
+*.png
+*.bin
diff --git a/tools/assets/n64texconv/LICENSE b/tools/assets/n64texconv/LICENSE
new file mode 100644
index 000000000..77c1ae07c
--- /dev/null
+++ b/tools/assets/n64texconv/LICENSE
@@ -0,0 +1,627 @@
+
+N64 texture converter (n64texconv).
+
+The library is under the MIT license (see src/LICENSE), but the app
+links statically with libimagequant which is under the GPL.
+
+Copyright (C) 2025 ZeldaRET
+
+ GNU GENERAL PUBLIC LICENSE
+ Version 3, 29 June 2007
+
+ Copyright (C) 2007 Free Software Foundation, Inc.
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The GNU General Public License is a free, copyleft license for
+software and other kinds of works.
+
+ The licenses for most software and other practical works are designed
+to take away your freedom to share and change the works. By contrast,
+the GNU General Public License is intended to guarantee your freedom to
+share and change all versions of a program--to make sure it remains free
+software for all its users. We, the Free Software Foundation, use the
+GNU General Public License for most of our software; it applies also to
+any other work released this way by its authors. You can apply it to
+your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+them if you wish), that you receive source code or can get it if you
+want it, that you can change the software or use pieces of it in new
+free programs, and that you know you can do these things.
+
+ To protect your rights, we need to prevent others from denying you
+these rights or asking you to surrender the rights. Therefore, you have
+certain responsibilities if you distribute copies of the software, or if
+you modify it: responsibilities to respect the freedom of others.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must pass on to the recipients the same
+freedoms that you received. You must make sure that they, too, receive
+or can get the source code. And you must show them these terms so they
+know their rights.
+
+ Developers that use the GNU GPL protect your rights with two steps:
+(1) assert copyright on the software, and (2) offer you this License
+giving you legal permission to copy, distribute and/or modify it.
+
+ For the developers' and authors' protection, the GPL clearly explains
+that there is no warranty for this free software. For both users' and
+authors' sake, the GPL requires that modified versions be marked as
+changed, so that their problems will not be attributed erroneously to
+authors of previous versions.
+
+ Some devices are designed to deny users access to install or run
+modified versions of the software inside them, although the manufacturer
+can do so. This is fundamentally incompatible with the aim of
+protecting users' freedom to change the software. The systematic
+pattern of such abuse occurs in the area of products for individuals to
+use, which is precisely where it is most unacceptable. Therefore, we
+have designed this version of the GPL to prohibit the practice for those
+products. If such problems arise substantially in other domains, we
+stand ready to extend this provision to those domains in future versions
+of the GPL, as needed to protect the freedom of users.
+
+ Finally, every program is threatened constantly by software patents.
+States should not allow patents to restrict development and use of
+software on general-purpose computers, but in those that do, we wish to
+avoid the special danger that patents applied to a free program could
+make it effectively proprietary. To prevent this, the GPL assures that
+patents cannot be used to render the program non-free.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ TERMS AND CONDITIONS
+
+ 0. Definitions.
+
+ "This License" refers to version 3 of the GNU General Public License.
+
+ "Copyright" also means copyright-like laws that apply to other kinds of
+works, such as semiconductor masks.
+
+ "The Program" refers to any copyrightable work licensed under this
+License. Each licensee is addressed as "you". "Licensees" and
+"recipients" may be individuals or organizations.
+
+ To "modify" a work means to copy from or adapt all or part of the work
+in a fashion requiring copyright permission, other than the making of an
+exact copy. The resulting work is called a "modified version" of the
+earlier work or a work "based on" the earlier work.
+
+ A "covered work" means either the unmodified Program or a work based
+on the Program.
+
+ To "propagate" a work means to do anything with it that, without
+permission, would make you directly or secondarily liable for
+infringement under applicable copyright law, except executing it on a
+computer or modifying a private copy. Propagation includes copying,
+distribution (with or without modification), making available to the
+public, and in some countries other activities as well.
+
+ To "convey" a work means any kind of propagation that enables other
+parties to make or receive copies. Mere interaction with a user through
+a computer network, with no transfer of a copy, is not conveying.
+
+ An interactive user interface displays "Appropriate Legal Notices"
+to the extent that it includes a convenient and prominently visible
+feature that (1) displays an appropriate copyright notice, and (2)
+tells the user that there is no warranty for the work (except to the
+extent that warranties are provided), that licensees may convey the
+work under this License, and how to view a copy of this License. If
+the interface presents a list of user commands or options, such as a
+menu, a prominent item in the list meets this criterion.
+
+ 1. Source Code.
+
+ The "source code" for a work means the preferred form of the work
+for making modifications to it. "Object code" means any non-source
+form of a work.
+
+ A "Standard Interface" means an interface that either is an official
+standard defined by a recognized standards body, or, in the case of
+interfaces specified for a particular programming language, one that
+is widely used among developers working in that language.
+
+ The "System Libraries" of an executable work include anything, other
+than the work as a whole, that (a) is included in the normal form of
+packaging a Major Component, but which is not part of that Major
+Component, and (b) serves only to enable use of the work with that
+Major Component, or to implement a Standard Interface for which an
+implementation is available to the public in source code form. A
+"Major Component", in this context, means a major essential component
+(kernel, window system, and so on) of the specific operating system
+(if any) on which the executable work runs, or a compiler used to
+produce the work, or an object code interpreter used to run it.
+
+ The "Corresponding Source" for a work in object code form means all
+the source code needed to generate, install, and (for an executable
+work) run the object code and to modify the work, including scripts to
+control those activities. However, it does not include the work's
+System Libraries, or general-purpose tools or generally available free
+programs which are used unmodified in performing those activities but
+which are not part of the work. For example, Corresponding Source
+includes interface definition files associated with source files for
+the work, and the source code for shared libraries and dynamically
+linked subprograms that the work is specifically designed to require,
+such as by intimate data communication or control flow between those
+subprograms and other parts of the work.
+
+ The Corresponding Source need not include anything that users
+can regenerate automatically from other parts of the Corresponding
+Source.
+
+ The Corresponding Source for a work in source code form is that
+same work.
+
+ 2. Basic Permissions.
+
+ All rights granted under this License are granted for the term of
+copyright on the Program, and are irrevocable provided the stated
+conditions are met. This License explicitly affirms your unlimited
+permission to run the unmodified Program. The output from running a
+covered work is covered by this License only if the output, given its
+content, constitutes a covered work. This License acknowledges your
+rights of fair use or other equivalent, as provided by copyright law.
+
+ You may make, run and propagate covered works that you do not
+convey, without conditions so long as your license otherwise remains
+in force. You may convey covered works to others for the sole purpose
+of having them make modifications exclusively for you, or provide you
+with facilities for running those works, provided that you comply with
+the terms of this License in conveying all material for which you do
+not control copyright. Those thus making or running the covered works
+for you must do so exclusively on your behalf, under your direction
+and control, on terms that prohibit them from making any copies of
+your copyrighted material outside their relationship with you.
+
+ Conveying under any other circumstances is permitted solely under
+the conditions stated below. Sublicensing is not allowed; section 10
+makes it unnecessary.
+
+ 3. Protecting Users' Legal Rights From Anti-Circumvention Law.
+
+ No covered work shall be deemed part of an effective technological
+measure under any applicable law fulfilling obligations under article
+11 of the WIPO copyright treaty adopted on 20 December 1996, or
+similar laws prohibiting or restricting circumvention of such
+measures.
+
+ When you convey a covered work, you waive any legal power to forbid
+circumvention of technological measures to the extent such circumvention
+is effected by exercising rights under this License with respect to
+the covered work, and you disclaim any intention to limit operation or
+modification of the work as a means of enforcing, against the work's
+users, your or third parties' legal rights to forbid circumvention of
+technological measures.
+
+ 4. Conveying Verbatim Copies.
+
+ You may convey verbatim copies of the Program's source code as you
+receive it, in any medium, provided that you conspicuously and
+appropriately publish on each copy an appropriate copyright notice;
+keep intact all notices stating that this License and any
+non-permissive terms added in accord with section 7 apply to the code;
+keep intact all notices of the absence of any warranty; and give all
+recipients a copy of this License along with the Program.
+
+ You may charge any price or no price for each copy that you convey,
+and you may offer support or warranty protection for a fee.
+
+ 5. Conveying Modified Source Versions.
+
+ You may convey a work based on the Program, or the modifications to
+produce it from the Program, in the form of source code under the
+terms of section 4, provided that you also meet all of these conditions:
+
+ a) The work must carry prominent notices stating that you modified
+ it, and giving a relevant date.
+
+ b) The work must carry prominent notices stating that it is
+ released under this License and any conditions added under section
+ 7. This requirement modifies the requirement in section 4 to
+ "keep intact all notices".
+
+ c) You must license the entire work, as a whole, under this
+ License to anyone who comes into possession of a copy. This
+ License will therefore apply, along with any applicable section 7
+ additional terms, to the whole of the work, and all its parts,
+ regardless of how they are packaged. This License gives no
+ permission to license the work in any other way, but it does not
+ invalidate such permission if you have separately received it.
+
+ d) If the work has interactive user interfaces, each must display
+ Appropriate Legal Notices; however, if the Program has interactive
+ interfaces that do not display Appropriate Legal Notices, your
+ work need not make them do so.
+
+ A compilation of a covered work with other separate and independent
+works, which are not by their nature extensions of the covered work,
+and which are not combined with it such as to form a larger program,
+in or on a volume of a storage or distribution medium, is called an
+"aggregate" if the compilation and its resulting copyright are not
+used to limit the access or legal rights of the compilation's users
+beyond what the individual works permit. Inclusion of a covered work
+in an aggregate does not cause this License to apply to the other
+parts of the aggregate.
+
+ 6. Conveying Non-Source Forms.
+
+ You may convey a covered work in object code form under the terms
+of sections 4 and 5, provided that you also convey the
+machine-readable Corresponding Source under the terms of this License,
+in one of these ways:
+
+ a) Convey the object code in, or embodied in, a physical product
+ (including a physical distribution medium), accompanied by the
+ Corresponding Source fixed on a durable physical medium
+ customarily used for software interchange.
+
+ b) Convey the object code in, or embodied in, a physical product
+ (including a physical distribution medium), accompanied by a
+ written offer, valid for at least three years and valid for as
+ long as you offer spare parts or customer support for that product
+ model, to give anyone who possesses the object code either (1) a
+ copy of the Corresponding Source for all the software in the
+ product that is covered by this License, on a durable physical
+ medium customarily used for software interchange, for a price no
+ more than your reasonable cost of physically performing this
+ conveying of source, or (2) access to copy the
+ Corresponding Source from a network server at no charge.
+
+ c) Convey individual copies of the object code with a copy of the
+ written offer to provide the Corresponding Source. This
+ alternative is allowed only occasionally and noncommercially, and
+ only if you received the object code with such an offer, in accord
+ with subsection 6b.
+
+ d) Convey the object code by offering access from a designated
+ place (gratis or for a charge), and offer equivalent access to the
+ Corresponding Source in the same way through the same place at no
+ further charge. You need not require recipients to copy the
+ Corresponding Source along with the object code. If the place to
+ copy the object code is a network server, the Corresponding Source
+ may be on a different server (operated by you or a third party)
+ that supports equivalent copying facilities, provided you maintain
+ clear directions next to the object code saying where to find the
+ Corresponding Source. Regardless of what server hosts the
+ Corresponding Source, you remain obligated to ensure that it is
+ available for as long as needed to satisfy these requirements.
+
+ e) Convey the object code using peer-to-peer transmission, provided
+ you inform other peers where the object code and Corresponding
+ Source of the work are being offered to the general public at no
+ charge under subsection 6d.
+
+ A separable portion of the object code, whose source code is excluded
+from the Corresponding Source as a System Library, need not be
+included in conveying the object code work.
+
+ A "User Product" is either (1) a "consumer product", which means any
+tangible personal property which is normally used for personal, family,
+or household purposes, or (2) anything designed or sold for incorporation
+into a dwelling. In determining whether a product is a consumer product,
+doubtful cases shall be resolved in favor of coverage. For a particular
+product received by a particular user, "normally used" refers to a
+typical or common use of that class of product, regardless of the status
+of the particular user or of the way in which the particular user
+actually uses, or expects or is expected to use, the product. A product
+is a consumer product regardless of whether the product has substantial
+commercial, industrial or non-consumer uses, unless such uses represent
+the only significant mode of use of the product.
+
+ "Installation Information" for a User Product means any methods,
+procedures, authorization keys, or other information required to install
+and execute modified versions of a covered work in that User Product from
+a modified version of its Corresponding Source. The information must
+suffice to ensure that the continued functioning of the modified object
+code is in no case prevented or interfered with solely because
+modification has been made.
+
+ If you convey an object code work under this section in, or with, or
+specifically for use in, a User Product, and the conveying occurs as
+part of a transaction in which the right of possession and use of the
+User Product is transferred to the recipient in perpetuity or for a
+fixed term (regardless of how the transaction is characterized), the
+Corresponding Source conveyed under this section must be accompanied
+by the Installation Information. But this requirement does not apply
+if neither you nor any third party retains the ability to install
+modified object code on the User Product (for example, the work has
+been installed in ROM).
+
+ The requirement to provide Installation Information does not include a
+requirement to continue to provide support service, warranty, or updates
+for a work that has been modified or installed by the recipient, or for
+the User Product in which it has been modified or installed. Access to a
+network may be denied when the modification itself materially and
+adversely affects the operation of the network or violates the rules and
+protocols for communication across the network.
+
+ Corresponding Source conveyed, and Installation Information provided,
+in accord with this section must be in a format that is publicly
+documented (and with an implementation available to the public in
+source code form), and must require no special password or key for
+unpacking, reading or copying.
+
+ 7. Additional Terms.
+
+ "Additional permissions" are terms that supplement the terms of this
+License by making exceptions from one or more of its conditions.
+Additional permissions that are applicable to the entire Program shall
+be treated as though they were included in this License, to the extent
+that they are valid under applicable law. If additional permissions
+apply only to part of the Program, that part may be used separately
+under those permissions, but the entire Program remains governed by
+this License without regard to the additional permissions.
+
+ When you convey a copy of a covered work, you may at your option
+remove any additional permissions from that copy, or from any part of
+it. (Additional permissions may be written to require their own
+removal in certain cases when you modify the work.) You may place
+additional permissions on material, added by you to a covered work,
+for which you have or can give appropriate copyright permission.
+
+ Notwithstanding any other provision of this License, for material you
+add to a covered work, you may (if authorized by the copyright holders of
+that material) supplement the terms of this License with terms:
+
+ a) Disclaiming warranty or limiting liability differently from the
+ terms of sections 15 and 16 of this License; or
+
+ b) Requiring preservation of specified reasonable legal notices or
+ author attributions in that material or in the Appropriate Legal
+ Notices displayed by works containing it; or
+
+ c) Prohibiting misrepresentation of the origin of that material, or
+ requiring that modified versions of such material be marked in
+ reasonable ways as different from the original version; or
+
+ d) Limiting the use for publicity purposes of names of licensors or
+ authors of the material; or
+
+ e) Declining to grant rights under trademark law for use of some
+ trade names, trademarks, or service marks; or
+
+ f) Requiring indemnification of licensors and authors of that
+ material by anyone who conveys the material (or modified versions of
+ it) with contractual assumptions of liability to the recipient, for
+ any liability that these contractual assumptions directly impose on
+ those licensors and authors.
+
+ All other non-permissive additional terms are considered "further
+restrictions" within the meaning of section 10. If the Program as you
+received it, or any part of it, contains a notice stating that it is
+governed by this License along with a term that is a further
+restriction, you may remove that term. If a license document contains
+a further restriction but permits relicensing or conveying under this
+License, you may add to a covered work material governed by the terms
+of that license document, provided that the further restriction does
+not survive such relicensing or conveying.
+
+ If you add terms to a covered work in accord with this section, you
+must place, in the relevant source files, a statement of the
+additional terms that apply to those files, or a notice indicating
+where to find the applicable terms.
+
+ Additional terms, permissive or non-permissive, may be stated in the
+form of a separately written license, or stated as exceptions;
+the above requirements apply either way.
+
+ 8. Termination.
+
+ You may not propagate or modify a covered work except as expressly
+provided under this License. Any attempt otherwise to propagate or
+modify it is void, and will automatically terminate your rights under
+this License (including any patent licenses granted under the third
+paragraph of section 11).
+
+ However, if you cease all violation of this License, then your
+license from a particular copyright holder is reinstated (a)
+provisionally, unless and until the copyright holder explicitly and
+finally terminates your license, and (b) permanently, if the copyright
+holder fails to notify you of the violation by some reasonable means
+prior to 60 days after the cessation.
+
+ Moreover, your license from a particular copyright holder is
+reinstated permanently if the copyright holder notifies you of the
+violation by some reasonable means, this is the first time you have
+received notice of violation of this License (for any work) from that
+copyright holder, and you cure the violation prior to 30 days after
+your receipt of the notice.
+
+ Termination of your rights under this section does not terminate the
+licenses of parties who have received copies or rights from you under
+this License. If your rights have been terminated and not permanently
+reinstated, you do not qualify to receive new licenses for the same
+material under section 10.
+
+ 9. Acceptance Not Required for Having Copies.
+
+ You are not required to accept this License in order to receive or
+run a copy of the Program. Ancillary propagation of a covered work
+occurring solely as a consequence of using peer-to-peer transmission
+to receive a copy likewise does not require acceptance. However,
+nothing other than this License grants you permission to propagate or
+modify any covered work. These actions infringe copyright if you do
+not accept this License. Therefore, by modifying or propagating a
+covered work, you indicate your acceptance of this License to do so.
+
+ 10. Automatic Licensing of Downstream Recipients.
+
+ Each time you convey a covered work, the recipient automatically
+receives a license from the original licensors, to run, modify and
+propagate that work, subject to this License. You are not responsible
+for enforcing compliance by third parties with this License.
+
+ An "entity transaction" is a transaction transferring control of an
+organization, or substantially all assets of one, or subdividing an
+organization, or merging organizations. If propagation of a covered
+work results from an entity transaction, each party to that
+transaction who receives a copy of the work also receives whatever
+licenses to the work the party's predecessor in interest had or could
+give under the previous paragraph, plus a right to possession of the
+Corresponding Source of the work from the predecessor in interest, if
+the predecessor has it or can get it with reasonable efforts.
+
+ You may not impose any further restrictions on the exercise of the
+rights granted or affirmed under this License. For example, you may
+not impose a license fee, royalty, or other charge for exercise of
+rights granted under this License, and you may not initiate litigation
+(including a cross-claim or counterclaim in a lawsuit) alleging that
+any patent claim is infringed by making, using, selling, offering for
+sale, or importing the Program or any portion of it.
+
+ 11. Patents.
+
+ A "contributor" is a copyright holder who authorizes use under this
+License of the Program or a work on which the Program is based. The
+work thus licensed is called the contributor's "contributor version".
+
+ A contributor's "essential patent claims" are all patent claims
+owned or controlled by the contributor, whether already acquired or
+hereafter acquired, that would be infringed by some manner, permitted
+by this License, of making, using, or selling its contributor version,
+but do not include claims that would be infringed only as a
+consequence of further modification of the contributor version. For
+purposes of this definition, "control" includes the right to grant
+patent sublicenses in a manner consistent with the requirements of
+this License.
+
+ Each contributor grants you a non-exclusive, worldwide, royalty-free
+patent license under the contributor's essential patent claims, to
+make, use, sell, offer for sale, import and otherwise run, modify and
+propagate the contents of its contributor version.
+
+ In the following three paragraphs, a "patent license" is any express
+agreement or commitment, however denominated, not to enforce a patent
+(such as an express permission to practice a patent or covenant not to
+sue for patent infringement). To "grant" such a patent license to a
+party means to make such an agreement or commitment not to enforce a
+patent against the party.
+
+ If you convey a covered work, knowingly relying on a patent license,
+and the Corresponding Source of the work is not available for anyone
+to copy, free of charge and under the terms of this License, through a
+publicly available network server or other readily accessible means,
+then you must either (1) cause the Corresponding Source to be so
+available, or (2) arrange to deprive yourself of the benefit of the
+patent license for this particular work, or (3) arrange, in a manner
+consistent with the requirements of this License, to extend the patent
+license to downstream recipients. "Knowingly relying" means you have
+actual knowledge that, but for the patent license, your conveying the
+covered work in a country, or your recipient's use of the covered work
+in a country, would infringe one or more identifiable patents in that
+country that you have reason to believe are valid.
+
+ If, pursuant to or in connection with a single transaction or
+arrangement, you convey, or propagate by procuring conveyance of, a
+covered work, and grant a patent license to some of the parties
+receiving the covered work authorizing them to use, propagate, modify
+or convey a specific copy of the covered work, then the patent license
+you grant is automatically extended to all recipients of the covered
+work and works based on it.
+
+ A patent license is "discriminatory" if it does not include within
+the scope of its coverage, prohibits the exercise of, or is
+conditioned on the non-exercise of one or more of the rights that are
+specifically granted under this License. You may not convey a covered
+work if you are a party to an arrangement with a third party that is
+in the business of distributing software, under which you make payment
+to the third party based on the extent of your activity of conveying
+the work, and under which the third party grants, to any of the
+parties who would receive the covered work from you, a discriminatory
+patent license (a) in connection with copies of the covered work
+conveyed by you (or copies made from those copies), or (b) primarily
+for and in connection with specific products or compilations that
+contain the covered work, unless you entered into that arrangement,
+or that patent license was granted, prior to 28 March 2007.
+
+ Nothing in this License shall be construed as excluding or limiting
+any implied license or other defenses to infringement that may
+otherwise be available to you under applicable patent law.
+
+ 12. No Surrender of Others' Freedom.
+
+ If conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot convey a
+covered work so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you may
+not convey it at all. For example, if you agree to terms that obligate you
+to collect a royalty for further conveying from those to whom you convey
+the Program, the only way you could satisfy both those terms and this
+License would be to refrain entirely from conveying the Program.
+
+ 13. Use with the GNU Affero General Public License.
+
+ Notwithstanding any other provision of this License, you have
+permission to link or combine any covered work with a work licensed
+under version 3 of the GNU Affero General Public License into a single
+combined work, and to convey the resulting work. The terms of this
+License will continue to apply to the part which is the covered work,
+but the special requirements of the GNU Affero General Public License,
+section 13, concerning interaction through a network will apply to the
+combination as such.
+
+ 14. Revised Versions of this License.
+
+ The Free Software Foundation may publish revised and/or new versions of
+the GNU General Public License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+ Each version is given a distinguishing version number. If the
+Program specifies that a certain numbered version of the GNU General
+Public License "or any later version" applies to it, you have the
+option of following the terms and conditions either of that numbered
+version or of any later version published by the Free Software
+Foundation. If the Program does not specify a version number of the
+GNU General Public License, you may choose any version ever published
+by the Free Software Foundation.
+
+ If the Program specifies that a proxy can decide which future
+versions of the GNU General Public License can be used, that proxy's
+public statement of acceptance of a version permanently authorizes you
+to choose that version for the Program.
+
+ Later license versions may give you additional or different
+permissions. However, no additional obligations are imposed on any
+author or copyright holder as a result of your choosing to follow a
+later version.
+
+ 15. Disclaimer of Warranty.
+
+ THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
+APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
+HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
+OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
+THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
+IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
+ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+ 16. Limitation of Liability.
+
+ IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
+THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
+GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
+USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
+DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
+PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
+EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGES.
+
+ 17. Interpretation of Sections 15 and 16.
+
+ If the disclaimer of warranty and limitation of liability provided
+above cannot be given local legal effect according to their terms,
+reviewing courts shall apply local law that most closely approximates
+an absolute waiver of all civil liability in connection with the
+Program, unless a warranty or assumption of liability accompanies a
+copy of the Program in return for a fee.
diff --git a/tools/assets/n64texconv/Makefile b/tools/assets/n64texconv/Makefile
new file mode 100644
index 000000000..fbe0300d7
--- /dev/null
+++ b/tools/assets/n64texconv/Makefile
@@ -0,0 +1,77 @@
+BUILD_DIR := build
+
+# Targets
+LIB := libn64texconv.a
+SOLIB := libn64texconv.so
+APP := n64texconv
+
+INC := -Ilib/spng -Ilib/libimagequant
+
+CC := gcc
+
+WFLAGS := -Wall -Wextra -Wshadow
+
+ifeq ($(shell $(CC) --version | grep clang),)
+ ARCHFLAGS := -march=native -mtune=native
+ OMPFLAGS := -fopenmp
+else
+ ARCHFLAGS :=
+ OMPFLAGS :=
+ WFLAGS += -Wno-unknown-pragmas
+endif
+
+CFLAGS := $(WFLAGS) $(ARCHFLAGS) -MD -MMD -std=gnu11 -fPIC -ffunction-sections -fdata-sections $(INC)
+OPTFLAGS := -O3
+LDFLAGS :=
+LDLIBS := $(OMPFLAGS) -lz -lm
+AR := ar
+ARFLAGS := rcs
+
+SRC_DIRS := $(shell find src -type d -not -path src/app)
+LIB_DIRS := $(shell find lib -type d)
+APP_SRC_DIRS := $(shell find src/app -type d)
+
+C_FILES := $(foreach dir,$(SRC_DIRS) $(LIB_DIRS),$(wildcard $(dir)/*.c))
+O_FILES := $(foreach f,$(C_FILES:.c=.o),$(BUILD_DIR)/$f)
+DEP_FILES := $(foreach f,$(O_FILES:.o=.d),$f)
+
+APP_C_FILES := $(foreach dir,$(APP_SRC_DIRS),$(wildcard $(dir)/*.c))
+APP_O_FILES := $(foreach f,$(APP_C_FILES:.c=.o),$(BUILD_DIR)/$f)
+APP_DEP_FILES := $(foreach f,$(APP_O_FILES:.o=.d),$f)
+
+FMT_C_FILES := $(foreach dir,$(SRC_DIRS) $(APP_SRC_DIRS),$(wildcard $(dir)/*.c))
+FMT_H_FILES := $(foreach dir,$(SRC_DIRS) $(APP_SRC_DIRS),$(wildcard $(dir)/*.h))
+FMT_FILES := $(FMT_C_FILES) $(FMT_H_FILES)
+
+CLANG_FORMAT := clang-format-14
+FORMAT_ARGS := -i -style=file
+
+$(shell mkdir -p $(BUILD_DIR) $(foreach dir,$(SRC_DIRS) $(LIB_DIRS) $(APP_SRC_DIRS),$(BUILD_DIR)/$(dir)))
+
+$(BUILD_DIR)/lib/libimagequant/%.o: CFLAGS += $(OMPFLAGS) -Wno-sign-compare -Wno-unused-parameter -Wno-shadow
+
+.PHONY: all clean distclean format
+
+all: $(LIB) $(SOLIB) $(APP)
+
+clean:
+ $(RM) -r $(LIB) $(SOLIB) $(APP) $(BUILD_DIR)
+
+distclean: clean
+
+format:
+ $(CLANG_FORMAT) $(FORMAT_ARGS) $(FMT_FILES)
+
+$(LIB): $(O_FILES)
+ $(AR) $(ARFLAGS) $@ $^
+
+$(SOLIB): $(O_FILES)
+ $(CC) -shared $^ $(LDLIBS) -o $@
+
+$(APP): $(APP_O_FILES) $(LIB)
+ $(CC) $(LDFLAGS) $^ $(LDLIBS) -o $@
+
+$(BUILD_DIR)/%.o: %.c
+ $(CC) $(CFLAGS) $(OPTFLAGS) -c $< -o $@
+
+-include $(DEP_FILES) $(APP_DEP_FILES)
diff --git a/tools/assets/n64texconv/__init__.py b/tools/assets/n64texconv/__init__.py
new file mode 100644
index 000000000..9e4ea1c51
--- /dev/null
+++ b/tools/assets/n64texconv/__init__.py
@@ -0,0 +1,472 @@
+# SPDX-FileCopyrightText: © 2025 ZeldaRET
+# SPDX-License-Identifier: MIT
+
+import os, sys
+from ctypes import CDLL, Structure, POINTER, string_at, byref, cast
+from ctypes import c_void_p, c_char_p, c_uint8, c_uint, c_bool, c_int, c_size_t
+from typing import Optional
+
+def ctypes_buffer_to_string(buffer) -> str:
+ return buffer.value.decode('utf-8')
+
+def ctypes_pointer_to_bytes(ptr : c_void_p, size : int) -> bytes:
+ return string_at(ptr, size)
+
+def deref(ptr):
+ if ptr:
+ return ptr.contents
+ return None
+
+ln64texconv = CDLL(os.path.join(os.path.dirname(__file__), "libn64texconv.so"))
+
+class RefCounter:
+ def __init__(self) -> None:
+ self.ref_counts = {}
+
+ def add_ref(self, ptr):
+ if not isinstance(ptr, POINTER(N64Palette)):
+ ptr = cast(ptr, POINTER(N64Palette))
+ if not ptr:
+ return
+ key = int.from_bytes(ptr, byteorder=sys.byteorder, signed=False)
+ if key not in self.ref_counts:
+ self.ref_counts[key] = 1
+ else:
+ self.ref_counts[key] += 1
+
+ def num_refs(self, ptr):
+ if not isinstance(ptr, POINTER(N64Palette)):
+ ptr = cast(ptr, POINTER(N64Palette))
+ if not ptr:
+ return 0
+ key = int.from_bytes(ptr, byteorder=sys.byteorder, signed=False)
+ if key not in self.ref_counts:
+ return 0
+ return self.ref_counts[key]
+
+ def rm_ref(self, ptr, free_func):
+ if not isinstance(ptr, POINTER(N64Palette)):
+ ptr = cast(ptr, POINTER(N64Palette))
+ if not ptr:
+ return
+ key = int.from_bytes(ptr, byteorder=sys.byteorder, signed=False)
+ assert key in self.ref_counts
+ count = self.ref_counts.pop(key)
+ count -= 1
+ if count == 0:
+ free_func(ptr)
+ else:
+ self.ref_counts[key] = count
+
+# Simple reference counter for C allocations
+_object_refcount = RefCounter()
+
+#
+# Private
+#
+
+# void n64texconv_free(void *p);
+ln64texconv.n64texconv_free.argtypes = [c_void_p]
+ln64texconv.n64texconv_free.restype = None
+
+#
+# bin2c.h
+#
+
+def bin2c(data : bytes | memoryview, pad_to_size : int = 0, byte_width : int = 8) -> Optional[str]:
+ if byte_width not in (1, 2, 4, 8):
+ raise ValueError("Invalid byte width, must be 1, 2, 4 or 8")
+ buffer = (c_uint8 * len(data)).from_buffer_copy(data)
+ ptr = c_char_p(None)
+ size = c_size_t(0)
+ if ln64texconv.bin2c(byref(ptr), byref(size), buffer, len(data), pad_to_size, byte_width) != 0:
+ return None
+ s = ctypes_buffer_to_string(ptr)
+ ln64texconv.n64texconv_free(ptr)
+ return s
+
+def bin2c_file(out_path : str, data : bytes | memoryview, pad_to_size : int = 0, byte_width : int = 8) -> bool:
+ if byte_width not in (1, 2, 4, 8):
+ raise ValueError("Invalid byte width, must be 1, 2, 4 or 8")
+ buffer = (c_uint8 * len(data)).from_buffer_copy(data)
+ return ln64texconv.bin2c_file(out_path.encode("utf-8"), buffer, len(data), pad_to_size, byte_width) == 0
+
+# int bin2c(char **out, size_t *size_out, void *bin, size_t size, size_t pad_to_size, unsigned int byte_width);
+ln64texconv.bin2c.argtypes = [POINTER(c_char_p), POINTER(c_size_t), c_void_p, c_size_t, c_size_t, c_uint]
+ln64texconv.bin2c.restype = c_int
+
+# int bin2c_file(const char *out_path, void *bin, size_t size, size_t pad_to_size, unsigned int byte_width);
+ln64texconv.bin2c_file.argtypes = [c_char_p, c_void_p, c_size_t, c_size_t, c_uint]
+ln64texconv.bin2c_file.restype = c_int
+
+#
+# jfif.h
+#
+
+# struct JFIF
+class JFIF(Structure):
+ _fields_ = [
+ ("data", c_void_p),
+ ("data_size", c_size_t),
+ ]
+
+ # JFIF_BUFFER_SIZE
+ BUFFER_SIZE = 320 * 240 * 2
+
+ @staticmethod
+ def fromfile(path : str, max_size : int = BUFFER_SIZE) -> Optional["JFIF"]:
+ if not os.path.isfile(path):
+ raise ValueError(f"Cannot open \"{path}\", is not a file")
+ return deref(ln64texconv.jfif_fromfile(path.encode("utf-8"), max_size))
+
+ def to_c(self, pad_to_size : int = BUFFER_SIZE) -> Optional[str]:
+ ptr = c_char_p(None)
+ size = c_size_t(0)
+ if ln64texconv.jfif_to_c(byref(ptr), byref(size), byref(self), pad_to_size) != 0:
+ return None
+ s = ctypes_buffer_to_string(ptr)
+ ln64texconv.n64texconv_free(ptr)
+ return s
+
+ def to_c_file(self, out_path : str, pad_to_size : int = BUFFER_SIZE) -> bool:
+ return ln64texconv.jfif_to_c_file(out_path.encode("utf-8"), byref(self), pad_to_size) == 0
+
+ def __del__(self):
+ ln64texconv.jfif_free(byref(self))
+
+# struct JFIF *jfif_fromfile(const char *path, size_t max_size);
+ln64texconv.jfif_fromfile.argtypes = [c_char_p, c_size_t]
+ln64texconv.jfif_fromfile.restype = POINTER(JFIF)
+
+# void jfif_free(struct JFIF *jfif);
+ln64texconv.jfif_free.argtypes = [POINTER(JFIF)]
+ln64texconv.jfif_free.restype = None
+
+# int jfif_to_c(char **out, size_t *size_out, struct JFIF *jfif, size_t pad_to_size)
+ln64texconv.jfif_to_c.argtypes = [POINTER(c_char_p), POINTER(c_size_t), POINTER(JFIF), c_size_t]
+ln64texconv.jfif_to_c.restype = c_int
+
+# int jfif_to_c_file(const char *out_path, struct JFIF *jfif, size_t pad_to_size);
+ln64texconv.jfif_to_c_file.argtypes = [c_char_p, POINTER(JFIF), c_size_t]
+ln64texconv.jfif_to_c_file.restype = c_int
+
+#
+# n64texconv.h
+#
+
+FMT_NONE = -1
+FMT_MAX = 5
+G_IM_FMT_RGBA = 0
+G_IM_FMT_YUV = 1
+G_IM_FMT_CI = 2
+G_IM_FMT_IA = 3
+G_IM_FMT_I = 4
+
+SIZ_NONE = -1
+SIZ_MAX = 4
+G_IM_SIZ_4b = 0
+G_IM_SIZ_8b = 1
+G_IM_SIZ_16b = 2
+G_IM_SIZ_32b = 3
+
+def fmt_name(fmt : int):
+ return {
+ G_IM_FMT_RGBA : "G_IM_FMT_RGBA",
+ G_IM_FMT_YUV : "G_IM_FMT_YUV",
+ G_IM_FMT_CI : "G_IM_FMT_CI",
+ G_IM_FMT_IA : "G_IM_FMT_IA",
+ G_IM_FMT_I : "G_IM_FMT_I",
+ }.get(fmt, str(fmt))
+
+def siz_name(siz : int):
+ return {
+ G_IM_SIZ_4b : "G_IM_SIZ_4b",
+ G_IM_SIZ_8b : "G_IM_SIZ_8b",
+ G_IM_SIZ_16b : "G_IM_SIZ_16b",
+ G_IM_SIZ_32b : "G_IM_SIZ_32b",
+ }.get(siz, str(siz))
+
+VALID_FORMAT_COMBINATIONS = (
+ (G_IM_FMT_RGBA, G_IM_SIZ_16b),
+ (G_IM_FMT_RGBA, G_IM_SIZ_32b),
+ (G_IM_FMT_CI, G_IM_SIZ_4b),
+ (G_IM_FMT_CI, G_IM_SIZ_8b),
+ (G_IM_FMT_IA, G_IM_SIZ_4b),
+ (G_IM_FMT_IA, G_IM_SIZ_8b),
+ (G_IM_FMT_IA, G_IM_SIZ_16b),
+ (G_IM_FMT_I, G_IM_SIZ_4b),
+ (G_IM_FMT_I, G_IM_SIZ_8b),
+)
+
+# struct color
+class Color(Structure):
+ _fields_ = [
+ ("r", c_uint8),
+ ("g", c_uint8),
+ ("b", c_uint8),
+ ("a", c_uint8),
+ ]
+
+# static inline size_t texel_size_bytes(size_t ntexels, int siz)
+def texel_size_bytes(ntexels : int, siz : int):
+ return (ntexels // 2) if (siz == G_IM_SIZ_4b) else (ntexels * ((1 << siz) >> 1))
+
+# struct n64_palette
+class N64Palette(Structure):
+ _fields_ = [
+ ("texels", POINTER(Color)),
+ ("fmt", c_int),
+ ("count", c_size_t),
+ ]
+
+ @staticmethod
+ def new(count : int, fmt : int) -> Optional["N64Palette"]:
+ if fmt not in (G_IM_FMT_RGBA, G_IM_FMT_IA):
+ raise ValueError("Palette format must be either G_IM_FMT_RGBA or G_IM_FMT_IA")
+ if count > 256:
+ raise ValueError("The largest possible palette size is 256")
+ pal = ln64texconv.n64texconv_palette_new(count, fmt)
+ _object_refcount.add_ref(pal)
+ return deref(pal)
+
+ def __del__(self):
+ # Free the underlying palette structure only if the refcount is 0
+ _object_refcount.rm_ref(byref(self), ln64texconv.n64texconv_palette_free)
+
+ def copy(self) -> Optional["N64Palette"]:
+ pal = ln64texconv.n64texconv_palette_copy(byref(self))
+ _object_refcount.add_ref(pal)
+ return deref(pal)
+
+ def reformat(self, fmt : int) -> Optional["N64Palette"]:
+ if fmt not in (G_IM_FMT_RGBA, G_IM_FMT_IA):
+ raise ValueError("Palette format must be either G_IM_FMT_RGBA or G_IM_FMT_IA")
+ pal = ln64texconv.n64texconv_palette_reformat(byref(self), fmt)
+ _object_refcount.add_ref(pal)
+ return deref(pal)
+
+ @staticmethod
+ def from_png(path : str, fmt : int) -> Optional["N64Palette"]:
+ if fmt not in (G_IM_FMT_RGBA, G_IM_FMT_IA):
+ raise ValueError("Palette format must be either G_IM_FMT_RGBA or G_IM_FMT_IA")
+ if not os.path.isfile(path):
+ raise ValueError(f"Cannot open \"{path}\", is not a file")
+ pal = ln64texconv.n64texconv_palette_from_png(path.encode("utf-8"), fmt)
+ _object_refcount.add_ref(pal)
+ return deref(pal)
+
+ @staticmethod
+ def from_bin(data : bytes | memoryview, fmt : int) -> Optional["N64Palette"]:
+ if fmt not in (G_IM_FMT_RGBA, G_IM_FMT_IA):
+ raise ValueError("Palette format must be either G_IM_FMT_RGBA or G_IM_FMT_IA")
+ buffer = (c_uint8 * len(data)).from_buffer_copy(data)
+ pal = ln64texconv.n64texconv_palette_from_bin(buffer, len(data) // 2, fmt)
+ _object_refcount.add_ref(pal)
+ return deref(pal)
+
+ def to_png(self, outpath : str) -> bool:
+ return ln64texconv.n64texconv_palette_to_png(outpath.encode("utf-8"), byref(self)) == 0
+
+ def to_bin(self, pad_to_8b : bool) -> Optional[bytes]:
+ nbytes = texel_size_bytes(self.count, G_IM_SIZ_16b)
+ if pad_to_8b:
+ nbytes = (nbytes + 7) & ~7
+ ptr = ln64texconv.n64texconv_palette_to_bin(byref(self), pad_to_8b)
+ if not ptr:
+ return None
+ data = ctypes_pointer_to_bytes(ptr, nbytes)
+ ln64texconv.n64texconv_free(ptr)
+ return data
+
+ def to_c(self, pad_to_8b : bool, byte_width : int) -> Optional[str]:
+ ptr = c_char_p(None)
+ size = c_size_t(0)
+ if ln64texconv.n64texconv_palette_to_c(byref(ptr), byref(size), byref(self), pad_to_8b, byte_width) != 0:
+ return None
+ s = ctypes_buffer_to_string(ptr)
+ ln64texconv.n64texconv_free(ptr)
+ return s
+
+ def to_c_file(self, out_path : str, pad_to_8b : bool, byte_width : int) -> bool:
+ return ln64texconv.n64texconv_palette_to_c_file(out_path.encode("utf-8"), byref(self), pad_to_8b, byte_width) == 0
+
+# struct n64_palette *n64texconv_palette_new(size_t count, int fmt);
+ln64texconv.n64texconv_palette_new.argtypes = [c_size_t, c_int]
+ln64texconv.n64texconv_palette_new.restype = POINTER(N64Palette)
+
+# void n64texconv_palette_free(struct n64_palette *pal);
+ln64texconv.n64texconv_palette_free.argtypes = [POINTER(N64Palette)]
+ln64texconv.n64texconv_palette_free.restype = None
+
+# struct n64_palette *n64texconv_palette_copy(struct n64_palette *pal);
+ln64texconv.n64texconv_palette_copy.argtypes = [POINTER(N64Palette)]
+ln64texconv.n64texconv_palette_copy.restype = POINTER(N64Palette)
+
+# struct n64_palette *n64texconv_palette_reformat(struct n64_palette *pal, int fmt);
+ln64texconv.n64texconv_palette_reformat.argtypes = [POINTER(N64Palette), c_int]
+ln64texconv.n64texconv_palette_reformat.restype = POINTER(N64Palette)
+
+# struct n64_palette *n64texconv_palette_from_png(const char *path, int fmt);
+ln64texconv.n64texconv_palette_from_png.argtypes = [c_char_p, c_int]
+ln64texconv.n64texconv_palette_from_png.restype = POINTER(N64Palette)
+
+# struct n64_palette *n64texconv_palette_from_bin(void *data, size_t count, int fmt);
+ln64texconv.n64texconv_palette_from_bin.argtypes = [c_void_p, c_size_t, c_int]
+ln64texconv.n64texconv_palette_from_bin.restype = POINTER(N64Palette)
+
+# int n64texconv_palette_to_png(const char *outpath, struct n64_palette *pal);
+ln64texconv.n64texconv_palette_to_png.argtypes = [c_char_p, POINTER(N64Palette)]
+ln64texconv.n64texconv_palette_to_png.restype = c_int
+
+# void *n64texconv_palette_to_bin(struct n64_palette *pal, bool pad_to_8b);
+ln64texconv.n64texconv_palette_to_bin.argtypes = [POINTER(N64Palette), c_bool]
+ln64texconv.n64texconv_palette_to_bin.restype = c_void_p
+
+# int n64texconv_palette_to_c(char **out, size_t *size_out, struct n64_palette *pal, bool pad_to_8b, unsigned int byte_width);
+ln64texconv.n64texconv_palette_to_c.argtypes = [POINTER(c_char_p), POINTER(c_size_t), POINTER(N64Palette), c_bool, c_uint]
+ln64texconv.n64texconv_palette_to_c.restype = c_int
+
+# int n64texconv_palette_to_c_file(const char *out_path, struct n64_palette *pal, bool pad_to_8b, unsigned int byte_width);
+ln64texconv.n64texconv_palette_to_c_file.argtypes = [c_char_p, POINTER(N64Palette), c_bool, c_uint]
+ln64texconv.n64texconv_palette_to_c_file.restype = c_int
+
+# struct n64_image
+class N64Image(Structure):
+ _fields_ = [
+ ("width", c_size_t),
+ ("height", c_size_t),
+ ("fmt", c_int),
+ ("siz", c_int),
+ ("pal", POINTER(N64Palette)),
+ ("texels", POINTER(Color)),
+ ("color_indices", POINTER(c_uint8)),
+ ]
+
+ def get_palette(self) -> Optional[N64Palette]:
+ return deref(self.pal)
+
+ @staticmethod
+ def new(width : int, height : int, fmt : int, siz : int, pal : N64Palette = None) -> Optional["N64Image"]:
+ if not any((fmt, siz) == fmtsiz for fmtsiz in VALID_FORMAT_COMBINATIONS):
+ raise ValueError(f"Invalid fmt/siz combination ({fmt_name(fmt)}, {siz_name(siz)})")
+ if pal is not None:
+ _object_refcount.add_ref(byref(pal))
+ return deref(ln64texconv.n64texconv_image_new(width, height, fmt, siz, pal))
+
+ def __del__(self):
+ ln64texconv.n64texconv_image_free(byref(self))
+ # Also free the palette if the reference count drops to 0
+ _object_refcount.rm_ref(self.pal, ln64texconv.n64texconv_palette_free)
+
+ def copy(self) -> Optional["N64Image"]:
+ _object_refcount.add_ref(self.pal)
+ return deref(ln64texconv.n64texconv_image_copy(byref(self)))
+
+ @staticmethod
+ def from_png(path : str, fmt : int, siz : int, pal_fmt : int = FMT_NONE) -> Optional["N64Image"]:
+ if not os.path.isfile(path):
+ raise ValueError(f"Cannot open \"{path}\", is not a file")
+ if not any((fmt, siz) == fmtsiz for fmtsiz in VALID_FORMAT_COMBINATIONS):
+ raise ValueError(f"Invalid fmt/siz combination ({fmt_name(fmt)}, {siz_name(siz)})")
+ if fmt == G_IM_FMT_CI and pal_fmt not in (G_IM_FMT_RGBA, G_IM_FMT_IA):
+ raise ValueError(f"Invalid palette format {fmt_name(pal_fmt)}, must be either G_IM_FMT_RGBA or G_IM_FMT_IA")
+ img = deref(ln64texconv.n64texconv_image_from_png(path.encode("utf-8"), fmt, siz, pal_fmt))
+ _object_refcount.add_ref(img.pal)
+ return img
+
+ @staticmethod
+ def from_bin(data : bytes | memoryview, width : int, height : int, fmt : int, siz : int, pal : Optional[N64Palette] = None,
+ preswapped : bool = False) -> Optional["N64Image"]:
+ if not any((fmt, siz) == fmtsiz for fmtsiz in VALID_FORMAT_COMBINATIONS):
+ raise ValueError(f"Invalid fmt/siz combination ({fmt_name(fmt)}, {siz_name(siz)})")
+ expected_size = texel_size_bytes(width * height, siz)
+ if len(data) < expected_size:
+ raise ValueError(f"Not enough data to extract the specified image. " +
+ f"Expected at least 0x{expected_size:X} bytes but only got 0x{len(data):X} bytes")
+ buffer = (c_uint8 * len(data)).from_buffer_copy(data)
+ if pal:
+ pal = byref(pal)
+ _object_refcount.add_ref(pal)
+ img = ln64texconv.n64texconv_image_from_bin(buffer, width, height, fmt, siz, pal, preswapped)
+ return deref(img)
+
+ def reformat(self, fmt : int, siz : int, pal : Optional[N64Palette] = None) -> Optional["N64Image"]:
+ if not any((fmt, siz) == fmtsiz for fmtsiz in VALID_FORMAT_COMBINATIONS):
+ raise ValueError(f"Invalid fmt/siz combination ({fmt_name(fmt)}, {siz_name(siz)})")
+ if pal:
+ pal = byref(pal)
+ _object_refcount.add_ref(pal)
+ return deref(ln64texconv.n64texconv_image_reformat(byref(self), fmt, siz, pal))
+
+ def to_png(self, outpath : str, intensity_alpha : bool) -> bool:
+ return ln64texconv.n64texconv_image_to_png(outpath.encode("utf-8"), byref(self), intensity_alpha) == 0
+
+ def to_bin(self, pad_to_8b : bool, preswap : bool) -> Optional[bytes]:
+ nbytes = texel_size_bytes(self.width * self.height, self.siz)
+ if pad_to_8b:
+ nbytes = (nbytes + 7) & ~7
+ ptr = ln64texconv.n64texconv_image_to_bin(byref(self), pad_to_8b, preswap)
+ if not ptr:
+ return None
+ data = ctypes_pointer_to_bytes(ptr, nbytes)
+ ln64texconv.n64texconv_free(ptr)
+ return data
+
+ def to_c(self, pad_to_8b : bool, preswap : bool, byte_width : int) -> Optional[str]:
+ ptr = c_char_p(None)
+ size = c_size_t(0)
+ if ln64texconv.n64texconv_image_to_c(byref(ptr), byref(size), byref(self), pad_to_8b, preswap, byte_width) != 0:
+ return None
+ s = ctypes_buffer_to_string(ptr)
+ ln64texconv.n64texconv_free(ptr)
+ return s
+
+ def to_c_file(self, out_path : str, pad_to_8b : bool, preswap : bool, byte_width : int) -> bool:
+ return ln64texconv.n64texconv_image_to_c_file(out_path.encode("utf-8"), byref(self), pad_to_8b, preswap, byte_width) == 0
+
+ def png_extension(self) -> str:
+ return ln64texconv.n64texconv_png_extension(byref(self)).decode("utf-8")
+
+# struct n64_image *n64texconv_image_new(size_t width, size_t height, int fmt, int siz, struct n64_palette *pal);
+ln64texconv.n64texconv_image_new.argtypes = [c_size_t, c_size_t, c_int, c_int, POINTER(N64Palette)]
+ln64texconv.n64texconv_image_new.restype = POINTER(N64Image)
+
+# void n64texconv_image_free(struct n64_image *img);
+ln64texconv.n64texconv_image_free.argtypes = [POINTER(N64Image)]
+ln64texconv.n64texconv_image_free.restype = None
+
+# struct n64_image *n64texconv_image_copy(struct n64_image *img);
+ln64texconv.n64texconv_image_copy.argtypes = [POINTER(N64Image)]
+ln64texconv.n64texconv_image_copy.restype = POINTER(N64Image)
+
+# struct n64_image *n64texconv_image_from_png(const char *path, int fmt, int siz, int pal_fmt);
+ln64texconv.n64texconv_image_from_png.argtypes = [c_char_p, c_int, c_int, c_int]
+ln64texconv.n64texconv_image_from_png.restype = POINTER(N64Image)
+
+# struct n64_image *n64texconv_image_from_bin(void *data, size_t width, size_t height, int fmt, int siz, struct n64_palette *pal, bool preswapped);
+ln64texconv.n64texconv_image_from_bin.argtypes = [c_void_p, c_size_t, c_size_t, c_int, c_int, POINTER(N64Palette), c_bool]
+ln64texconv.n64texconv_image_from_bin.restype = POINTER(N64Image)
+
+# struct n64_image *n64texconv_image_reformat(struct n64_image *img, int fmt, int siz, struct n64_palette *pal);
+ln64texconv.n64texconv_image_reformat.argtypes = [POINTER(N64Image), c_int, c_int, POINTER(N64Palette)]
+ln64texconv.n64texconv_image_reformat.restype = POINTER(N64Image)
+
+# int n64texconv_image_to_png(const char *outpath, struct n64_image *img, bool intensity_alpha);
+ln64texconv.n64texconv_image_to_png.argtypes = [c_char_p, POINTER(N64Image), c_bool]
+ln64texconv.n64texconv_image_to_png.restype = c_int
+
+# void *n64texconv_image_to_bin(struct n64_image *img, bool pad_to_8b, bool preswap);
+ln64texconv.n64texconv_image_to_bin.argtypes = [POINTER(N64Image), c_bool, c_bool]
+ln64texconv.n64texconv_image_to_bin.restype = c_void_p
+
+# int n64texconv_image_to_c(char **out, size_t *size_out, struct n64_image *img, bool pad_to_8b, bool preswap, unsigned int byte_width);
+ln64texconv.n64texconv_image_to_c.argtypes = [POINTER(c_char_p), POINTER(c_size_t), POINTER(N64Image), c_bool, c_bool, c_uint]
+ln64texconv.n64texconv_image_to_c.restype = c_int
+
+# int n64texconv_image_to_c_file(const char *out_path, struct n64_image *img, bool pad_to_8b, bool preswap, unsigned int byte_width);
+ln64texconv.n64texconv_image_to_c_file.argtypes = [c_char_p, POINTER(N64Image), c_bool, c_bool, c_uint]
+ln64texconv.n64texconv_image_to_c_file.restype = c_int
+
+# const char *n64texconv_png_extension(struct n64_image *img);
+ln64texconv.n64texconv_png_extension.argtypes = [POINTER(N64Image)]
+ln64texconv.n64texconv_png_extension.restype = c_char_p
diff --git a/tools/assets/n64texconv/lib/libimagequant/COPYRIGHT b/tools/assets/n64texconv/lib/libimagequant/COPYRIGHT
new file mode 100644
index 000000000..4297b943e
--- /dev/null
+++ b/tools/assets/n64texconv/lib/libimagequant/COPYRIGHT
@@ -0,0 +1,641 @@
+
+libimagequant is derived from code by Jef Poskanzer and Greg Roelofs
+licensed under pngquant's original license (at the end of this file),
+and contains extensive changes and additions by Kornel Lesiński
+licensed under GPL v3 or later.
+
+- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+libimagequant © 2009-2018 by Kornel Lesiński.
+
+ GNU GENERAL PUBLIC LICENSE
+ Version 3, 29 June 2007
+
+ Copyright (C) 2007 Free Software Foundation, Inc.
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The GNU General Public License is a free, copyleft license for
+software and other kinds of works.
+
+ The licenses for most software and other practical works are designed
+to take away your freedom to share and change the works. By contrast,
+the GNU General Public License is intended to guarantee your freedom to
+share and change all versions of a program--to make sure it remains free
+software for all its users. We, the Free Software Foundation, use the
+GNU General Public License for most of our software; it applies also to
+any other work released this way by its authors. You can apply it to
+your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+them if you wish), that you receive source code or can get it if you
+want it, that you can change the software or use pieces of it in new
+free programs, and that you know you can do these things.
+
+ To protect your rights, we need to prevent others from denying you
+these rights or asking you to surrender the rights. Therefore, you have
+certain responsibilities if you distribute copies of the software, or if
+you modify it: responsibilities to respect the freedom of others.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must pass on to the recipients the same
+freedoms that you received. You must make sure that they, too, receive
+or can get the source code. And you must show them these terms so they
+know their rights.
+
+ Developers that use the GNU GPL protect your rights with two steps:
+(1) assert copyright on the software, and (2) offer you this License
+giving you legal permission to copy, distribute and/or modify it.
+
+ For the developers' and authors' protection, the GPL clearly explains
+that there is no warranty for this free software. For both users' and
+authors' sake, the GPL requires that modified versions be marked as
+changed, so that their problems will not be attributed erroneously to
+authors of previous versions.
+
+ Some devices are designed to deny users access to install or run
+modified versions of the software inside them, although the manufacturer
+can do so. This is fundamentally incompatible with the aim of
+protecting users' freedom to change the software. The systematic
+pattern of such abuse occurs in the area of products for individuals to
+use, which is precisely where it is most unacceptable. Therefore, we
+have designed this version of the GPL to prohibit the practice for those
+products. If such problems arise substantially in other domains, we
+stand ready to extend this provision to those domains in future versions
+of the GPL, as needed to protect the freedom of users.
+
+ Finally, every program is threatened constantly by software patents.
+States should not allow patents to restrict development and use of
+software on general-purpose computers, but in those that do, we wish to
+avoid the special danger that patents applied to a free program could
+make it effectively proprietary. To prevent this, the GPL assures that
+patents cannot be used to render the program non-free.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ TERMS AND CONDITIONS
+
+ 0. Definitions.
+
+ "This License" refers to version 3 of the GNU General Public License.
+
+ "Copyright" also means copyright-like laws that apply to other kinds of
+works, such as semiconductor masks.
+
+ "The Program" refers to any copyrightable work licensed under this
+License. Each licensee is addressed as "you". "Licensees" and
+"recipients" may be individuals or organizations.
+
+ To "modify" a work means to copy from or adapt all or part of the work
+in a fashion requiring copyright permission, other than the making of an
+exact copy. The resulting work is called a "modified version" of the
+earlier work or a work "based on" the earlier work.
+
+ A "covered work" means either the unmodified Program or a work based
+on the Program.
+
+ To "propagate" a work means to do anything with it that, without
+permission, would make you directly or secondarily liable for
+infringement under applicable copyright law, except executing it on a
+computer or modifying a private copy. Propagation includes copying,
+distribution (with or without modification), making available to the
+public, and in some countries other activities as well.
+
+ To "convey" a work means any kind of propagation that enables other
+parties to make or receive copies. Mere interaction with a user through
+a computer network, with no transfer of a copy, is not conveying.
+
+ An interactive user interface displays "Appropriate Legal Notices"
+to the extent that it includes a convenient and prominently visible
+feature that (1) displays an appropriate copyright notice, and (2)
+tells the user that there is no warranty for the work (except to the
+extent that warranties are provided), that licensees may convey the
+work under this License, and how to view a copy of this License. If
+the interface presents a list of user commands or options, such as a
+menu, a prominent item in the list meets this criterion.
+
+ 1. Source Code.
+
+ The "source code" for a work means the preferred form of the work
+for making modifications to it. "Object code" means any non-source
+form of a work.
+
+ A "Standard Interface" means an interface that either is an official
+standard defined by a recognized standards body, or, in the case of
+interfaces specified for a particular programming language, one that
+is widely used among developers working in that language.
+
+ The "System Libraries" of an executable work include anything, other
+than the work as a whole, that (a) is included in the normal form of
+packaging a Major Component, but which is not part of that Major
+Component, and (b) serves only to enable use of the work with that
+Major Component, or to implement a Standard Interface for which an
+implementation is available to the public in source code form. A
+"Major Component", in this context, means a major essential component
+(kernel, window system, and so on) of the specific operating system
+(if any) on which the executable work runs, or a compiler used to
+produce the work, or an object code interpreter used to run it.
+
+ The "Corresponding Source" for a work in object code form means all
+the source code needed to generate, install, and (for an executable
+work) run the object code and to modify the work, including scripts to
+control those activities. However, it does not include the work's
+System Libraries, or general-purpose tools or generally available free
+programs which are used unmodified in performing those activities but
+which are not part of the work. For example, Corresponding Source
+includes interface definition files associated with source files for
+the work, and the source code for shared libraries and dynamically
+linked subprograms that the work is specifically designed to require,
+such as by intimate data communication or control flow between those
+subprograms and other parts of the work.
+
+ The Corresponding Source need not include anything that users
+can regenerate automatically from other parts of the Corresponding
+Source.
+
+ The Corresponding Source for a work in source code form is that
+same work.
+
+ 2. Basic Permissions.
+
+ All rights granted under this License are granted for the term of
+copyright on the Program, and are irrevocable provided the stated
+conditions are met. This License explicitly affirms your unlimited
+permission to run the unmodified Program. The output from running a
+covered work is covered by this License only if the output, given its
+content, constitutes a covered work. This License acknowledges your
+rights of fair use or other equivalent, as provided by copyright law.
+
+ You may make, run and propagate covered works that you do not
+convey, without conditions so long as your license otherwise remains
+in force. You may convey covered works to others for the sole purpose
+of having them make modifications exclusively for you, or provide you
+with facilities for running those works, provided that you comply with
+the terms of this License in conveying all material for which you do
+not control copyright. Those thus making or running the covered works
+for you must do so exclusively on your behalf, under your direction
+and control, on terms that prohibit them from making any copies of
+your copyrighted material outside their relationship with you.
+
+ Conveying under any other circumstances is permitted solely under
+the conditions stated below. Sublicensing is not allowed; section 10
+makes it unnecessary.
+
+ 3. Protecting Users' Legal Rights From Anti-Circumvention Law.
+
+ No covered work shall be deemed part of an effective technological
+measure under any applicable law fulfilling obligations under article
+11 of the WIPO copyright treaty adopted on 20 December 1996, or
+similar laws prohibiting or restricting circumvention of such
+measures.
+
+ When you convey a covered work, you waive any legal power to forbid
+circumvention of technological measures to the extent such circumvention
+is effected by exercising rights under this License with respect to
+the covered work, and you disclaim any intention to limit operation or
+modification of the work as a means of enforcing, against the work's
+users, your or third parties' legal rights to forbid circumvention of
+technological measures.
+
+ 4. Conveying Verbatim Copies.
+
+ You may convey verbatim copies of the Program's source code as you
+receive it, in any medium, provided that you conspicuously and
+appropriately publish on each copy an appropriate copyright notice;
+keep intact all notices stating that this License and any
+non-permissive terms added in accord with section 7 apply to the code;
+keep intact all notices of the absence of any warranty; and give all
+recipients a copy of this License along with the Program.
+
+ You may charge any price or no price for each copy that you convey,
+and you may offer support or warranty protection for a fee.
+
+ 5. Conveying Modified Source Versions.
+
+ You may convey a work based on the Program, or the modifications to
+produce it from the Program, in the form of source code under the
+terms of section 4, provided that you also meet all of these conditions:
+
+ a) The work must carry prominent notices stating that you modified
+ it, and giving a relevant date.
+
+ b) The work must carry prominent notices stating that it is
+ released under this License and any conditions added under section
+ 7. This requirement modifies the requirement in section 4 to
+ "keep intact all notices".
+
+ c) You must license the entire work, as a whole, under this
+ License to anyone who comes into possession of a copy. This
+ License will therefore apply, along with any applicable section 7
+ additional terms, to the whole of the work, and all its parts,
+ regardless of how they are packaged. This License gives no
+ permission to license the work in any other way, but it does not
+ invalidate such permission if you have separately received it.
+
+ d) If the work has interactive user interfaces, each must display
+ Appropriate Legal Notices; however, if the Program has interactive
+ interfaces that do not display Appropriate Legal Notices, your
+ work need not make them do so.
+
+ A compilation of a covered work with other separate and independent
+works, which are not by their nature extensions of the covered work,
+and which are not combined with it such as to form a larger program,
+in or on a volume of a storage or distribution medium, is called an
+"aggregate" if the compilation and its resulting copyright are not
+used to limit the access or legal rights of the compilation's users
+beyond what the individual works permit. Inclusion of a covered work
+in an aggregate does not cause this License to apply to the other
+parts of the aggregate.
+
+ 6. Conveying Non-Source Forms.
+
+ You may convey a covered work in object code form under the terms
+of sections 4 and 5, provided that you also convey the
+machine-readable Corresponding Source under the terms of this License,
+in one of these ways:
+
+ a) Convey the object code in, or embodied in, a physical product
+ (including a physical distribution medium), accompanied by the
+ Corresponding Source fixed on a durable physical medium
+ customarily used for software interchange.
+
+ b) Convey the object code in, or embodied in, a physical product
+ (including a physical distribution medium), accompanied by a
+ written offer, valid for at least three years and valid for as
+ long as you offer spare parts or customer support for that product
+ model, to give anyone who possesses the object code either (1) a
+ copy of the Corresponding Source for all the software in the
+ product that is covered by this License, on a durable physical
+ medium customarily used for software interchange, for a price no
+ more than your reasonable cost of physically performing this
+ conveying of source, or (2) access to copy the
+ Corresponding Source from a network server at no charge.
+
+ c) Convey individual copies of the object code with a copy of the
+ written offer to provide the Corresponding Source. This
+ alternative is allowed only occasionally and noncommercially, and
+ only if you received the object code with such an offer, in accord
+ with subsection 6b.
+
+ d) Convey the object code by offering access from a designated
+ place (gratis or for a charge), and offer equivalent access to the
+ Corresponding Source in the same way through the same place at no
+ further charge. You need not require recipients to copy the
+ Corresponding Source along with the object code. If the place to
+ copy the object code is a network server, the Corresponding Source
+ may be on a different server (operated by you or a third party)
+ that supports equivalent copying facilities, provided you maintain
+ clear directions next to the object code saying where to find the
+ Corresponding Source. Regardless of what server hosts the
+ Corresponding Source, you remain obligated to ensure that it is
+ available for as long as needed to satisfy these requirements.
+
+ e) Convey the object code using peer-to-peer transmission, provided
+ you inform other peers where the object code and Corresponding
+ Source of the work are being offered to the general public at no
+ charge under subsection 6d.
+
+ A separable portion of the object code, whose source code is excluded
+from the Corresponding Source as a System Library, need not be
+included in conveying the object code work.
+
+ A "User Product" is either (1) a "consumer product", which means any
+tangible personal property which is normally used for personal, family,
+or household purposes, or (2) anything designed or sold for incorporation
+into a dwelling. In determining whether a product is a consumer product,
+doubtful cases shall be resolved in favor of coverage. For a particular
+product received by a particular user, "normally used" refers to a
+typical or common use of that class of product, regardless of the status
+of the particular user or of the way in which the particular user
+actually uses, or expects or is expected to use, the product. A product
+is a consumer product regardless of whether the product has substantial
+commercial, industrial or non-consumer uses, unless such uses represent
+the only significant mode of use of the product.
+
+ "Installation Information" for a User Product means any methods,
+procedures, authorization keys, or other information required to install
+and execute modified versions of a covered work in that User Product from
+a modified version of its Corresponding Source. The information must
+suffice to ensure that the continued functioning of the modified object
+code is in no case prevented or interfered with solely because
+modification has been made.
+
+ If you convey an object code work under this section in, or with, or
+specifically for use in, a User Product, and the conveying occurs as
+part of a transaction in which the right of possession and use of the
+User Product is transferred to the recipient in perpetuity or for a
+fixed term (regardless of how the transaction is characterized), the
+Corresponding Source conveyed under this section must be accompanied
+by the Installation Information. But this requirement does not apply
+if neither you nor any third party retains the ability to install
+modified object code on the User Product (for example, the work has
+been installed in ROM).
+
+ The requirement to provide Installation Information does not include a
+requirement to continue to provide support service, warranty, or updates
+for a work that has been modified or installed by the recipient, or for
+the User Product in which it has been modified or installed. Access to a
+network may be denied when the modification itself materially and
+adversely affects the operation of the network or violates the rules and
+protocols for communication across the network.
+
+ Corresponding Source conveyed, and Installation Information provided,
+in accord with this section must be in a format that is publicly
+documented (and with an implementation available to the public in
+source code form), and must require no special password or key for
+unpacking, reading or copying.
+
+ 7. Additional Terms.
+
+ "Additional permissions" are terms that supplement the terms of this
+License by making exceptions from one or more of its conditions.
+Additional permissions that are applicable to the entire Program shall
+be treated as though they were included in this License, to the extent
+that they are valid under applicable law. If additional permissions
+apply only to part of the Program, that part may be used separately
+under those permissions, but the entire Program remains governed by
+this License without regard to the additional permissions.
+
+ When you convey a copy of a covered work, you may at your option
+remove any additional permissions from that copy, or from any part of
+it. (Additional permissions may be written to require their own
+removal in certain cases when you modify the work.) You may place
+additional permissions on material, added by you to a covered work,
+for which you have or can give appropriate copyright permission.
+
+ Notwithstanding any other provision of this License, for material you
+add to a covered work, you may (if authorized by the copyright holders of
+that material) supplement the terms of this License with terms:
+
+ a) Disclaiming warranty or limiting liability differently from the
+ terms of sections 15 and 16 of this License; or
+
+ b) Requiring preservation of specified reasonable legal notices or
+ author attributions in that material or in the Appropriate Legal
+ Notices displayed by works containing it; or
+
+ c) Prohibiting misrepresentation of the origin of that material, or
+ requiring that modified versions of such material be marked in
+ reasonable ways as different from the original version; or
+
+ d) Limiting the use for publicity purposes of names of licensors or
+ authors of the material; or
+
+ e) Declining to grant rights under trademark law for use of some
+ trade names, trademarks, or service marks; or
+
+ f) Requiring indemnification of licensors and authors of that
+ material by anyone who conveys the material (or modified versions of
+ it) with contractual assumptions of liability to the recipient, for
+ any liability that these contractual assumptions directly impose on
+ those licensors and authors.
+
+ All other non-permissive additional terms are considered "further
+restrictions" within the meaning of section 10. If the Program as you
+received it, or any part of it, contains a notice stating that it is
+governed by this License along with a term that is a further
+restriction, you may remove that term. If a license document contains
+a further restriction but permits relicensing or conveying under this
+License, you may add to a covered work material governed by the terms
+of that license document, provided that the further restriction does
+not survive such relicensing or conveying.
+
+ If you add terms to a covered work in accord with this section, you
+must place, in the relevant source files, a statement of the
+additional terms that apply to those files, or a notice indicating
+where to find the applicable terms.
+
+ Additional terms, permissive or non-permissive, may be stated in the
+form of a separately written license, or stated as exceptions;
+the above requirements apply either way.
+
+ 8. Termination.
+
+ You may not propagate or modify a covered work except as expressly
+provided under this License. Any attempt otherwise to propagate or
+modify it is void, and will automatically terminate your rights under
+this License (including any patent licenses granted under the third
+paragraph of section 11).
+
+ However, if you cease all violation of this License, then your
+license from a particular copyright holder is reinstated (a)
+provisionally, unless and until the copyright holder explicitly and
+finally terminates your license, and (b) permanently, if the copyright
+holder fails to notify you of the violation by some reasonable means
+prior to 60 days after the cessation.
+
+ Moreover, your license from a particular copyright holder is
+reinstated permanently if the copyright holder notifies you of the
+violation by some reasonable means, this is the first time you have
+received notice of violation of this License (for any work) from that
+copyright holder, and you cure the violation prior to 30 days after
+your receipt of the notice.
+
+ Termination of your rights under this section does not terminate the
+licenses of parties who have received copies or rights from you under
+this License. If your rights have been terminated and not permanently
+reinstated, you do not qualify to receive new licenses for the same
+material under section 10.
+
+ 9. Acceptance Not Required for Having Copies.
+
+ You are not required to accept this License in order to receive or
+run a copy of the Program. Ancillary propagation of a covered work
+occurring solely as a consequence of using peer-to-peer transmission
+to receive a copy likewise does not require acceptance. However,
+nothing other than this License grants you permission to propagate or
+modify any covered work. These actions infringe copyright if you do
+not accept this License. Therefore, by modifying or propagating a
+covered work, you indicate your acceptance of this License to do so.
+
+ 10. Automatic Licensing of Downstream Recipients.
+
+ Each time you convey a covered work, the recipient automatically
+receives a license from the original licensors, to run, modify and
+propagate that work, subject to this License. You are not responsible
+for enforcing compliance by third parties with this License.
+
+ An "entity transaction" is a transaction transferring control of an
+organization, or substantially all assets of one, or subdividing an
+organization, or merging organizations. If propagation of a covered
+work results from an entity transaction, each party to that
+transaction who receives a copy of the work also receives whatever
+licenses to the work the party's predecessor in interest had or could
+give under the previous paragraph, plus a right to possession of the
+Corresponding Source of the work from the predecessor in interest, if
+the predecessor has it or can get it with reasonable efforts.
+
+ You may not impose any further restrictions on the exercise of the
+rights granted or affirmed under this License. For example, you may
+not impose a license fee, royalty, or other charge for exercise of
+rights granted under this License, and you may not initiate litigation
+(including a cross-claim or counterclaim in a lawsuit) alleging that
+any patent claim is infringed by making, using, selling, offering for
+sale, or importing the Program or any portion of it.
+
+ 11. Patents.
+
+ A "contributor" is a copyright holder who authorizes use under this
+License of the Program or a work on which the Program is based. The
+work thus licensed is called the contributor's "contributor version".
+
+ A contributor's "essential patent claims" are all patent claims
+owned or controlled by the contributor, whether already acquired or
+hereafter acquired, that would be infringed by some manner, permitted
+by this License, of making, using, or selling its contributor version,
+but do not include claims that would be infringed only as a
+consequence of further modification of the contributor version. For
+purposes of this definition, "control" includes the right to grant
+patent sublicenses in a manner consistent with the requirements of
+this License.
+
+ Each contributor grants you a non-exclusive, worldwide, royalty-free
+patent license under the contributor's essential patent claims, to
+make, use, sell, offer for sale, import and otherwise run, modify and
+propagate the contents of its contributor version.
+
+ In the following three paragraphs, a "patent license" is any express
+agreement or commitment, however denominated, not to enforce a patent
+(such as an express permission to practice a patent or covenant not to
+sue for patent infringement). To "grant" such a patent license to a
+party means to make such an agreement or commitment not to enforce a
+patent against the party.
+
+ If you convey a covered work, knowingly relying on a patent license,
+and the Corresponding Source of the work is not available for anyone
+to copy, free of charge and under the terms of this License, through a
+publicly available network server or other readily accessible means,
+then you must either (1) cause the Corresponding Source to be so
+available, or (2) arrange to deprive yourself of the benefit of the
+patent license for this particular work, or (3) arrange, in a manner
+consistent with the requirements of this License, to extend the patent
+license to downstream recipients. "Knowingly relying" means you have
+actual knowledge that, but for the patent license, your conveying the
+covered work in a country, or your recipient's use of the covered work
+in a country, would infringe one or more identifiable patents in that
+country that you have reason to believe are valid.
+
+ If, pursuant to or in connection with a single transaction or
+arrangement, you convey, or propagate by procuring conveyance of, a
+covered work, and grant a patent license to some of the parties
+receiving the covered work authorizing them to use, propagate, modify
+or convey a specific copy of the covered work, then the patent license
+you grant is automatically extended to all recipients of the covered
+work and works based on it.
+
+ A patent license is "discriminatory" if it does not include within
+the scope of its coverage, prohibits the exercise of, or is
+conditioned on the non-exercise of one or more of the rights that are
+specifically granted under this License. You may not convey a covered
+work if you are a party to an arrangement with a third party that is
+in the business of distributing software, under which you make payment
+to the third party based on the extent of your activity of conveying
+the work, and under which the third party grants, to any of the
+parties who would receive the covered work from you, a discriminatory
+patent license (a) in connection with copies of the covered work
+conveyed by you (or copies made from those copies), or (b) primarily
+for and in connection with specific products or compilations that
+contain the covered work, unless you entered into that arrangement,
+or that patent license was granted, prior to 28 March 2007.
+
+ Nothing in this License shall be construed as excluding or limiting
+any implied license or other defenses to infringement that may
+otherwise be available to you under applicable patent law.
+
+ 12. No Surrender of Others' Freedom.
+
+ If conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot convey a
+covered work so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you may
+not convey it at all. For example, if you agree to terms that obligate you
+to collect a royalty for further conveying from those to whom you convey
+the Program, the only way you could satisfy both those terms and this
+License would be to refrain entirely from conveying the Program.
+
+ 13. Use with the GNU Affero General Public License.
+
+ Notwithstanding any other provision of this License, you have
+permission to link or combine any covered work with a work licensed
+under version 3 of the GNU Affero General Public License into a single
+combined work, and to convey the resulting work. The terms of this
+License will continue to apply to the part which is the covered work,
+but the special requirements of the GNU Affero General Public License,
+section 13, concerning interaction through a network will apply to the
+combination as such.
+
+ 14. Revised Versions of this License.
+
+ The Free Software Foundation may publish revised and/or new versions of
+the GNU General Public License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+ Each version is given a distinguishing version number. If the
+Program specifies that a certain numbered version of the GNU General
+Public License "or any later version" applies to it, you have the
+option of following the terms and conditions either of that numbered
+version or of any later version published by the Free Software
+Foundation. If the Program does not specify a version number of the
+GNU General Public License, you may choose any version ever published
+by the Free Software Foundation.
+
+ If the Program specifies that a proxy can decide which future
+versions of the GNU General Public License can be used, that proxy's
+public statement of acceptance of a version permanently authorizes you
+to choose that version for the Program.
+
+ Later license versions may give you additional or different
+permissions. However, no additional obligations are imposed on any
+author or copyright holder as a result of your choosing to follow a
+later version.
+
+ 15. Disclaimer of Warranty.
+
+ THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
+APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
+HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
+OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
+THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
+IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
+ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+ 16. Limitation of Liability.
+
+ IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
+THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
+GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
+USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
+DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
+PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
+EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGES.
+
+ 17. Interpretation of Sections 15 and 16.
+
+ If the disclaimer of warranty and limitation of liability provided
+above cannot be given local legal effect according to their terms,
+reviewing courts shall apply local law that most closely approximates
+an absolute waiver of all civil liability in connection with the
+Program, unless a warranty or assumption of liability accompanies a
+copy of the Program in return for a fee.
+
+- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+© 1989, 1991 by Jef Poskanzer.
+© 1997, 2000, 2002 by Greg Roelofs.
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted, provided
+that the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation. This software is provided "as is" without express or
+implied warranty.
diff --git a/tools/assets/n64texconv/lib/libimagequant/blur.c b/tools/assets/n64texconv/lib/libimagequant/blur.c
new file mode 100644
index 000000000..7f0a71672
--- /dev/null
+++ b/tools/assets/n64texconv/lib/libimagequant/blur.c
@@ -0,0 +1,132 @@
+/*
+© 2011-2015 by Kornel Lesiński.
+
+This file is part of libimagequant.
+
+libimagequant is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+libimagequant is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with libimagequant. If not, see .
+*/
+
+#include "libimagequant.h"
+#include "pam.h"
+#include "blur.h"
+
+/*
+ Blurs image horizontally (width 2*size+1) and writes it transposed to dst (called twice gives 2d blur)
+ */
+static void transposing_1d_blur(unsigned char *restrict src, unsigned char *restrict dst, unsigned int width, unsigned int height, const unsigned int size)
+{
+ assert(size > 0);
+
+ for(unsigned int j=0; j < height; j++) {
+ unsigned char *restrict row = src + j*width;
+
+ // accumulate sum for pixels outside line
+ unsigned int sum;
+ sum = row[0]*size;
+ for(unsigned int i=0; i < size; i++) {
+ sum += row[i];
+ }
+
+ // blur with left side outside line
+ for(unsigned int i=0; i < size; i++) {
+ sum -= row[0];
+ sum += row[i+size];
+
+ dst[i*height + j] = sum / (size*2);
+ }
+
+ for(unsigned int i=size; i < width-size; i++) {
+ sum -= row[i-size];
+ sum += row[i+size];
+
+ dst[i*height + j] = sum / (size*2);
+ }
+
+ // blur with right side outside line
+ for(unsigned int i=width-size; i < width; i++) {
+ sum -= row[i-size];
+ sum += row[width-1];
+
+ dst[i*height + j] = sum / (size*2);
+ }
+ }
+}
+
+/**
+ * Picks maximum of neighboring pixels (blur + lighten)
+ */
+LIQ_PRIVATE void liq_max3(unsigned char *src, unsigned char *dst, unsigned int width, unsigned int height)
+{
+ for(unsigned int j=0; j < height; j++) {
+ const unsigned char *row = src + j*width,
+ *prevrow = src + (j > 1 ? j-1 : 0)*width,
+ *nextrow = src + MIN(height-1,j+1)*width;
+
+ unsigned char prev,curr=row[0],next=row[0];
+
+ for(unsigned int i=0; i < width-1; i++) {
+ prev=curr;
+ curr=next;
+ next=row[i+1];
+
+ unsigned char t1 = MAX(prev,next);
+ unsigned char t2 = MAX(nextrow[i],prevrow[i]);
+ *dst++ = MAX(curr,MAX(t1,t2));
+ }
+ unsigned char t1 = MAX(curr,next);
+ unsigned char t2 = MAX(nextrow[width-1],prevrow[width-1]);
+ *dst++ = MAX(t1,t2);
+ }
+}
+
+/**
+ * Picks minimum of neighboring pixels (blur + darken)
+ */
+LIQ_PRIVATE void liq_min3(unsigned char *src, unsigned char *dst, unsigned int width, unsigned int height)
+{
+ for(unsigned int j=0; j < height; j++) {
+ const unsigned char *row = src + j*width,
+ *prevrow = src + (j > 1 ? j-1 : 0)*width,
+ *nextrow = src + MIN(height-1,j+1)*width;
+
+ unsigned char prev,curr=row[0],next=row[0];
+
+ for(unsigned int i=0; i < width-1; i++) {
+ prev=curr;
+ curr=next;
+ next=row[i+1];
+
+ unsigned char t1 = MIN(prev,next);
+ unsigned char t2 = MIN(nextrow[i],prevrow[i]);
+ *dst++ = MIN(curr,MIN(t1,t2));
+ }
+ unsigned char t1 = MIN(curr,next);
+ unsigned char t2 = MIN(nextrow[width-1],prevrow[width-1]);
+ *dst++ = MIN(t1,t2);
+ }
+}
+
+/*
+ Filters src image and saves it to dst, overwriting tmp in the process.
+ Image must be width*height pixels high. Size controls radius of box blur.
+ */
+LIQ_PRIVATE void liq_blur(unsigned char *src, unsigned char *tmp, unsigned char *dst, unsigned int width, unsigned int height, unsigned int size)
+{
+ assert(size > 0);
+ if (width < 2*size+1 || height < 2*size+1) {
+ return;
+ }
+ transposing_1d_blur(src, tmp, width, height, size);
+ transposing_1d_blur(tmp, dst, height, width, size);
+}
diff --git a/tools/assets/n64texconv/lib/libimagequant/blur.h b/tools/assets/n64texconv/lib/libimagequant/blur.h
new file mode 100644
index 000000000..1e7781920
--- /dev/null
+++ b/tools/assets/n64texconv/lib/libimagequant/blur.h
@@ -0,0 +1,8 @@
+#ifndef BLUR_H
+#define BLUR_H
+
+LIQ_PRIVATE void liq_blur(unsigned char *src, unsigned char *tmp, unsigned char *dst, unsigned int width, unsigned int height, unsigned int size);
+LIQ_PRIVATE void liq_max3(unsigned char *src, unsigned char *dst, unsigned int width, unsigned int height);
+LIQ_PRIVATE void liq_min3(unsigned char *src, unsigned char *dst, unsigned int width, unsigned int height);
+
+#endif
diff --git a/tools/assets/n64texconv/lib/libimagequant/kmeans.c b/tools/assets/n64texconv/lib/libimagequant/kmeans.c
new file mode 100644
index 000000000..6d1a12287
--- /dev/null
+++ b/tools/assets/n64texconv/lib/libimagequant/kmeans.c
@@ -0,0 +1,119 @@
+/*
+** © 2011-2016 by Kornel Lesiński.
+** See COPYRIGHT file for license.
+*/
+
+#include "libimagequant.h"
+#include "pam.h"
+#include "kmeans.h"
+#include "nearest.h"
+#include
+#include
+
+#ifdef _OPENMP
+#include
+#else
+#define omp_get_max_threads() 1
+#define omp_get_thread_num() 0
+#endif
+
+/*
+ * K-Means iteration: new palette color is computed from weighted average of colors that map to that palette entry.
+ */
+LIQ_PRIVATE void kmeans_init(const colormap *map, const unsigned int max_threads, kmeans_state average_color[])
+{
+ memset(average_color, 0, sizeof(average_color[0])*(KMEANS_CACHE_LINE_GAP+map->colors)*max_threads);
+}
+
+LIQ_PRIVATE void kmeans_update_color(const f_pixel acolor, const float value, const colormap *map, unsigned int match, const unsigned int thread, kmeans_state average_color[])
+{
+ match += thread * (KMEANS_CACHE_LINE_GAP+map->colors);
+ average_color[match].a += acolor.a * value;
+ average_color[match].r += acolor.r * value;
+ average_color[match].g += acolor.g * value;
+ average_color[match].b += acolor.b * value;
+ average_color[match].total += value;
+}
+
+LIQ_PRIVATE void kmeans_finalize(colormap *map, const unsigned int max_threads, const kmeans_state average_color[])
+{
+ for (unsigned int i=0; i < map->colors; i++) {
+ double a=0, r=0, g=0, b=0, total=0;
+
+ // Aggregate results from all threads
+ for(unsigned int t=0; t < max_threads; t++) {
+ const unsigned int offset = (KMEANS_CACHE_LINE_GAP+map->colors) * t + i;
+
+ a += average_color[offset].a;
+ r += average_color[offset].r;
+ g += average_color[offset].g;
+ b += average_color[offset].b;
+ total += average_color[offset].total;
+ }
+
+ if (!map->palette[i].fixed) {
+ map->palette[i].popularity = total;
+ if (total) {
+ map->palette[i].acolor = (f_pixel){
+ .a = a / total,
+ .r = r / total,
+ .g = g / total,
+ .b = b / total,
+ };
+ } else {
+ // if a color is useless, make a new one
+ // (it was supposed to be random, but Android NDK has problematic stdlib headers)
+ map->palette[i].acolor.a = map->palette[(i+1)%map->colors].acolor.a;
+ map->palette[i].acolor.r = map->palette[(i+2)%map->colors].acolor.r;
+ map->palette[i].acolor.g = map->palette[(i+3)%map->colors].acolor.g;
+ map->palette[i].acolor.b = map->palette[(i+4)%map->colors].acolor.b;
+ }
+ }
+ }
+}
+
+LIQ_PRIVATE double kmeans_do_iteration(histogram *hist, colormap *const map, kmeans_callback callback, unsigned int max_threads)
+{
+ LIQ_ARRAY(kmeans_state, average_color, (KMEANS_CACHE_LINE_GAP+map->colors) * max_threads);
+ kmeans_init(map, max_threads, average_color);
+ struct nearest_map *const n = nearest_init(map);
+ hist_item *const achv = hist->achv;
+ const int hist_size = hist->size;
+
+ double total_diff=0;
+#if __GNUC__ >= 9 || __clang__
+ #pragma omp parallel for if (hist_size > 2000) \
+ schedule(static) default(none) shared(achv,average_color,callback,hist_size,map,n) reduction(+:total_diff)
+#else
+ #pragma omp parallel for if (hist_size > 2000) \
+ schedule(static) default(none) shared(average_color,callback) reduction(+:total_diff)
+#endif
+ for(int j=0; j < hist_size; j++) {
+ float diff;
+ const f_pixel px = achv[j].acolor;
+ const unsigned int match = nearest_search(n, &px, achv[j].tmp.likely_colormap_index, &diff);
+ achv[j].tmp.likely_colormap_index = match;
+
+ if (callback) {
+ // Check how average diff would look like if there was dithering
+ const f_pixel remapped = map->palette[match].acolor;
+ nearest_search(n, &(f_pixel){
+ .a = px.a + px.a - remapped.a,
+ .r = px.r + px.r - remapped.r,
+ .g = px.g + px.g - remapped.g,
+ .b = px.b + px.b - remapped.b,
+ }, match, &diff);
+
+ callback(&achv[j], diff);
+ }
+
+ total_diff += diff * achv[j].perceptual_weight;
+
+ kmeans_update_color(px, achv[j].adjusted_weight, map, match, omp_get_thread_num(), average_color);
+ }
+
+ nearest_free(n);
+ kmeans_finalize(map, max_threads, average_color);
+
+ return total_diff / hist->total_perceptual_weight;
+}
diff --git a/tools/assets/n64texconv/lib/libimagequant/kmeans.h b/tools/assets/n64texconv/lib/libimagequant/kmeans.h
new file mode 100644
index 000000000..78db4ccde
--- /dev/null
+++ b/tools/assets/n64texconv/lib/libimagequant/kmeans.h
@@ -0,0 +1,18 @@
+#ifndef KMEANS_H
+#define KMEANS_H
+
+// Spread memory touched by different threads at least 64B apart which I assume is the cache line size. This should avoid memory write contention.
+#define KMEANS_CACHE_LINE_GAP ((64+sizeof(kmeans_state)-1)/sizeof(kmeans_state))
+
+typedef struct {
+ double a, r, g, b, total;
+} kmeans_state;
+
+typedef void (*kmeans_callback)(hist_item *item, float diff);
+
+LIQ_PRIVATE void kmeans_init(const colormap *map, const unsigned int max_threads, kmeans_state state[]);
+LIQ_PRIVATE void kmeans_update_color(const f_pixel acolor, const float value, const colormap *map, unsigned int match, const unsigned int thread, kmeans_state average_color[]);
+LIQ_PRIVATE void kmeans_finalize(colormap *map, const unsigned int max_threads, const kmeans_state state[]);
+LIQ_PRIVATE double kmeans_do_iteration(histogram *hist, colormap *const map, kmeans_callback callback, const unsigned int max_threads);
+
+#endif
diff --git a/tools/assets/n64texconv/lib/libimagequant/libimagequant.c b/tools/assets/n64texconv/lib/libimagequant/libimagequant.c
new file mode 100644
index 000000000..632c24277
--- /dev/null
+++ b/tools/assets/n64texconv/lib/libimagequant/libimagequant.c
@@ -0,0 +1,1814 @@
+/*
+** © 2009-2018 by Kornel Lesiński.
+** © 1989, 1991 by Jef Poskanzer.
+** © 1997, 2000, 2002 by Greg Roelofs; based on an idea by Stefan Schneider.
+**
+** See COPYRIGHT file for license.
+*/
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#if !(defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199900L) && !(defined(_MSC_VER) && _MSC_VER >= 1800)
+#error "This program requires C99, e.g. -std=c99 switch in GCC or it requires MSVC 18.0 or higher."
+#error "Ignore torrent of syntax errors that may follow. It's only because compiler is set to use too old C version."
+#endif
+
+#include "libimagequant.h"
+
+#include "pam.h"
+#include "libimagequant_private.h"
+#include "mediancut.h"
+#include "blur.h"
+#include "kmeans.h"
+#include "remap.h"
+
+#define LIQ_HIGH_MEMORY_LIMIT (1<<26) /* avoid allocating buffers larger than 64MB */
+
+// each structure has a pointer as a unique identifier that allows type checking at run time
+static const char liq_attr_magic[] = "liq_attr";
+static const char liq_image_magic[] = "liq_image";
+static const char liq_result_magic[] = "liq_result";
+static const char liq_histogram_magic[] = "liq_histogram";
+static const char liq_remapping_result_magic[] = "liq_remapping_result";
+static const char liq_freed_magic[] = "free";
+#define CHECK_STRUCT_TYPE(attr, kind) liq_crash_if_invalid_handle_pointer_given((const liq_attr*)attr, kind ## _magic)
+#define CHECK_USER_POINTER(ptr) liq_crash_if_invalid_pointer_given(ptr)
+
+struct liq_attr {
+ const char *magic_header;
+ void* (*malloc)(size_t);
+ void (*free)(void*);
+
+ double target_mse, max_mse, kmeans_iteration_limit;
+ unsigned int max_colors, max_histogram_entries;
+ unsigned int min_posterization_output /* user setting */, min_posterization_input /* speed setting */;
+ unsigned int kmeans_iterations, feedback_loop_trials;
+ bool last_index_transparent, use_contrast_maps;
+ unsigned char use_dither_map;
+ unsigned char speed;
+
+ unsigned char progress_stage1, progress_stage2, progress_stage3;
+ liq_progress_callback_function *progress_callback;
+ void *progress_callback_user_info;
+
+ liq_log_callback_function *log_callback;
+ void *log_callback_user_info;
+ liq_log_flush_callback_function *log_flush_callback;
+ void *log_flush_callback_user_info;
+};
+
+struct liq_result {
+ const char *magic_header;
+ void* (*malloc)(size_t);
+ void (*free)(void*);
+
+ liq_remapping_result *remapping;
+ colormap *palette;
+ liq_progress_callback_function *progress_callback;
+ void *progress_callback_user_info;
+
+ liq_palette int_palette;
+ float dither_level;
+ double gamma, palette_error;
+ int min_posterization_output;
+ unsigned char use_dither_map;
+};
+
+struct liq_histogram {
+ const char *magic_header;
+ void* (*malloc)(size_t);
+ void (*free)(void*);
+
+ struct acolorhash_table *acht;
+ double gamma;
+ f_pixel fixed_colors[256];
+ unsigned short fixed_colors_count;
+ unsigned short ignorebits;
+ bool had_image_added;
+};
+
+static void contrast_maps(liq_image *image) LIQ_NONNULL;
+static liq_error finalize_histogram(liq_histogram *input_hist, liq_attr *options, histogram **hist_output) LIQ_NONNULL;
+static const liq_color *liq_image_get_row_rgba(liq_image *input_image, unsigned int row) LIQ_NONNULL;
+static void liq_remapping_result_destroy(liq_remapping_result *result) LIQ_NONNULL;
+static liq_error pngquant_quantize(histogram *hist, const liq_attr *options, const int fixed_colors_count, const f_pixel fixed_colors[], const double gamma, bool fixed_result_colors, liq_result **) LIQ_NONNULL;
+static liq_error liq_histogram_quantize_internal(liq_histogram *input_hist, liq_attr *attr, bool fixed_result_colors, liq_result **result_output) LIQ_NONNULL;
+
+LIQ_NONNULL static void liq_verbose_printf(const liq_attr *context, const char *fmt, ...)
+{
+ if (context->log_callback) {
+ va_list va;
+ va_start(va, fmt);
+ int required_space = vsnprintf(NULL, 0, fmt, va)+1; // +\0
+ va_end(va);
+
+ LIQ_ARRAY(char, buf, required_space);
+ va_start(va, fmt);
+ vsnprintf(buf, required_space, fmt, va);
+ va_end(va);
+
+ context->log_callback(context, buf, context->log_callback_user_info);
+ }
+}
+
+LIQ_NONNULL inline static void verbose_print(const liq_attr *attr, const char *msg)
+{
+ if (attr->log_callback) {
+ attr->log_callback(attr, msg, attr->log_callback_user_info);
+ }
+}
+
+LIQ_NONNULL static void liq_verbose_printf_flush(liq_attr *attr)
+{
+ if (attr->log_flush_callback) {
+ attr->log_flush_callback(attr, attr->log_flush_callback_user_info);
+ }
+}
+
+LIQ_NONNULL static bool liq_progress(const liq_attr *attr, const float percent)
+{
+ return attr->progress_callback && !attr->progress_callback(percent, attr->progress_callback_user_info);
+}
+
+LIQ_PRIVATE LIQ_NONNULL bool liq_remap_progress(const liq_remapping_result *quant, const float percent)
+{
+ return quant->progress_callback && !quant->progress_callback(percent, quant->progress_callback_user_info);
+}
+
+#if USE_SSE
+inline static bool is_sse_available()
+{
+#if (defined(__x86_64__) || defined(__amd64) || defined(_WIN64))
+ return true;
+#elif _MSC_VER
+ int info[4];
+ __cpuid(info, 1);
+ /* bool is implemented as a built-in type of size 1 in MSVC */
+ return info[3] & (1<<26) ? true : false;
+#else
+ int a,b,c,d;
+ cpuid(1, a, b, c, d);
+ return d & (1<<25); // edx bit 25 is set when SSE is present
+#endif
+}
+#endif
+
+/* make it clear in backtrace when user-supplied handle points to invalid memory */
+NEVER_INLINE LIQ_EXPORT bool liq_crash_if_invalid_handle_pointer_given(const liq_attr *user_supplied_pointer, const char *const expected_magic_header);
+LIQ_EXPORT bool liq_crash_if_invalid_handle_pointer_given(const liq_attr *user_supplied_pointer, const char *const expected_magic_header)
+{
+ if (!user_supplied_pointer) {
+ return false;
+ }
+
+ if (user_supplied_pointer->magic_header == liq_freed_magic) {
+ fprintf(stderr, "%s used after being freed", expected_magic_header);
+ // this is not normal error handling, this is programmer error that should crash the program.
+ // program cannot safely continue if memory has been used after it's been freed.
+ // abort() is nasty, but security vulnerability may be worse.
+ abort();
+ }
+
+ return user_supplied_pointer->magic_header == expected_magic_header;
+}
+
+NEVER_INLINE LIQ_EXPORT bool liq_crash_if_invalid_pointer_given(const void *pointer);
+LIQ_EXPORT bool liq_crash_if_invalid_pointer_given(const void *pointer)
+{
+ if (!pointer) {
+ return false;
+ }
+ // Force a read from the given (potentially invalid) memory location in order to check early whether this crashes the program or not.
+ // It doesn't matter what value is read, the code here is just to shut the compiler up about unused read.
+ char test_access = *((volatile char *)pointer);
+ return test_access || true;
+}
+
+LIQ_NONNULL static void liq_log_error(const liq_attr *attr, const char *msg)
+{
+ if (!CHECK_STRUCT_TYPE(attr, liq_attr)) return;
+ liq_verbose_printf(attr, " error: %s", msg);
+}
+
+static double quality_to_mse(long quality)
+{
+ if (quality == 0) {
+ return MAX_DIFF;
+ }
+ if (quality == 100) {
+ return 0;
+ }
+
+ // curve fudged to be roughly similar to quality of libjpeg
+ // except lowest 10 for really low number of colors
+ const double extra_low_quality_fudge = MAX(0,0.016/(0.001+quality) - 0.001);
+ // LIQ_WEIGHT_MSE is a fudge factor - reminder that colors are not in 0..1 range any more
+ return LIQ_WEIGHT_MSE * (extra_low_quality_fudge + 2.5/pow(210.0 + quality, 1.2) * (100.1-quality)/100.0);
+}
+
+static unsigned int mse_to_quality(double mse)
+{
+ for(int i=100; i > 0; i--) {
+ if (mse <= quality_to_mse(i) + 0.000001) { // + epsilon for floating point errors
+ return i;
+ }
+ }
+ return 0;
+}
+
+/** internally MSE is a sum of all channels with pixels 0..1 range,
+ but other software gives per-RGB-channel MSE for 0..255 range */
+static double mse_to_standard_mse(double mse) {
+ return (mse * 65536.0/6.0) / LIQ_WEIGHT_MSE;
+}
+
+LIQ_EXPORT LIQ_NONNULL liq_error liq_set_quality(liq_attr* attr, int minimum, int target)
+{
+ if (!CHECK_STRUCT_TYPE(attr, liq_attr)) return LIQ_INVALID_POINTER;
+ if (target < 0 || target > 100 || target < minimum || minimum < 0) return LIQ_VALUE_OUT_OF_RANGE;
+
+ attr->target_mse = quality_to_mse(target);
+ attr->max_mse = quality_to_mse(minimum);
+ return LIQ_OK;
+}
+
+LIQ_EXPORT LIQ_NONNULL int liq_get_min_quality(const liq_attr *attr)
+{
+ if (!CHECK_STRUCT_TYPE(attr, liq_attr)) return -1;
+ return mse_to_quality(attr->max_mse);
+}
+
+LIQ_EXPORT LIQ_NONNULL int liq_get_max_quality(const liq_attr *attr)
+{
+ if (!CHECK_STRUCT_TYPE(attr, liq_attr)) return -1;
+ return mse_to_quality(attr->target_mse);
+}
+
+
+LIQ_EXPORT LIQ_NONNULL liq_error liq_set_max_colors(liq_attr* attr, int colors)
+{
+ if (!CHECK_STRUCT_TYPE(attr, liq_attr)) return LIQ_INVALID_POINTER;
+ if (colors < 2 || colors > 256) return LIQ_VALUE_OUT_OF_RANGE;
+
+ attr->max_colors = colors;
+ return LIQ_OK;
+}
+
+LIQ_EXPORT LIQ_NONNULL int liq_get_max_colors(const liq_attr *attr)
+{
+ if (!CHECK_STRUCT_TYPE(attr, liq_attr)) return -1;
+
+ return attr->max_colors;
+}
+
+LIQ_EXPORT LIQ_NONNULL liq_error liq_set_min_posterization(liq_attr *attr, int bits)
+{
+ if (!CHECK_STRUCT_TYPE(attr, liq_attr)) return LIQ_INVALID_POINTER;
+ if (bits < 0 || bits > 4) return LIQ_VALUE_OUT_OF_RANGE;
+
+ attr->min_posterization_output = bits;
+ return LIQ_OK;
+}
+
+LIQ_EXPORT LIQ_NONNULL int liq_get_min_posterization(const liq_attr *attr)
+{
+ if (!CHECK_STRUCT_TYPE(attr, liq_attr)) return -1;
+
+ return attr->min_posterization_output;
+}
+
+LIQ_EXPORT LIQ_NONNULL liq_error liq_set_speed(liq_attr* attr, int speed)
+{
+ if (!CHECK_STRUCT_TYPE(attr, liq_attr)) return LIQ_INVALID_POINTER;
+ if (speed < 1 || speed > 10) return LIQ_VALUE_OUT_OF_RANGE;
+
+ unsigned int iterations = MAX(8-speed, 0);
+ iterations += iterations * iterations/2;
+ attr->kmeans_iterations = iterations;
+ attr->kmeans_iteration_limit = 1.0/(double)(1<<(23-speed));
+ attr->feedback_loop_trials = MAX(56-9*speed, 0);
+
+ attr->max_histogram_entries = (1<<17) + (1<<18)*(10-speed);
+ attr->min_posterization_input = (speed >= 8) ? 1 : 0;
+ attr->use_dither_map = (speed <= (omp_get_max_threads() > 1 ? 7 : 5)); // parallelized dither map might speed up floyd remapping
+ if (attr->use_dither_map && speed < 3) {
+ attr->use_dither_map = 2; // always
+ }
+ attr->use_contrast_maps = (speed <= 7) || attr->use_dither_map;
+ attr->speed = speed;
+
+ attr->progress_stage1 = attr->use_contrast_maps ? 20 : 8;
+ if (attr->feedback_loop_trials < 2) {
+ attr->progress_stage1 += 30;
+ }
+ attr->progress_stage3 = 50 / (1+speed);
+ attr->progress_stage2 = 100 - attr->progress_stage1 - attr->progress_stage3;
+ return LIQ_OK;
+}
+
+LIQ_EXPORT LIQ_NONNULL int liq_get_speed(const liq_attr *attr)
+{
+ if (!CHECK_STRUCT_TYPE(attr, liq_attr)) return -1;
+
+ return attr->speed;
+}
+
+LIQ_EXPORT LIQ_NONNULL liq_error liq_set_output_gamma(liq_result* res, double gamma)
+{
+ if (!CHECK_STRUCT_TYPE(res, liq_result)) return LIQ_INVALID_POINTER;
+ if (gamma <= 0 || gamma >= 1.0) return LIQ_VALUE_OUT_OF_RANGE;
+
+ if (res->remapping) {
+ liq_remapping_result_destroy(res->remapping);
+ res->remapping = NULL;
+ }
+
+ res->gamma = gamma;
+ return LIQ_OK;
+}
+
+LIQ_EXPORT LIQ_NONNULL liq_error liq_set_min_opacity(liq_attr* attr, int min)
+{
+ return LIQ_OK;
+}
+
+LIQ_EXPORT LIQ_NONNULL int liq_get_min_opacity(const liq_attr *attr)
+{
+ return 0;
+}
+
+LIQ_EXPORT LIQ_NONNULL void liq_set_last_index_transparent(liq_attr* attr, int is_last)
+{
+ if (!CHECK_STRUCT_TYPE(attr, liq_attr)) return;
+
+ attr->last_index_transparent = !!is_last;
+}
+
+LIQ_EXPORT void liq_attr_set_progress_callback(liq_attr *attr, liq_progress_callback_function *callback, void *user_info)
+{
+ if (!CHECK_STRUCT_TYPE(attr, liq_attr)) return;
+
+ attr->progress_callback = callback;
+ attr->progress_callback_user_info = user_info;
+}
+
+LIQ_EXPORT void liq_result_set_progress_callback(liq_result *result, liq_progress_callback_function *callback, void *user_info)
+{
+ if (!CHECK_STRUCT_TYPE(result, liq_result)) return;
+
+ result->progress_callback = callback;
+ result->progress_callback_user_info = user_info;
+}
+
+LIQ_EXPORT void liq_set_log_callback(liq_attr *attr, liq_log_callback_function *callback, void* user_info)
+{
+ if (!CHECK_STRUCT_TYPE(attr, liq_attr)) return;
+
+ liq_verbose_printf_flush(attr);
+ attr->log_callback = callback;
+ attr->log_callback_user_info = user_info;
+}
+
+LIQ_EXPORT void liq_set_log_flush_callback(liq_attr *attr, liq_log_flush_callback_function *callback, void* user_info)
+{
+ if (!CHECK_STRUCT_TYPE(attr, liq_attr)) return;
+
+ attr->log_flush_callback = callback;
+ attr->log_flush_callback_user_info = user_info;
+}
+
+LIQ_EXPORT liq_attr* liq_attr_create()
+{
+ return liq_attr_create_with_allocator(NULL, NULL);
+}
+
+LIQ_EXPORT LIQ_NONNULL void liq_attr_destroy(liq_attr *attr)
+{
+ if (!CHECK_STRUCT_TYPE(attr, liq_attr)) {
+ return;
+ }
+
+ liq_verbose_printf_flush(attr);
+
+ attr->magic_header = liq_freed_magic;
+ attr->free(attr);
+}
+
+LIQ_EXPORT LIQ_NONNULL liq_attr* liq_attr_copy(const liq_attr *orig)
+{
+ if (!CHECK_STRUCT_TYPE(orig, liq_attr)) {
+ return NULL;
+ }
+
+ liq_attr *attr = orig->malloc(sizeof(liq_attr));
+ if (!attr) return NULL;
+ *attr = *orig;
+ return attr;
+}
+
+static void *liq_aligned_malloc(size_t size)
+{
+ unsigned char *ptr = malloc(size + 16);
+ if (!ptr) {
+ return NULL;
+ }
+
+ uintptr_t offset = 16 - ((uintptr_t)ptr & 15); // also reserves 1 byte for ptr[-1]
+ ptr += offset;
+ assert(0 == (((uintptr_t)ptr) & 15));
+ ptr[-1] = offset ^ 0x59; // store how much pointer was shifted to get the original for free()
+ return ptr;
+}
+
+LIQ_NONNULL static void liq_aligned_free(void *inptr)
+{
+ unsigned char *ptr = inptr;
+ size_t offset = ptr[-1] ^ 0x59;
+ assert(offset > 0 && offset <= 16);
+ free(ptr - offset);
+}
+
+LIQ_EXPORT liq_attr* liq_attr_create_with_allocator(void* (*custom_malloc)(size_t), void (*custom_free)(void*))
+{
+#if USE_SSE
+ if (!is_sse_available()) {
+ return NULL;
+ }
+#endif
+ if (!custom_malloc && !custom_free) {
+ custom_malloc = liq_aligned_malloc;
+ custom_free = liq_aligned_free;
+ } else if (!custom_malloc != !custom_free) {
+ return NULL; // either specify both or none
+ }
+
+ liq_attr *attr = custom_malloc(sizeof(liq_attr));
+ if (!attr) return NULL;
+ *attr = (liq_attr) {
+ .magic_header = liq_attr_magic,
+ .malloc = custom_malloc,
+ .free = custom_free,
+ .max_colors = 256,
+ .last_index_transparent = false, // puts transparent color at last index. This is workaround for blu-ray subtitles.
+ .target_mse = 0,
+ .max_mse = MAX_DIFF,
+ };
+ liq_set_speed(attr, 4);
+ return attr;
+}
+
+LIQ_EXPORT LIQ_NONNULL liq_error liq_image_add_fixed_color(liq_image *img, liq_color color)
+{
+ if (!CHECK_STRUCT_TYPE(img, liq_image)) return LIQ_INVALID_POINTER;
+ if (img->fixed_colors_count > 255) return LIQ_UNSUPPORTED;
+
+ float gamma_lut[256];
+ to_f_set_gamma(gamma_lut, img->gamma);
+ img->fixed_colors[img->fixed_colors_count++] = rgba_to_f(gamma_lut, (liq_color){
+ .r = color.r,
+ .g = color.g,
+ .b = color.b,
+ .a = color.a,
+ });
+ return LIQ_OK;
+}
+
+LIQ_NONNULL static liq_error liq_histogram_add_fixed_color_f(liq_histogram *hist, f_pixel color)
+{
+ if (hist->fixed_colors_count > 255) return LIQ_UNSUPPORTED;
+
+ hist->fixed_colors[hist->fixed_colors_count++] = color;
+ return LIQ_OK;
+}
+
+LIQ_EXPORT LIQ_NONNULL liq_error liq_histogram_add_fixed_color(liq_histogram *hist, liq_color color, double gamma)
+{
+ if (!CHECK_STRUCT_TYPE(hist, liq_histogram)) return LIQ_INVALID_POINTER;
+
+ float gamma_lut[256];
+ to_f_set_gamma(gamma_lut, gamma ? gamma : 0.45455);
+ const f_pixel px = rgba_to_f(gamma_lut, (liq_color){
+ .r = color.r,
+ .g = color.g,
+ .b = color.b,
+ .a = color.a,
+ });
+ return liq_histogram_add_fixed_color_f(hist, px);
+}
+
+LIQ_NONNULL static bool liq_image_use_low_memory(liq_image *img)
+{
+ if (img->temp_f_row) {
+ img->free(img->temp_f_row);
+ }
+ img->temp_f_row = img->malloc(sizeof(img->f_pixels[0]) * LIQ_TEMP_ROW_WIDTH(img->width) * omp_get_max_threads());
+ return img->temp_f_row != NULL;
+}
+
+LIQ_NONNULL static bool liq_image_should_use_low_memory(liq_image *img, const bool low_memory_hint)
+{
+ return (size_t)img->width * (size_t)img->height > (low_memory_hint ? LIQ_HIGH_MEMORY_LIMIT/8 : LIQ_HIGH_MEMORY_LIMIT) / sizeof(f_pixel); // Watch out for integer overflow
+}
+
+static liq_image *liq_image_create_internal(const liq_attr *attr, liq_color* rows[], liq_image_get_rgba_row_callback *row_callback, void *row_callback_user_info, int width, int height, double gamma)
+{
+ if (gamma < 0 || gamma > 1.0) {
+ liq_log_error(attr, "gamma must be >= 0 and <= 1 (try 1/gamma instead)");
+ return NULL;
+ }
+
+ if (!rows && !row_callback) {
+ liq_log_error(attr, "missing row data");
+ return NULL;
+ }
+
+ liq_image *img = attr->malloc(sizeof(liq_image));
+ if (!img) return NULL;
+ *img = (liq_image){
+ .magic_header = liq_image_magic,
+ .malloc = attr->malloc,
+ .free = attr->free,
+ .width = width, .height = height,
+ .gamma = gamma ? gamma : 0.45455,
+ .rows = rows,
+ .row_callback = row_callback,
+ .row_callback_user_info = row_callback_user_info,
+ };
+
+ if (!rows) {
+ img->temp_row = attr->malloc(sizeof(img->temp_row[0]) * LIQ_TEMP_ROW_WIDTH(width) * omp_get_max_threads());
+ if (!img->temp_row) return NULL;
+ }
+
+ // if image is huge or converted pixels are not likely to be reused then don't cache converted pixels
+ if (liq_image_should_use_low_memory(img, !img->temp_row && !attr->use_contrast_maps && !attr->use_dither_map)) {
+ verbose_print(attr, " conserving memory");
+ if (!liq_image_use_low_memory(img)) return NULL;
+ }
+
+ return img;
+}
+
+LIQ_EXPORT LIQ_NONNULL liq_error liq_image_set_memory_ownership(liq_image *img, int ownership_flags)
+{
+ if (!CHECK_STRUCT_TYPE(img, liq_image)) return LIQ_INVALID_POINTER;
+ if (!img->rows || !ownership_flags || (ownership_flags & ~(LIQ_OWN_ROWS|LIQ_OWN_PIXELS))) {
+ return LIQ_VALUE_OUT_OF_RANGE;
+ }
+
+ if (ownership_flags & LIQ_OWN_ROWS) {
+ if (img->free_rows_internal) return LIQ_VALUE_OUT_OF_RANGE;
+ img->free_rows = true;
+ }
+
+ if (ownership_flags & LIQ_OWN_PIXELS) {
+ img->free_pixels = true;
+ if (!img->pixels) {
+ // for simplicity of this API there's no explicit bitmap argument,
+ // so the row with the lowest address is assumed to be at the start of the bitmap
+ img->pixels = img->rows[0];
+ for(unsigned int i=1; i < img->height; i++) {
+ img->pixels = MIN(img->pixels, img->rows[i]);
+ }
+ }
+ }
+
+ return LIQ_OK;
+}
+
+LIQ_NONNULL static void liq_image_free_maps(liq_image *input_image);
+LIQ_NONNULL static void liq_image_free_dither_map(liq_image *input_image);
+LIQ_NONNULL static void liq_image_free_importance_map(liq_image *input_image);
+
+LIQ_EXPORT LIQ_NONNULL liq_error liq_image_set_importance_map(liq_image *img, unsigned char importance_map[], size_t buffer_size, enum liq_ownership ownership) {
+ if (!CHECK_STRUCT_TYPE(img, liq_image)) return LIQ_INVALID_POINTER;
+ if (!CHECK_USER_POINTER(importance_map)) return LIQ_INVALID_POINTER;
+
+ const size_t required_size = (size_t)img->width * (size_t)img->height;
+ if (buffer_size < required_size) {
+ return LIQ_BUFFER_TOO_SMALL;
+ }
+
+ if (ownership == LIQ_COPY_PIXELS) {
+ unsigned char *tmp = img->malloc(required_size);
+ if (!tmp) {
+ return LIQ_OUT_OF_MEMORY;
+ }
+ memcpy(tmp, importance_map, required_size);
+ importance_map = tmp;
+ } else if (ownership != LIQ_OWN_PIXELS) {
+ return LIQ_UNSUPPORTED;
+ }
+
+ liq_image_free_importance_map(img);
+ img->importance_map = importance_map;
+
+ return LIQ_OK;
+}
+
+LIQ_EXPORT LIQ_NONNULL liq_error liq_image_set_background(liq_image *img, liq_image *background)
+{
+ if (!CHECK_STRUCT_TYPE(img, liq_image)) return LIQ_INVALID_POINTER;
+ if (!CHECK_STRUCT_TYPE(background, liq_image)) return LIQ_INVALID_POINTER;
+
+ if (background->background) {
+ return LIQ_UNSUPPORTED;
+ }
+ if (img->width != background->width || img->height != background->height) {
+ return LIQ_BUFFER_TOO_SMALL;
+ }
+
+ if (img->background) {
+ liq_image_destroy(img->background);
+ }
+
+ img->background = background;
+ liq_image_free_dither_map(img); // Force it to be re-analyzed with the background
+
+ return LIQ_OK;
+}
+
+LIQ_NONNULL static bool check_image_size(const liq_attr *attr, const int width, const int height)
+{
+ if (!CHECK_STRUCT_TYPE(attr, liq_attr)) {
+ return false;
+ }
+
+ if (width <= 0 || height <= 0) {
+ liq_log_error(attr, "width and height must be > 0");
+ return false;
+ }
+
+ if (width > INT_MAX/sizeof(liq_color)/height || width > INT_MAX/16/sizeof(f_pixel) || height > INT_MAX/sizeof(size_t)) {
+ liq_log_error(attr, "image too large");
+ return false;
+ }
+ return true;
+}
+
+LIQ_EXPORT liq_image *liq_image_create_custom(const liq_attr *attr, liq_image_get_rgba_row_callback *row_callback, void* user_info, int width, int height, double gamma)
+{
+ if (!check_image_size(attr, width, height)) {
+ return NULL;
+ }
+ return liq_image_create_internal(attr, NULL, row_callback, user_info, width, height, gamma);
+}
+
+LIQ_EXPORT liq_image *liq_image_create_rgba_rows(const liq_attr *attr, void *const rows[], int width, int height, double gamma)
+{
+ if (!check_image_size(attr, width, height)) {
+ return NULL;
+ }
+
+ for(int i=0; i < height; i++) {
+ if (!CHECK_USER_POINTER(rows+i) || !CHECK_USER_POINTER(rows[i])) {
+ liq_log_error(attr, "invalid row pointers");
+ return NULL;
+ }
+ }
+ return liq_image_create_internal(attr, (liq_color**)rows, NULL, NULL, width, height, gamma);
+}
+
+LIQ_EXPORT LIQ_NONNULL liq_image *liq_image_create_rgba(const liq_attr *attr, const void* bitmap, int width, int height, double gamma)
+{
+ if (!check_image_size(attr, width, height)) {
+ return NULL;
+ }
+ if (!CHECK_USER_POINTER(bitmap)) {
+ liq_log_error(attr, "invalid bitmap pointer");
+ return NULL;
+ }
+
+ liq_color *const pixels = (liq_color *const)bitmap;
+ liq_color **rows = attr->malloc(sizeof(rows[0])*height);
+ if (!rows) return NULL;
+
+ for(int i=0; i < height; i++) {
+ rows[i] = pixels + width * i;
+ }
+
+ liq_image *image = liq_image_create_internal(attr, rows, NULL, NULL, width, height, gamma);
+ if (!image) {
+ attr->free(rows);
+ return NULL;
+ }
+ image->free_rows = true;
+ image->free_rows_internal = true;
+ return image;
+}
+
+NEVER_INLINE LIQ_EXPORT void liq_executing_user_callback(liq_image_get_rgba_row_callback *callback, liq_color *temp_row, int row, int width, void *user_info);
+LIQ_EXPORT void liq_executing_user_callback(liq_image_get_rgba_row_callback *callback, liq_color *temp_row, int row, int width, void *user_info)
+{
+ assert(callback);
+ assert(temp_row);
+ callback(temp_row, row, width, user_info);
+}
+
+LIQ_NONNULL inline static bool liq_image_has_rgba_pixels(const liq_image *img)
+{
+ if (!CHECK_STRUCT_TYPE(img, liq_image)) {
+ return false;
+ }
+ return img->rows || (img->temp_row && img->row_callback);
+}
+
+LIQ_NONNULL inline static bool liq_image_can_use_rgba_rows(const liq_image *img)
+{
+ assert(liq_image_has_rgba_pixels(img));
+ return img->rows;
+}
+
+LIQ_NONNULL static const liq_color *liq_image_get_row_rgba(liq_image *img, unsigned int row)
+{
+ if (liq_image_can_use_rgba_rows(img)) {
+ return img->rows[row];
+ }
+
+ assert(img->temp_row);
+ liq_color *temp_row = img->temp_row + LIQ_TEMP_ROW_WIDTH(img->width) * omp_get_thread_num();
+ if (img->rows) {
+ memcpy(temp_row, img->rows[row], img->width * sizeof(temp_row[0]));
+ } else {
+ liq_executing_user_callback(img->row_callback, (liq_color*)temp_row, row, img->width, img->row_callback_user_info);
+ }
+
+ return temp_row;
+}
+
+LIQ_NONNULL static void convert_row_to_f(liq_image *img, f_pixel *row_f_pixels, const unsigned int row, const float gamma_lut[])
+{
+ assert(row_f_pixels);
+ assert(!USE_SSE || 0 == ((uintptr_t)row_f_pixels & 15));
+
+ const liq_color *const row_pixels = liq_image_get_row_rgba(img, row);
+
+ for(unsigned int col=0; col < img->width; col++) {
+ row_f_pixels[col] = rgba_to_f(gamma_lut, row_pixels[col]);
+ }
+}
+
+LIQ_PRIVATE LIQ_NONNULL bool liq_image_get_row_f_init(liq_image *img)
+{
+ assert(omp_get_thread_num() == 0);
+ if (img->f_pixels) {
+ return true;
+ }
+ if (!liq_image_should_use_low_memory(img, false)) {
+ img->f_pixels = img->malloc(sizeof(img->f_pixels[0]) * img->width * img->height);
+ }
+ if (!img->f_pixels) {
+ return liq_image_use_low_memory(img);
+ }
+
+ if (!liq_image_has_rgba_pixels(img)) {
+ return false;
+ }
+
+ float gamma_lut[256];
+ to_f_set_gamma(gamma_lut, img->gamma);
+ for(unsigned int i=0; i < img->height; i++) {
+ convert_row_to_f(img, &img->f_pixels[i*img->width], i, gamma_lut);
+ }
+ return true;
+}
+
+LIQ_PRIVATE LIQ_NONNULL const f_pixel *liq_image_get_row_f(liq_image *img, unsigned int row)
+{
+ if (!img->f_pixels) {
+ assert(img->temp_f_row); // init should have done that
+ float gamma_lut[256];
+ to_f_set_gamma(gamma_lut, img->gamma);
+ f_pixel *row_for_thread = img->temp_f_row + LIQ_TEMP_ROW_WIDTH(img->width) * omp_get_thread_num();
+ convert_row_to_f(img, row_for_thread, row, gamma_lut);
+ return row_for_thread;
+ }
+ return img->f_pixels + img->width * row;
+}
+
+LIQ_EXPORT LIQ_NONNULL int liq_image_get_width(const liq_image *input_image)
+{
+ if (!CHECK_STRUCT_TYPE(input_image, liq_image)) return -1;
+ return input_image->width;
+}
+
+LIQ_EXPORT LIQ_NONNULL int liq_image_get_height(const liq_image *input_image)
+{
+ if (!CHECK_STRUCT_TYPE(input_image, liq_image)) return -1;
+ return input_image->height;
+}
+
+typedef void free_func(void*);
+
+LIQ_NONNULL static free_func *get_default_image_free_func(liq_image *img)
+{
+ // When default allocator is used then user-supplied pointers must be freed with free()
+ if (img->free != liq_aligned_free) {
+ return img->free;
+ }
+ return free;
+}
+
+LIQ_NONNULL static free_func *get_default_rows_free_func(liq_image *img)
+{
+ // When default allocator is used then user-supplied pointers must be freed with free()
+ if (img->free_rows_internal || img->free != liq_aligned_free) {
+ return img->free;
+ }
+ return free;
+}
+
+LIQ_NONNULL static void liq_image_free_rgba_source(liq_image *input_image)
+{
+ if (input_image->free_pixels && input_image->pixels) {
+ get_default_image_free_func(input_image)(input_image->pixels);
+ input_image->pixels = NULL;
+ }
+
+ if (input_image->free_rows && input_image->rows) {
+ get_default_rows_free_func(input_image)(input_image->rows);
+ input_image->rows = NULL;
+ }
+}
+
+LIQ_NONNULL static void liq_image_free_importance_map(liq_image *input_image) {
+ if (input_image->importance_map) {
+ input_image->free(input_image->importance_map);
+ input_image->importance_map = NULL;
+ }
+}
+
+LIQ_NONNULL static void liq_image_free_maps(liq_image *input_image) {
+ liq_image_free_importance_map(input_image);
+
+ if (input_image->edges) {
+ input_image->free(input_image->edges);
+ input_image->edges = NULL;
+ }
+ liq_image_free_dither_map(input_image);
+}
+
+LIQ_NONNULL static void liq_image_free_dither_map(liq_image *input_image) {
+ if (input_image->dither_map) {
+ input_image->free(input_image->dither_map);
+ input_image->dither_map = NULL;
+ }
+}
+
+LIQ_EXPORT LIQ_NONNULL void liq_image_destroy(liq_image *input_image)
+{
+ if (!CHECK_STRUCT_TYPE(input_image, liq_image)) return;
+
+ liq_image_free_rgba_source(input_image);
+
+ liq_image_free_maps(input_image);
+
+ if (input_image->f_pixels) {
+ input_image->free(input_image->f_pixels);
+ }
+
+ if (input_image->temp_row) {
+ input_image->free(input_image->temp_row);
+ }
+
+ if (input_image->temp_f_row) {
+ input_image->free(input_image->temp_f_row);
+ }
+
+ if (input_image->background) {
+ liq_image_destroy(input_image->background);
+ }
+
+ input_image->magic_header = liq_freed_magic;
+ input_image->free(input_image);
+}
+
+LIQ_EXPORT liq_histogram* liq_histogram_create(const liq_attr* attr)
+{
+ if (!CHECK_STRUCT_TYPE(attr, liq_attr)) {
+ return NULL;
+ }
+
+ liq_histogram *hist = attr->malloc(sizeof(liq_histogram));
+ if (!hist) return NULL;
+ *hist = (liq_histogram) {
+ .magic_header = liq_histogram_magic,
+ .malloc = attr->malloc,
+ .free = attr->free,
+
+ .ignorebits = MAX(attr->min_posterization_output, attr->min_posterization_input),
+ };
+ return hist;
+}
+
+LIQ_EXPORT LIQ_NONNULL void liq_histogram_destroy(liq_histogram *hist)
+{
+ if (!CHECK_STRUCT_TYPE(hist, liq_histogram)) return;
+ hist->magic_header = liq_freed_magic;
+
+ pam_freeacolorhash(hist->acht);
+ hist->free(hist);
+}
+
+LIQ_EXPORT LIQ_NONNULL liq_result *liq_quantize_image(liq_attr *attr, liq_image *img)
+{
+ liq_result *res;
+ if (LIQ_OK != liq_image_quantize(img, attr, &res)) {
+ return NULL;
+ }
+ return res;
+}
+
+LIQ_EXPORT LIQ_NONNULL liq_error liq_image_quantize(liq_image *const img, liq_attr *const attr, liq_result **result_output)
+{
+ if (!CHECK_STRUCT_TYPE(attr, liq_attr)) return LIQ_INVALID_POINTER;
+ if (!liq_image_has_rgba_pixels(img)) {
+ return LIQ_UNSUPPORTED;
+ }
+
+ liq_histogram *hist = liq_histogram_create(attr);
+ if (!hist) {
+ return LIQ_OUT_OF_MEMORY;
+ }
+ liq_error err = liq_histogram_add_image(hist, attr, img);
+ if (LIQ_OK != err) {
+ liq_histogram_destroy(hist);
+ return err;
+ }
+
+ err = liq_histogram_quantize_internal(hist, attr, false, result_output);
+ liq_histogram_destroy(hist);
+
+ return err;
+}
+
+LIQ_EXPORT LIQ_NONNULL liq_error liq_histogram_quantize(liq_histogram *input_hist, liq_attr *attr, liq_result **result_output) {
+ return liq_histogram_quantize_internal(input_hist, attr, true, result_output);
+}
+
+LIQ_NONNULL static liq_error liq_histogram_quantize_internal(liq_histogram *input_hist, liq_attr *attr, bool fixed_result_colors, liq_result **result_output)
+{
+ if (!CHECK_USER_POINTER(result_output)) return LIQ_INVALID_POINTER;
+ *result_output = NULL;
+
+ if (!CHECK_STRUCT_TYPE(attr, liq_attr)) return LIQ_INVALID_POINTER;
+ if (!CHECK_STRUCT_TYPE(input_hist, liq_histogram)) return LIQ_INVALID_POINTER;
+
+ if (liq_progress(attr, 0)) return LIQ_ABORTED;
+
+ histogram *hist;
+ liq_error err = finalize_histogram(input_hist, attr, &hist);
+ if (err != LIQ_OK) {
+ return err;
+ }
+
+ err = pngquant_quantize(hist, attr, input_hist->fixed_colors_count, input_hist->fixed_colors, input_hist->gamma, fixed_result_colors, result_output);
+ pam_freeacolorhist(hist);
+
+ return err;
+}
+
+LIQ_EXPORT LIQ_NONNULL liq_error liq_set_dithering_level(liq_result *res, float dither_level)
+{
+ if (!CHECK_STRUCT_TYPE(res, liq_result)) return LIQ_INVALID_POINTER;
+
+ if (res->remapping) {
+ liq_remapping_result_destroy(res->remapping);
+ res->remapping = NULL;
+ }
+
+ if (dither_level < 0 || dither_level > 1.0f) return LIQ_VALUE_OUT_OF_RANGE;
+ res->dither_level = dither_level;
+ return LIQ_OK;
+}
+
+LIQ_NONNULL static liq_remapping_result *liq_remapping_result_create(liq_result *result)
+{
+ if (!CHECK_STRUCT_TYPE(result, liq_result)) {
+ return NULL;
+ }
+
+ liq_remapping_result *res = result->malloc(sizeof(liq_remapping_result));
+ if (!res) return NULL;
+ *res = (liq_remapping_result) {
+ .magic_header = liq_remapping_result_magic,
+ .malloc = result->malloc,
+ .free = result->free,
+ .dither_level = result->dither_level,
+ .use_dither_map = result->use_dither_map,
+ .palette_error = result->palette_error,
+ .gamma = result->gamma,
+ .palette = pam_duplicate_colormap(result->palette),
+ .progress_callback = result->progress_callback,
+ .progress_callback_user_info = result->progress_callback_user_info,
+ .progress_stage1 = result->use_dither_map ? 20 : 0,
+ };
+ return res;
+}
+
+LIQ_EXPORT LIQ_NONNULL double liq_get_output_gamma(const liq_result *result)
+{
+ if (!CHECK_STRUCT_TYPE(result, liq_result)) return -1;
+
+ return result->gamma;
+}
+
+LIQ_NONNULL static void liq_remapping_result_destroy(liq_remapping_result *result)
+{
+ if (!CHECK_STRUCT_TYPE(result, liq_remapping_result)) return;
+
+ if (result->palette) pam_freecolormap(result->palette);
+ if (result->pixels) result->free(result->pixels);
+
+ result->magic_header = liq_freed_magic;
+ result->free(result);
+}
+
+LIQ_EXPORT LIQ_NONNULL void liq_result_destroy(liq_result *res)
+{
+ if (!CHECK_STRUCT_TYPE(res, liq_result)) return;
+
+ memset(&res->int_palette, 0, sizeof(liq_palette));
+
+ if (res->remapping) {
+ memset(&res->remapping->int_palette, 0, sizeof(liq_palette));
+ liq_remapping_result_destroy(res->remapping);
+ }
+
+ pam_freecolormap(res->palette);
+
+ res->magic_header = liq_freed_magic;
+ res->free(res);
+}
+
+
+LIQ_EXPORT LIQ_NONNULL double liq_get_quantization_error(const liq_result *result) {
+ if (!CHECK_STRUCT_TYPE(result, liq_result)) return -1;
+
+ if (result->palette_error >= 0) {
+ return mse_to_standard_mse(result->palette_error);
+ }
+
+ return -1;
+}
+
+LIQ_EXPORT LIQ_NONNULL double liq_get_remapping_error(const liq_result *result) {
+ if (!CHECK_STRUCT_TYPE(result, liq_result)) return -1;
+
+ if (result->remapping && result->remapping->palette_error >= 0) {
+ return mse_to_standard_mse(result->remapping->palette_error);
+ }
+
+ return -1;
+}
+
+LIQ_EXPORT LIQ_NONNULL int liq_get_quantization_quality(const liq_result *result) {
+ if (!CHECK_STRUCT_TYPE(result, liq_result)) return -1;
+
+ if (result->palette_error >= 0) {
+ return mse_to_quality(result->palette_error);
+ }
+
+ return -1;
+}
+
+LIQ_EXPORT LIQ_NONNULL int liq_get_remapping_quality(const liq_result *result) {
+ if (!CHECK_STRUCT_TYPE(result, liq_result)) return -1;
+
+ if (result->remapping && result->remapping->palette_error >= 0) {
+ return mse_to_quality(result->remapping->palette_error);
+ }
+
+ return -1;
+}
+
+LIQ_NONNULL static int compare_popularity(const void *ch1, const void *ch2)
+{
+ const float v1 = ((const colormap_item*)ch1)->popularity;
+ const float v2 = ((const colormap_item*)ch2)->popularity;
+ return v1 > v2 ? -1 : 1;
+}
+
+LIQ_NONNULL static void sort_palette_qsort(colormap *map, int start, int nelem)
+{
+ if (!nelem) return;
+ qsort(map->palette + start, nelem, sizeof(map->palette[0]), compare_popularity);
+}
+
+#define SWAP_PALETTE(map, a,b) { \
+ const colormap_item tmp = (map)->palette[(a)]; \
+ (map)->palette[(a)] = (map)->palette[(b)]; \
+ (map)->palette[(b)] = tmp; }
+
+LIQ_NONNULL static void sort_palette(colormap *map, const liq_attr *options)
+{
+ /*
+ ** Step 3.5 [GRR]: remap the palette colors so that all entries with
+ ** the maximal alpha value (i.e., fully opaque) are at the end and can
+ ** therefore be omitted from the tRNS chunk.
+ */
+ if (options->last_index_transparent) {
+ for(unsigned int i=0; i < map->colors; i++) {
+ if (map->palette[i].acolor.a < MIN_OPAQUE_A) {
+ const unsigned int old = i, transparent_dest = map->colors-1;
+
+ SWAP_PALETTE(map, transparent_dest, old);
+
+ /* colors sorted by popularity make pngs slightly more compressible */
+ sort_palette_qsort(map, 0, map->colors-1);
+ return;
+ }
+ }
+ }
+
+ unsigned int non_fixed_colors = 0;
+ for(unsigned int i = 0; i < map->colors; i++) {
+ if (map->palette[i].fixed) {
+ break;
+ }
+ non_fixed_colors++;
+ }
+
+ /* move transparent colors to the beginning to shrink trns chunk */
+ unsigned int num_transparent = 0;
+ for(unsigned int i = 0; i < non_fixed_colors; i++) {
+ if (map->palette[i].acolor.a < 255.f/256.f * LIQ_WEIGHT_A) {
+ // current transparent color is swapped with earlier opaque one
+ if (i != num_transparent) {
+ SWAP_PALETTE(map, num_transparent, i);
+ i--;
+ }
+ num_transparent++;
+ }
+ }
+
+ liq_verbose_printf(options, " eliminated opaque tRNS-chunk entries...%d entr%s transparent", num_transparent, (num_transparent == 1)? "y" : "ies");
+
+ /* colors sorted by popularity make pngs slightly more compressible
+ * opaque and transparent are sorted separately
+ */
+ sort_palette_qsort(map, 0, num_transparent);
+ sort_palette_qsort(map, num_transparent, non_fixed_colors - num_transparent);
+
+ if (non_fixed_colors > 9 && map->colors > 16) {
+ SWAP_PALETTE(map, 7, 1); // slightly improves compression
+ SWAP_PALETTE(map, 8, 2);
+ SWAP_PALETTE(map, 9, 3);
+ }
+}
+
+inline static unsigned int posterize_channel(unsigned int color, unsigned int bits)
+{
+ return (color & ~((1<> (8-bits));
+}
+
+LIQ_NONNULL static void set_rounded_palette(liq_palette *const dest, colormap *const map, const double gamma, unsigned int posterize)
+{
+ float gamma_lut[256];
+ to_f_set_gamma(gamma_lut, gamma);
+
+ dest->count = map->colors;
+ for(unsigned int x = 0; x < map->colors; ++x) {
+ liq_color px = f_to_rgb(gamma, map->palette[x].acolor);
+
+ px.r = posterize_channel(px.r, posterize);
+ px.g = posterize_channel(px.g, posterize);
+ px.b = posterize_channel(px.b, posterize);
+ px.a = posterize_channel(px.a, posterize);
+
+ map->palette[x].acolor = rgba_to_f(gamma_lut, px); /* saves rounding error introduced by to_rgb, which makes remapping & dithering more accurate */
+
+ if (!px.a && !map->palette[x].fixed) {
+ px.r = 71; px.g = 112; px.b = 76;
+ }
+
+ dest->entries[x] = (liq_color){.r=px.r,.g=px.g,.b=px.b,.a=px.a};
+ }
+}
+
+LIQ_EXPORT LIQ_NONNULL const liq_palette *liq_get_palette(liq_result *result)
+{
+ if (!CHECK_STRUCT_TYPE(result, liq_result)) return NULL;
+
+ if (result->remapping && result->remapping->int_palette.count) {
+ return &result->remapping->int_palette;
+ }
+
+ if (!result->int_palette.count) {
+ set_rounded_palette(&result->int_palette, result->palette, result->gamma, result->min_posterization_output);
+ }
+ return &result->int_palette;
+}
+
+LIQ_EXPORT LIQ_NONNULL liq_error liq_histogram_add_colors(liq_histogram *input_hist, const liq_attr *options, const liq_histogram_entry entries[], int num_entries, double gamma)
+{
+ if (!CHECK_STRUCT_TYPE(options, liq_attr)) return LIQ_INVALID_POINTER;
+ if (!CHECK_STRUCT_TYPE(input_hist, liq_histogram)) return LIQ_INVALID_POINTER;
+ if (!CHECK_USER_POINTER(entries)) return LIQ_INVALID_POINTER;
+ if (gamma < 0 || gamma >= 1.0) return LIQ_VALUE_OUT_OF_RANGE;
+ if (num_entries <= 0 || num_entries > 1<<30) return LIQ_VALUE_OUT_OF_RANGE;
+
+ if (input_hist->ignorebits > 0 && input_hist->had_image_added) {
+ return LIQ_UNSUPPORTED;
+ }
+ input_hist->ignorebits = 0;
+
+ input_hist->had_image_added = true;
+ input_hist->gamma = gamma ? gamma : 0.45455;
+
+ if (!input_hist->acht) {
+ input_hist->acht = pam_allocacolorhash(~0, num_entries*num_entries, 0, options->malloc, options->free);
+ if (!input_hist->acht) {
+ return LIQ_OUT_OF_MEMORY;
+ }
+ }
+ // Fake image size. It's only for hash size estimates.
+ if (!input_hist->acht->cols) {
+ input_hist->acht->cols = num_entries;
+ }
+ input_hist->acht->rows += num_entries;
+
+ const unsigned int hash_size = input_hist->acht->hash_size;
+ for(int i=0; i < num_entries; i++) {
+ const liq_color rgba = {
+ .r = entries[i].color.r,
+ .g = entries[i].color.g,
+ .b = entries[i].color.b,
+ .a = entries[i].color.a,
+ };
+ union rgba_as_int px = {rgba};
+ unsigned int hash;
+ if (px.rgba.a) {
+ hash = px.l % hash_size;
+ } else {
+ hash=0; px.l=0;
+ }
+ if (!pam_add_to_hash(input_hist->acht, hash, entries[i].count, px, i, num_entries)) {
+ return LIQ_OUT_OF_MEMORY;
+ }
+ }
+
+ return LIQ_OK;
+}
+
+LIQ_EXPORT LIQ_NONNULL liq_error liq_histogram_add_image(liq_histogram *input_hist, const liq_attr *options, liq_image *input_image)
+{
+ if (!CHECK_STRUCT_TYPE(options, liq_attr)) return LIQ_INVALID_POINTER;
+ if (!CHECK_STRUCT_TYPE(input_hist, liq_histogram)) return LIQ_INVALID_POINTER;
+ if (!CHECK_STRUCT_TYPE(input_image, liq_image)) return LIQ_INVALID_POINTER;
+
+ const unsigned int cols = input_image->width, rows = input_image->height;
+
+ if (!input_image->importance_map && options->use_contrast_maps) {
+ contrast_maps(input_image);
+ }
+
+ input_hist->gamma = input_image->gamma;
+
+ for(int i = 0; i < input_image->fixed_colors_count; i++) {
+ liq_error res = liq_histogram_add_fixed_color_f(input_hist, input_image->fixed_colors[i]);
+ if (res != LIQ_OK) {
+ return res;
+ }
+ }
+
+ /*
+ ** Step 2: attempt to make a histogram of the colors, unclustered.
+ ** If at first we don't succeed, increase ignorebits to increase color
+ ** coherence and try again.
+ */
+
+ if (liq_progress(options, options->progress_stage1 * 0.4f)) {
+ return LIQ_ABORTED;
+ }
+
+ const bool all_rows_at_once = liq_image_can_use_rgba_rows(input_image);
+
+ // Usual solution is to start from scratch when limit is exceeded, but that's not possible if it's not
+ // the first image added
+ const unsigned int max_histogram_entries = input_hist->had_image_added ? ~0 : options->max_histogram_entries;
+ do {
+ if (!input_hist->acht) {
+ input_hist->acht = pam_allocacolorhash(max_histogram_entries, rows*cols, input_hist->ignorebits, options->malloc, options->free);
+ }
+ if (!input_hist->acht) return LIQ_OUT_OF_MEMORY;
+
+ // histogram uses noise contrast map for importance. Color accuracy in noisy areas is not very important.
+ // noise map does not include edges to avoid ruining anti-aliasing
+ for(unsigned int row=0; row < rows; row++) {
+ bool added_ok;
+ if (all_rows_at_once) {
+ added_ok = pam_computeacolorhash(input_hist->acht, (const liq_color *const *)input_image->rows, cols, rows, input_image->importance_map);
+ if (added_ok) break;
+ } else {
+ const liq_color* rows_p[1] = { liq_image_get_row_rgba(input_image, row) };
+ added_ok = pam_computeacolorhash(input_hist->acht, rows_p, cols, 1, input_image->importance_map ? &input_image->importance_map[row * cols] : NULL);
+ }
+ if (!added_ok) {
+ input_hist->ignorebits++;
+ liq_verbose_printf(options, " too many colors! Scaling colors to improve clustering... %d", input_hist->ignorebits);
+ pam_freeacolorhash(input_hist->acht);
+ input_hist->acht = NULL;
+ if (liq_progress(options, options->progress_stage1 * 0.6f)) return LIQ_ABORTED;
+ break;
+ }
+ }
+ } while(!input_hist->acht);
+
+ input_hist->had_image_added = true;
+
+ liq_image_free_importance_map(input_image);
+
+ if (input_image->free_pixels && input_image->f_pixels) {
+ liq_image_free_rgba_source(input_image); // bow can free the RGBA source if copy has been made in f_pixels
+ }
+
+ return LIQ_OK;
+}
+
+LIQ_NONNULL static liq_error finalize_histogram(liq_histogram *input_hist, liq_attr *options, histogram **hist_output)
+{
+ if (liq_progress(options, options->progress_stage1 * 0.9f)) {
+ return LIQ_ABORTED;
+ }
+
+ if (!input_hist->acht) {
+ return LIQ_BITMAP_NOT_AVAILABLE;
+ }
+
+ histogram *hist = pam_acolorhashtoacolorhist(input_hist->acht, input_hist->gamma, options->malloc, options->free);
+ pam_freeacolorhash(input_hist->acht);
+ input_hist->acht = NULL;
+
+ if (!hist) {
+ return LIQ_OUT_OF_MEMORY;
+ }
+ liq_verbose_printf(options, " made histogram...%d colors found", hist->size);
+ remove_fixed_colors_from_histogram(hist, input_hist->fixed_colors_count, input_hist->fixed_colors, options->target_mse);
+
+ *hist_output = hist;
+ return LIQ_OK;
+}
+
+/**
+ Builds two maps:
+ importance_map - approximation of areas with high-frequency noise, except straight edges. 1=flat, 0=noisy.
+ edges - noise map including all edges
+ */
+LIQ_NONNULL static void contrast_maps(liq_image *image)
+{
+ const unsigned int cols = image->width, rows = image->height;
+ if (cols < 4 || rows < 4 || (3*cols*rows) > LIQ_HIGH_MEMORY_LIMIT) {
+ return;
+ }
+
+ unsigned char *restrict noise = image->importance_map ? image->importance_map : image->malloc(cols*rows);
+ image->importance_map = NULL;
+ unsigned char *restrict edges = image->edges ? image->edges : image->malloc(cols*rows);
+ image->edges = NULL;
+
+ unsigned char *restrict tmp = image->malloc(cols*rows);
+
+ if (!noise || !edges || !tmp || !liq_image_get_row_f_init(image)) {
+ image->free(noise);
+ image->free(edges);
+ image->free(tmp);
+ return;
+ }
+
+ const f_pixel *curr_row, *prev_row, *next_row;
+ curr_row = prev_row = next_row = liq_image_get_row_f(image, 0);
+
+ for (unsigned int j=0; j < rows; j++) {
+ prev_row = curr_row;
+ curr_row = next_row;
+ next_row = liq_image_get_row_f(image, MIN(rows-1,j+1));
+
+ f_pixel prev, curr = curr_row[0], next=curr;
+ for (unsigned int i=0; i < cols; i++) {
+ prev=curr;
+ curr=next;
+ next = curr_row[MIN(cols-1,i+1)];
+
+ // contrast is difference between pixels neighbouring horizontally and vertically
+ const float a = fabsf(prev.a+next.a - curr.a*2.f),
+ r = fabsf(prev.r+next.r - curr.r*2.f),
+ g = fabsf(prev.g+next.g - curr.g*2.f),
+ b = fabsf(prev.b+next.b - curr.b*2.f);
+
+ const f_pixel prevl = prev_row[i];
+ const f_pixel nextl = next_row[i];
+
+ const float a1 = fabsf(prevl.a+nextl.a - curr.a*2.f),
+ r1 = fabsf(prevl.r+nextl.r - curr.r*2.f),
+ g1 = fabsf(prevl.g+nextl.g - curr.g*2.f),
+ b1 = fabsf(prevl.b+nextl.b - curr.b*2.f);
+
+ const float horiz = MAX(MAX(a,r),MAX(g,b));
+ const float vert = MAX(MAX(a1,r1),MAX(g1,b1));
+ const float edge = MAX(horiz,vert);
+ float z = edge - fabsf(horiz-vert)*.5f;
+ z = 1.f - MAX(z,MIN(horiz,vert));
+ z *= z; // noise is amplified
+ z *= z;
+ // 85 is about 1/3rd of weight (not 0, because noisy pixels still need to be included, just not as precisely).
+ const unsigned int z_int = 80 + (unsigned int)(z * 176.f);
+ noise[j*cols+i] = MIN(z_int, 255);
+ const int e_int = 255 - (int)(edge * 256.f);
+ edges[j*cols+i] = e_int > 0 ? MIN(e_int, 255) : 0;
+ }
+ }
+
+ // noise areas are shrunk and then expanded to remove thin edges from the map
+ liq_max3(noise, tmp, cols, rows);
+ liq_max3(tmp, noise, cols, rows);
+
+ liq_blur(noise, tmp, noise, cols, rows, 3);
+
+ liq_max3(noise, tmp, cols, rows);
+
+ liq_min3(tmp, noise, cols, rows);
+ liq_min3(noise, tmp, cols, rows);
+ liq_min3(tmp, noise, cols, rows);
+
+ liq_min3(edges, tmp, cols, rows);
+ liq_max3(tmp, edges, cols, rows);
+ for(unsigned int i=0; i < cols*rows; i++) edges[i] = MIN(noise[i], edges[i]);
+
+ image->free(tmp);
+
+ image->importance_map = noise;
+ image->edges = edges;
+}
+
+/**
+ * Builds map of neighbor pixels mapped to the same palette entry
+ *
+ * For efficiency/simplicity it mainly looks for same consecutive pixels horizontally
+ * and peeks 1 pixel above/below. Full 2d algorithm doesn't improve it significantly.
+ * Correct flood fill doesn't have visually good properties.
+ */
+LIQ_NONNULL static void update_dither_map(liq_image *input_image, unsigned char *const *const row_pointers, colormap *map)
+{
+ const unsigned int width = input_image->width;
+ const unsigned int height = input_image->height;
+ unsigned char *const edges = input_image->edges;
+
+ for(unsigned int row=0; row < height; row++) {
+ unsigned char lastpixel = row_pointers[row][0];
+ unsigned int lastcol=0;
+
+ for(unsigned int col=1; col < width; col++) {
+ const unsigned char px = row_pointers[row][col];
+ if (input_image->background && map->palette[px].acolor.a < MIN_OPAQUE_A) {
+ // Transparency may or may not create an edge. When there's an explicit background set, assume no edge.
+ continue;
+ }
+
+ if (px != lastpixel || col == width-1) {
+ int neighbor_count = 10 * (col-lastcol);
+
+ unsigned int i=lastcol;
+ while(i < col) {
+ if (row > 0) {
+ unsigned char pixelabove = row_pointers[row-1][i];
+ if (pixelabove == lastpixel) neighbor_count += 15;
+ }
+ if (row < height-1) {
+ unsigned char pixelbelow = row_pointers[row+1][i];
+ if (pixelbelow == lastpixel) neighbor_count += 15;
+ }
+ i++;
+ }
+
+ while(lastcol <= col) {
+ int e = edges[row*width + lastcol];
+ edges[row*width + lastcol++] = (e+128) * (255.f/(255+128)) * (1.f - 20.f / (20 + neighbor_count));
+ }
+ lastpixel = px;
+ }
+ }
+ }
+ input_image->dither_map = input_image->edges;
+ input_image->edges = NULL;
+}
+
+/**
+ * Palette can be NULL, in which case it creates a new palette from scratch.
+ */
+static colormap *add_fixed_colors_to_palette(colormap *palette, const int max_colors, const f_pixel fixed_colors[], const int fixed_colors_count, void* (*malloc)(size_t), void (*free)(void*))
+{
+ if (!fixed_colors_count) return palette;
+
+ colormap *newpal = pam_colormap(MIN(max_colors, (palette ? palette->colors : 0) + fixed_colors_count), malloc, free);
+ unsigned int i=0;
+ if (palette && fixed_colors_count < max_colors) {
+ unsigned int palette_max = MIN(palette->colors, max_colors - fixed_colors_count);
+ for(; i < palette_max; i++) {
+ newpal->palette[i] = palette->palette[i];
+ }
+ }
+ for(int j=0; j < MIN(max_colors, fixed_colors_count); j++) {
+ newpal->palette[i++] = (colormap_item){
+ .acolor = fixed_colors[j],
+ .fixed = true,
+ };
+ }
+ if (palette) pam_freecolormap(palette);
+ return newpal;
+}
+
+LIQ_NONNULL static void adjust_histogram_callback(hist_item *item, float diff)
+{
+ item->adjusted_weight = (item->perceptual_weight + 2.f * item->adjusted_weight) * (0.5f + diff);
+}
+
+/**
+ Repeats mediancut with different histogram weights to find palette with minimum error.
+
+ feedback_loop_trials controls how long the search will take. < 0 skips the iteration.
+ */
+static colormap *find_best_palette(histogram *hist, const liq_attr *options, const double max_mse, const f_pixel fixed_colors[], const unsigned int fixed_colors_count, double *palette_error_p)
+{
+ unsigned int max_colors = options->max_colors;
+
+ // if output is posterized it doesn't make sense to aim for perfrect colors, so increase target_mse
+ // at this point actual gamma is not set, so very conservative posterization estimate is used
+ const double target_mse = MIN(max_mse, MAX(options->target_mse, pow((1<min_posterization_output)/1024.0, 2)));
+ int feedback_loop_trials = options->feedback_loop_trials;
+ if (hist->size > 5000) {feedback_loop_trials = (feedback_loop_trials*3 + 3)/4;}
+ if (hist->size > 25000) {feedback_loop_trials = (feedback_loop_trials*3 + 3)/4;}
+ if (hist->size > 50000) {feedback_loop_trials = (feedback_loop_trials*3 + 3)/4;}
+ if (hist->size > 100000) {feedback_loop_trials = (feedback_loop_trials*3 + 3)/4;}
+ colormap *acolormap = NULL;
+ double least_error = MAX_DIFF;
+ double target_mse_overshoot = feedback_loop_trials>0 ? 1.05 : 1.0;
+ const float total_trials = (float)(feedback_loop_trials>0?feedback_loop_trials:1);
+ int fails_in_a_row=0;
+
+ do {
+ colormap *newmap;
+ if (hist->size && fixed_colors_count < max_colors) {
+ newmap = mediancut(hist, max_colors-fixed_colors_count, target_mse * target_mse_overshoot, MAX(MAX(45.0/65536.0, target_mse), least_error)*1.2,
+ options->malloc, options->free);
+ } else {
+ feedback_loop_trials = 0;
+ newmap = NULL;
+ }
+ newmap = add_fixed_colors_to_palette(newmap, max_colors, fixed_colors, fixed_colors_count, options->malloc, options->free);
+ if (!newmap) {
+ return NULL;
+ }
+
+ if (feedback_loop_trials <= 0) {
+ return newmap;
+ }
+
+ // after palette has been created, total error (MSE) is calculated to keep the best palette
+ // at the same time K-Means iteration is done to improve the palette
+ // and histogram weights are adjusted based on remapping error to give more weight to poorly matched colors
+
+ const bool first_run_of_target_mse = !acolormap && target_mse > 0;
+ double total_error = kmeans_do_iteration(hist, newmap, first_run_of_target_mse ? NULL : adjust_histogram_callback, omp_get_max_threads());
+
+ // goal is to increase quality or to reduce number of colors used if quality is good enough
+ if (!acolormap || total_error < least_error || (total_error <= target_mse && newmap->colors < max_colors)) {
+ if (acolormap) pam_freecolormap(acolormap);
+ acolormap = newmap;
+
+ if (total_error < target_mse && total_error > 0) {
+ // K-Means iteration improves quality above what mediancut aims for
+ // this compensates for it, making mediancut aim for worse
+ target_mse_overshoot = MIN(target_mse_overshoot*1.25, target_mse/total_error);
+ }
+
+ least_error = total_error;
+
+ // if number of colors could be reduced, try to keep it that way
+ // but allow extra color as a bit of wiggle room in case quality can be improved too
+ max_colors = MIN(newmap->colors+1, max_colors);
+
+ feedback_loop_trials -= 1; // asymptotic improvement could make it go on forever
+ fails_in_a_row = 0;
+ } else {
+ fails_in_a_row++;
+ target_mse_overshoot = 1.0;
+
+ // if error is really bad, it's unlikely to improve, so end sooner
+ feedback_loop_trials -= 5 + fails_in_a_row;
+ pam_freecolormap(newmap);
+ }
+
+ float fraction_done = 1.f-MAX(0.f, feedback_loop_trials/total_trials);
+ if (liq_progress(options, options->progress_stage1 + fraction_done * options->progress_stage2)) break;
+ liq_verbose_printf(options, " selecting colors...%d%%", (int)(100.f * fraction_done));
+ }
+ while(feedback_loop_trials > 0);
+
+ *palette_error_p = least_error;
+ return acolormap;
+}
+
+LIQ_NONNULL static liq_error pngquant_quantize(histogram *hist, const liq_attr *options, const int fixed_colors_count, const f_pixel fixed_colors[], const double gamma, bool fixed_result_colors, liq_result **result_output)
+{
+ colormap *acolormap;
+ double palette_error = -1;
+
+ assert((verbose_print(options, "SLOW debug checks enabled. Recompile with NDEBUG for normal operation."),1));
+
+ const bool few_input_colors = hist->size+fixed_colors_count <= options->max_colors;
+
+ if (liq_progress(options, options->progress_stage1)) return LIQ_ABORTED;
+
+ // If image has few colors to begin with (and no quality degradation is required)
+ // then it's possible to skip quantization entirely
+ if (few_input_colors && options->target_mse == 0) {
+ colormap *hist_pal = histogram_to_palette(hist, options->malloc, options->free);
+ acolormap = add_fixed_colors_to_palette(hist_pal, options->max_colors, fixed_colors, fixed_colors_count, options->malloc, options->free);
+ palette_error = 0;
+ } else {
+ const double max_mse = options->max_mse * (few_input_colors ? 0.33 : 1.0); // when degrading image that's already paletted, require much higher improvement, since pal2pal often looks bad and there's little gain
+ acolormap = find_best_palette(hist, options, max_mse, fixed_colors, fixed_colors_count, &palette_error);
+ if (!acolormap) {
+ return LIQ_VALUE_OUT_OF_RANGE;
+ }
+
+ // K-Means iteration approaches local minimum for the palette
+ double iteration_limit = options->kmeans_iteration_limit;
+ unsigned int iterations = options->kmeans_iterations;
+
+ if (!iterations && palette_error < 0 && max_mse < MAX_DIFF) iterations = 1; // otherwise total error is never calculated and MSE limit won't work
+
+ if (iterations) {
+ // likely_colormap_index (used and set in kmeans_do_iteration) can't point to index outside colormap
+ hist_reset_colors(hist, acolormap->colors);
+
+ if (hist->size > 5000) {iterations = (iterations*3 + 3)/4;}
+ if (hist->size > 25000) {iterations = (iterations*3 + 3)/4;}
+ if (hist->size > 50000) {iterations = (iterations*3 + 3)/4;}
+ if (hist->size > 100000) {iterations = (iterations*3 + 3)/4; iteration_limit *= 2;}
+
+ verbose_print(options, " moving colormap towards local minimum");
+
+ double previous_palette_error = MAX_DIFF;
+
+ for(unsigned int i=0; i < iterations; i++) {
+ palette_error = kmeans_do_iteration(hist, acolormap, NULL, omp_get_max_threads());
+
+ if (liq_progress(options, options->progress_stage1 + options->progress_stage2 + (i * options->progress_stage3 * 0.9f) / iterations)) {
+ break;
+ }
+
+ if (fabs(previous_palette_error-palette_error) < iteration_limit) {
+ break;
+ }
+
+ if (palette_error > max_mse*1.5) { // probably hopeless
+ if (palette_error > max_mse*3.0) break; // definitely hopeless
+ i++;
+ }
+
+ previous_palette_error = palette_error;
+ }
+ }
+
+ if (palette_error > max_mse) {
+ liq_verbose_printf(options, " image degradation MSE=%.3f (Q=%d) exceeded limit of %.3f (%d)",
+ mse_to_standard_mse(palette_error), mse_to_quality(palette_error),
+ mse_to_standard_mse(max_mse), mse_to_quality(max_mse));
+ pam_freecolormap(acolormap);
+ return LIQ_QUALITY_TOO_LOW;
+ }
+ }
+
+ if (liq_progress(options, options->progress_stage1 + options->progress_stage2 + options->progress_stage3 * 0.95f)) {
+ pam_freecolormap(acolormap);
+ return LIQ_ABORTED;
+ }
+
+ sort_palette(acolormap, options);
+
+ // If palette was created from a multi-image histogram,
+ // then it shouldn't be optimized for one image during remapping
+ if (fixed_result_colors) {
+ for(unsigned int i=0; i < acolormap->colors; i++) {
+ acolormap->palette[i].fixed = true;
+ }
+ }
+
+ liq_result *result = options->malloc(sizeof(liq_result));
+ if (!result) return LIQ_OUT_OF_MEMORY;
+ *result = (liq_result){
+ .magic_header = liq_result_magic,
+ .malloc = options->malloc,
+ .free = options->free,
+ .palette = acolormap,
+ .palette_error = palette_error,
+ .use_dither_map = options->use_dither_map,
+ .gamma = gamma,
+ .min_posterization_output = options->min_posterization_output,
+ };
+ *result_output = result;
+ return LIQ_OK;
+}
+
+LIQ_EXPORT LIQ_NONNULL liq_error liq_write_remapped_image(liq_result *result, liq_image *input_image, void *buffer, size_t buffer_size)
+{
+ if (!CHECK_STRUCT_TYPE(result, liq_result)) {
+ return LIQ_INVALID_POINTER;
+ }
+ if (!CHECK_STRUCT_TYPE(input_image, liq_image)) {
+ return LIQ_INVALID_POINTER;
+ }
+ if (!CHECK_USER_POINTER(buffer)) {
+ return LIQ_INVALID_POINTER;
+ }
+
+ const size_t required_size = (size_t)input_image->width * (size_t)input_image->height;
+ if (buffer_size < required_size) {
+ return LIQ_BUFFER_TOO_SMALL;
+ }
+
+ unsigned char **rows = input_image->malloc(input_image->height * sizeof(unsigned char *));
+ unsigned char *buffer_bytes = buffer;
+ for(unsigned int i=0; i < input_image->height; i++) {
+ rows[i] = &buffer_bytes[input_image->width * i];
+ }
+
+ liq_error err = liq_write_remapped_image_rows(result, input_image, rows);
+ input_image->free(rows);
+ return err;
+}
+
+LIQ_EXPORT LIQ_NONNULL liq_error liq_write_remapped_image_rows(liq_result *quant, liq_image *input_image, unsigned char **row_pointers)
+{
+ if (!CHECK_STRUCT_TYPE(quant, liq_result)) return LIQ_INVALID_POINTER;
+ if (!CHECK_STRUCT_TYPE(input_image, liq_image)) return LIQ_INVALID_POINTER;
+ for(unsigned int i=0; i < input_image->height; i++) {
+ if (!CHECK_USER_POINTER(row_pointers+i) || !CHECK_USER_POINTER(row_pointers[i])) return LIQ_INVALID_POINTER;
+ }
+
+ if (quant->remapping) {
+ liq_remapping_result_destroy(quant->remapping);
+ }
+ liq_remapping_result *const result = quant->remapping = liq_remapping_result_create(quant);
+ if (!result) return LIQ_OUT_OF_MEMORY;
+
+ if (!input_image->edges && !input_image->dither_map && quant->use_dither_map) {
+ contrast_maps(input_image);
+ }
+
+ if (liq_remap_progress(result, result->progress_stage1 * 0.25f)) {
+ return LIQ_ABORTED;
+ }
+
+ /*
+ ** Step 4: map the colors in the image to their closest match in the
+ ** new colormap, and write 'em out.
+ */
+
+ float remapping_error = result->palette_error;
+ if (result->dither_level == 0) {
+ set_rounded_palette(&result->int_palette, result->palette, result->gamma, quant->min_posterization_output);
+ remapping_error = remap_to_palette(input_image, row_pointers, result->palette);
+ } else {
+ const bool is_image_huge = (input_image->width * input_image->height) > 2000 * 2000;
+ const bool allow_dither_map = result->use_dither_map == 2 || (!is_image_huge && result->use_dither_map);
+ const bool generate_dither_map = allow_dither_map && (input_image->edges && !input_image->dither_map);
+ if (generate_dither_map) {
+ // If dithering (with dither map) is required, this image is used to find areas that require dithering
+ remapping_error = remap_to_palette(input_image, row_pointers, result->palette);
+ update_dither_map(input_image, row_pointers, result->palette);
+ }
+
+ if (liq_remap_progress(result, result->progress_stage1 * 0.5f)) {
+ return LIQ_ABORTED;
+ }
+
+ // remapping above was the last chance to do K-Means iteration, hence the final palette is set after remapping
+ set_rounded_palette(&result->int_palette, result->palette, result->gamma, quant->min_posterization_output);
+
+ if (!remap_to_palette_floyd(input_image, row_pointers, result, MAX(remapping_error*2.4f, 8.f/256.f), generate_dither_map)) {
+ return LIQ_ABORTED;
+ }
+ }
+
+ // remapping error from dithered image is absurd, so always non-dithered value is used
+ // palette_error includes some perceptual weighting from histogram which is closer correlated with dssim
+ // so that should be used when possible.
+ if (result->palette_error < 0) {
+ result->palette_error = remapping_error;
+ }
+
+ return LIQ_OK;
+}
+
+LIQ_EXPORT int liq_version() {
+ return LIQ_VERSION;
+}
diff --git a/tools/assets/n64texconv/lib/libimagequant/libimagequant.h b/tools/assets/n64texconv/lib/libimagequant/libimagequant.h
new file mode 100644
index 000000000..e4763ab38
--- /dev/null
+++ b/tools/assets/n64texconv/lib/libimagequant/libimagequant.h
@@ -0,0 +1,151 @@
+/*
+ * https://pngquant.org
+ */
+
+#ifndef LIBIMAGEQUANT_H
+#define LIBIMAGEQUANT_H
+
+#ifdef IMAGEQUANT_EXPORTS
+#define LIQ_EXPORT __declspec(dllexport)
+#endif
+
+#ifndef LIQ_EXPORT
+#define LIQ_EXPORT extern
+#endif
+
+#define LIQ_VERSION 21800
+#define LIQ_VERSION_STRING "2.18.0"
+
+#ifndef LIQ_PRIVATE
+#if defined(__GNUC__) || defined (__llvm__)
+#define LIQ_PRIVATE __attribute__((visibility("hidden")))
+#define LIQ_NONNULL __attribute__((nonnull))
+#define LIQ_USERESULT __attribute__((warn_unused_result))
+#else
+#define LIQ_PRIVATE
+#define LIQ_NONNULL
+#define LIQ_USERESULT
+#endif
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include
+
+typedef struct liq_attr liq_attr;
+typedef struct liq_image liq_image;
+typedef struct liq_result liq_result;
+typedef struct liq_histogram liq_histogram;
+
+typedef struct liq_color {
+ unsigned char r, g, b, a;
+} liq_color;
+
+typedef struct liq_palette {
+ unsigned int count;
+ liq_color entries[256];
+} liq_palette;
+
+typedef enum liq_error {
+ LIQ_OK = 0,
+ LIQ_QUALITY_TOO_LOW = 99,
+ LIQ_VALUE_OUT_OF_RANGE = 100,
+ LIQ_OUT_OF_MEMORY,
+ LIQ_ABORTED,
+ LIQ_BITMAP_NOT_AVAILABLE,
+ LIQ_BUFFER_TOO_SMALL,
+ LIQ_INVALID_POINTER,
+ LIQ_UNSUPPORTED,
+} liq_error;
+
+enum liq_ownership {
+ LIQ_OWN_ROWS=4,
+ LIQ_OWN_PIXELS=8,
+ LIQ_COPY_PIXELS=16,
+};
+
+typedef struct liq_histogram_entry {
+ liq_color color;
+ unsigned int count;
+} liq_histogram_entry;
+
+LIQ_EXPORT LIQ_USERESULT liq_attr* liq_attr_create(void);
+LIQ_EXPORT LIQ_USERESULT liq_attr* liq_attr_create_with_allocator(void* (*malloc)(size_t), void (*free)(void*));
+LIQ_EXPORT LIQ_USERESULT liq_attr* liq_attr_copy(const liq_attr *orig) LIQ_NONNULL;
+LIQ_EXPORT void liq_attr_destroy(liq_attr *attr) LIQ_NONNULL;
+
+LIQ_EXPORT LIQ_USERESULT liq_histogram* liq_histogram_create(const liq_attr* attr);
+LIQ_EXPORT liq_error liq_histogram_add_image(liq_histogram *hist, const liq_attr *attr, liq_image* image) LIQ_NONNULL;
+LIQ_EXPORT liq_error liq_histogram_add_colors(liq_histogram *hist, const liq_attr *attr, const liq_histogram_entry entries[], int num_entries, double gamma) LIQ_NONNULL;
+LIQ_EXPORT liq_error liq_histogram_add_fixed_color(liq_histogram *hist, liq_color color, double gamma) LIQ_NONNULL;
+LIQ_EXPORT void liq_histogram_destroy(liq_histogram *hist) LIQ_NONNULL;
+
+LIQ_EXPORT liq_error liq_set_max_colors(liq_attr* attr, int colors) LIQ_NONNULL;
+LIQ_EXPORT LIQ_USERESULT int liq_get_max_colors(const liq_attr* attr) LIQ_NONNULL;
+LIQ_EXPORT liq_error liq_set_speed(liq_attr* attr, int speed) LIQ_NONNULL;
+LIQ_EXPORT LIQ_USERESULT int liq_get_speed(const liq_attr* attr) LIQ_NONNULL;
+LIQ_EXPORT liq_error liq_set_min_opacity(liq_attr* attr, int min) LIQ_NONNULL;
+LIQ_EXPORT LIQ_USERESULT int liq_get_min_opacity(const liq_attr* attr) LIQ_NONNULL;
+LIQ_EXPORT liq_error liq_set_min_posterization(liq_attr* attr, int bits) LIQ_NONNULL;
+LIQ_EXPORT LIQ_USERESULT int liq_get_min_posterization(const liq_attr* attr) LIQ_NONNULL;
+LIQ_EXPORT liq_error liq_set_quality(liq_attr* attr, int minimum, int maximum) LIQ_NONNULL;
+LIQ_EXPORT LIQ_USERESULT int liq_get_min_quality(const liq_attr* attr) LIQ_NONNULL;
+LIQ_EXPORT LIQ_USERESULT int liq_get_max_quality(const liq_attr* attr) LIQ_NONNULL;
+LIQ_EXPORT void liq_set_last_index_transparent(liq_attr* attr, int is_last) LIQ_NONNULL;
+
+typedef void liq_log_callback_function(const liq_attr*, const char *message, void* user_info);
+typedef void liq_log_flush_callback_function(const liq_attr*, void* user_info);
+LIQ_EXPORT void liq_set_log_callback(liq_attr*, liq_log_callback_function*, void* user_info);
+LIQ_EXPORT void liq_set_log_flush_callback(liq_attr*, liq_log_flush_callback_function*, void* user_info);
+
+typedef int liq_progress_callback_function(float progress_percent, void* user_info);
+LIQ_EXPORT void liq_attr_set_progress_callback(liq_attr*, liq_progress_callback_function*, void* user_info);
+LIQ_EXPORT void liq_result_set_progress_callback(liq_result*, liq_progress_callback_function*, void* user_info);
+
+// The rows and their data are not modified. The type of `rows` is non-const only due to a bug in C's typesystem design.
+LIQ_EXPORT LIQ_USERESULT liq_image *liq_image_create_rgba_rows(const liq_attr *attr, void *const rows[], int width, int height, double gamma) LIQ_NONNULL;
+LIQ_EXPORT LIQ_USERESULT liq_image *liq_image_create_rgba(const liq_attr *attr, const void *bitmap, int width, int height, double gamma) LIQ_NONNULL;
+
+typedef void liq_image_get_rgba_row_callback(liq_color row_out[], int row, int width, void* user_info);
+LIQ_EXPORT LIQ_USERESULT liq_image *liq_image_create_custom(const liq_attr *attr, liq_image_get_rgba_row_callback *row_callback, void* user_info, int width, int height, double gamma);
+
+LIQ_EXPORT liq_error liq_image_set_memory_ownership(liq_image *image, int ownership_flags) LIQ_NONNULL;
+LIQ_EXPORT liq_error liq_image_set_background(liq_image *img, liq_image *background_image) LIQ_NONNULL;
+LIQ_EXPORT liq_error liq_image_set_importance_map(liq_image *img, unsigned char buffer[], size_t buffer_size, enum liq_ownership memory_handling) LIQ_NONNULL;
+LIQ_EXPORT liq_error liq_image_add_fixed_color(liq_image *img, liq_color color) LIQ_NONNULL;
+LIQ_EXPORT LIQ_USERESULT int liq_image_get_width(const liq_image *img) LIQ_NONNULL;
+LIQ_EXPORT LIQ_USERESULT int liq_image_get_height(const liq_image *img) LIQ_NONNULL;
+LIQ_EXPORT void liq_image_destroy(liq_image *img) LIQ_NONNULL;
+
+LIQ_EXPORT LIQ_USERESULT liq_error liq_histogram_quantize(liq_histogram *const input_hist, liq_attr *const options, liq_result **result_output) LIQ_NONNULL;
+LIQ_EXPORT LIQ_USERESULT liq_error liq_image_quantize(liq_image *const input_image, liq_attr *const options, liq_result **result_output) LIQ_NONNULL;
+
+LIQ_EXPORT liq_error liq_set_dithering_level(liq_result *res, float dither_level) LIQ_NONNULL;
+LIQ_EXPORT liq_error liq_set_output_gamma(liq_result* res, double gamma) LIQ_NONNULL;
+LIQ_EXPORT LIQ_USERESULT double liq_get_output_gamma(const liq_result *result) LIQ_NONNULL;
+
+LIQ_EXPORT LIQ_USERESULT const liq_palette *liq_get_palette(liq_result *result) LIQ_NONNULL;
+
+LIQ_EXPORT liq_error liq_write_remapped_image(liq_result *result, liq_image *input_image, void *buffer, size_t buffer_size) LIQ_NONNULL;
+LIQ_EXPORT liq_error liq_write_remapped_image_rows(liq_result *result, liq_image *input_image, unsigned char **row_pointers) LIQ_NONNULL;
+
+LIQ_EXPORT double liq_get_quantization_error(const liq_result *result) LIQ_NONNULL;
+LIQ_EXPORT int liq_get_quantization_quality(const liq_result *result) LIQ_NONNULL;
+LIQ_EXPORT double liq_get_remapping_error(const liq_result *result) LIQ_NONNULL;
+LIQ_EXPORT int liq_get_remapping_quality(const liq_result *result) LIQ_NONNULL;
+
+LIQ_EXPORT void liq_result_destroy(liq_result *) LIQ_NONNULL;
+
+LIQ_EXPORT int liq_version(void);
+
+
+// Deprecated
+LIQ_EXPORT LIQ_USERESULT liq_result *liq_quantize_image(liq_attr *options, liq_image *input_image) LIQ_NONNULL;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/tools/assets/n64texconv/lib/libimagequant/libimagequant_private.h b/tools/assets/n64texconv/lib/libimagequant/libimagequant_private.h
new file mode 100644
index 000000000..50e2c18a3
--- /dev/null
+++ b/tools/assets/n64texconv/lib/libimagequant/libimagequant_private.h
@@ -0,0 +1,50 @@
+#ifdef _OPENMP
+#include
+#define LIQ_TEMP_ROW_WIDTH(img_width) (((img_width) | 15) + 1) /* keep alignment & leave space between rows to avoid cache line contention */
+#else
+#define LIQ_TEMP_ROW_WIDTH(img_width) (img_width)
+#define omp_get_max_threads() 1
+#define omp_get_thread_num() 0
+#endif
+
+struct liq_image {
+ const char *magic_header;
+ void* (*malloc)(size_t);
+ void (*free)(void*);
+
+ f_pixel *f_pixels;
+ liq_color **rows;
+ double gamma;
+ unsigned int width, height;
+ unsigned char *importance_map, *edges, *dither_map;
+ liq_color *pixels, *temp_row;
+ f_pixel *temp_f_row;
+ liq_image_get_rgba_row_callback *row_callback;
+ void *row_callback_user_info;
+ liq_image *background;
+ f_pixel fixed_colors[256];
+ unsigned short fixed_colors_count;
+ bool free_pixels, free_rows, free_rows_internal;
+};
+
+typedef struct liq_remapping_result {
+ const char *magic_header;
+ void* (*malloc)(size_t);
+ void (*free)(void*);
+
+ unsigned char *pixels;
+ colormap *palette;
+ liq_progress_callback_function *progress_callback;
+ void *progress_callback_user_info;
+
+ liq_palette int_palette;
+ double gamma, palette_error;
+ float dither_level;
+ unsigned char use_dither_map;
+ unsigned char progress_stage1;
+} liq_remapping_result;
+
+
+LIQ_PRIVATE bool liq_image_get_row_f_init(liq_image *img) LIQ_NONNULL;
+LIQ_PRIVATE const f_pixel *liq_image_get_row_f(liq_image *input_image, unsigned int row) LIQ_NONNULL;
+LIQ_PRIVATE bool liq_remap_progress(const liq_remapping_result *quant, const float percent) LIQ_NONNULL;
diff --git a/tools/assets/n64texconv/lib/libimagequant/mediancut.c b/tools/assets/n64texconv/lib/libimagequant/mediancut.c
new file mode 100644
index 000000000..cc241b858
--- /dev/null
+++ b/tools/assets/n64texconv/lib/libimagequant/mediancut.c
@@ -0,0 +1,476 @@
+/*
+** © 2009-2018 by Kornel Lesiński.
+** © 1989, 1991 by Jef Poskanzer.
+** © 1997, 2000, 2002 by Greg Roelofs; based on an idea by Stefan Schneider.
+**
+** See COPYRIGHT file for license.
+*/
+
+#include
+#include
+
+#include "libimagequant.h"
+#include "pam.h"
+#include "mediancut.h"
+
+#define index_of_channel(ch) (offsetof(f_pixel,ch)/sizeof(float))
+
+static f_pixel averagepixels(unsigned int clrs, const hist_item achv[]);
+
+struct box {
+ f_pixel color;
+ f_pixel variance;
+ double sum, total_error, max_error;
+ unsigned int ind;
+ unsigned int colors;
+};
+
+/** Weighted per-channel variance of the box. It's used to decide which channel to split by */
+static f_pixel box_variance(const hist_item achv[], const struct box *box)
+{
+ const f_pixel mean = box->color;
+ double variancea=0, variancer=0, varianceg=0, varianceb=0;
+
+ for(unsigned int i = 0; i < box->colors; ++i) {
+ const f_pixel px = achv[box->ind + i].acolor;
+ double weight = achv[box->ind + i].adjusted_weight;
+ variancea += (mean.a - px.a)*(mean.a - px.a)*weight;
+ variancer += (mean.r - px.r)*(mean.r - px.r)*weight;
+ varianceg += (mean.g - px.g)*(mean.g - px.g)*weight;
+ varianceb += (mean.b - px.b)*(mean.b - px.b)*weight;
+ }
+
+ return (f_pixel){
+ .a = variancea,
+ .r = variancer,
+ .g = varianceg,
+ .b = varianceb,
+ };
+}
+
+static double box_max_error(const hist_item achv[], const struct box *box)
+{
+ f_pixel mean = box->color;
+ double max_error = 0;
+
+ for(unsigned int i = 0; i < box->colors; ++i) {
+ const double diff = colordifference(mean, achv[box->ind + i].acolor);
+ if (diff > max_error) {
+ max_error = diff;
+ }
+ }
+ return max_error;
+}
+
+ALWAYS_INLINE static double color_weight(f_pixel median, hist_item h);
+
+static inline void hist_item_swap(hist_item *l, hist_item *r)
+{
+ if (l != r) {
+ hist_item t = *l;
+ *l = *r;
+ *r = t;
+ }
+}
+
+ALWAYS_INLINE static unsigned int qsort_pivot(const hist_item *const base, const unsigned int len);
+inline static unsigned int qsort_pivot(const hist_item *const base, const unsigned int len)
+{
+ if (len < 32) {
+ return len/2;
+ }
+
+ const unsigned int aidx=8, bidx=len/2, cidx=len-1;
+ const unsigned int a=base[aidx].tmp.sort_value, b=base[bidx].tmp.sort_value, c=base[cidx].tmp.sort_value;
+ return (a < b) ? ((b < c) ? bidx : ((a < c) ? cidx : aidx ))
+ : ((b > c) ? bidx : ((a < c) ? aidx : cidx ));
+}
+
+ALWAYS_INLINE static unsigned int qsort_partition(hist_item *const base, const unsigned int len);
+inline static unsigned int qsort_partition(hist_item *const base, const unsigned int len)
+{
+ unsigned int l = 1, r = len;
+ if (len >= 8) {
+ hist_item_swap(&base[0], &base[qsort_pivot(base,len)]);
+ }
+
+ const unsigned int pivot_value = base[0].tmp.sort_value;
+ while (l < r) {
+ if (base[l].tmp.sort_value >= pivot_value) {
+ l++;
+ } else {
+ while(l < --r && base[r].tmp.sort_value <= pivot_value) {}
+ hist_item_swap(&base[l], &base[r]);
+ }
+ }
+ l--;
+ hist_item_swap(&base[0], &base[l]);
+
+ return l;
+}
+
+/** quick select algorithm */
+static void hist_item_sort_range(hist_item base[], unsigned int len, unsigned int sort_start)
+{
+ for(;;) {
+ const unsigned int l = qsort_partition(base, len), r = l+1;
+
+ if (l > 0 && sort_start < l) {
+ len = l;
+ }
+ else if (r < len && sort_start > r) {
+ base += r; len -= r; sort_start -= r;
+ }
+ else break;
+ }
+}
+
+/** sorts array to make sum of weights lower than halfvar one side, returns index of the edge between halfvar parts of the set */
+static unsigned int hist_item_sort_halfvar(hist_item base[], unsigned int len, double halfvar)
+{
+ unsigned int base_idx = 0; // track base-index
+ do {
+ const unsigned int l = qsort_partition(base, len), r = l+1;
+
+ // check if sum of left side is smaller than half,
+ // if it is, then it doesn't need to be sorted
+ double tmpsum = 0.;
+ for(unsigned int t = 0; t <= l && tmpsum < halfvar; ++t) tmpsum += base[t].color_weight;
+
+ // the split is on the left part
+ if (tmpsum >= halfvar) {
+ if (l > 0) {
+ len = l;
+ continue;
+ } else {
+ // reached the end of left part
+ return base_idx;
+ }
+ }
+ // process the right part
+ halfvar -= tmpsum;
+ if (len > r) {
+ base += r;
+ base_idx += r;
+ len -= r; // tail-recursive "call"
+ } else {
+ // reached the end of the right part
+ return base_idx + len;
+ }
+ } while(1);
+}
+
+static f_pixel get_median(const struct box *b, hist_item achv[]);
+
+typedef struct {
+ unsigned int chan; float variance;
+} channelvariance;
+
+static int comparevariance(const void *ch1, const void *ch2)
+{
+ return ((const channelvariance*)ch1)->variance > ((const channelvariance*)ch2)->variance ? -1 :
+ (((const channelvariance*)ch1)->variance < ((const channelvariance*)ch2)->variance ? 1 : 0);
+}
+
+/** Finds which channels need to be sorted first and preproceses achv for fast sort */
+static double prepare_sort(struct box *b, hist_item achv[])
+{
+ /*
+ ** Sort dimensions by their variance, and then sort colors first by dimension with highest variance
+ */
+ channelvariance channels[4] = {
+ {index_of_channel(a), b->variance.a},
+ {index_of_channel(r), b->variance.r},
+ {index_of_channel(g), b->variance.g},
+ {index_of_channel(b), b->variance.b},
+ };
+
+ qsort(channels, 4, sizeof(channels[0]), comparevariance);
+
+ const unsigned int ind1 = b->ind;
+ const unsigned int colors = b->colors;
+#if __GNUC__ >= 9 || __clang__
+ #pragma omp parallel for if (colors > 25000) \
+ schedule(static) default(none) shared(achv, channels, colors, ind1)
+#else
+ #pragma omp parallel for if (colors > 25000) \
+ schedule(static) default(none) shared(achv, channels)
+#endif
+ for(unsigned int i=0; i < colors; i++) {
+ const float *chans = (const float *)&achv[ind1 + i].acolor;
+ // Only the first channel really matters. When trying median cut many times
+ // with different histogram weights, I don't want sort randomness to influence outcome.
+ achv[ind1 + i].tmp.sort_value = ((unsigned int)(chans[channels[0].chan]*65535.0)<<16) |
+ (unsigned int)((chans[channels[2].chan] + chans[channels[1].chan]/2.0 + chans[channels[3].chan]/4.0)*65535.0);
+ }
+
+ const f_pixel median = get_median(b, achv);
+
+ // box will be split to make color_weight of each side even
+ const unsigned int ind = b->ind, end = ind+b->colors;
+ double totalvar = 0;
+ #pragma omp parallel for if (end - ind > 15000) \
+ schedule(static) default(shared) reduction(+:totalvar)
+ for(unsigned int j=ind; j < end; j++) totalvar += (achv[j].color_weight = color_weight(median, achv[j]));
+ return totalvar / 2.0;
+}
+
+/** finds median in unsorted set by sorting only minimum required */
+static f_pixel get_median(const struct box *b, hist_item achv[])
+{
+ const unsigned int median_start = (b->colors-1)/2;
+
+ hist_item_sort_range(&(achv[b->ind]), b->colors,
+ median_start);
+
+ if (b->colors&1) return achv[b->ind + median_start].acolor;
+
+ // technically the second color is not guaranteed to be sorted correctly
+ // but most of the time it is good enough to be useful
+ return averagepixels(2, &achv[b->ind + median_start]);
+}
+
+/*
+ ** Find the best splittable box. -1 if no boxes are splittable.
+ */
+static int best_splittable_box(struct box bv[], unsigned int boxes, const double max_mse)
+{
+ int bi=-1; double maxsum=0;
+ for(unsigned int i=0; i < boxes; i++) {
+ if (bv[i].colors < 2) {
+ continue;
+ }
+
+ // looks only at max variance, because it's only going to split by it
+ const double cv = MAX(bv[i].variance.r, MAX(bv[i].variance.g,bv[i].variance.b));
+ double thissum = bv[i].sum * MAX(bv[i].variance.a, cv);
+
+ if (bv[i].max_error > max_mse) {
+ thissum = thissum* bv[i].max_error/max_mse;
+ }
+
+ if (thissum > maxsum) {
+ maxsum = thissum;
+ bi = i;
+ }
+ }
+ return bi;
+}
+
+inline static double color_weight(f_pixel median, hist_item h)
+{
+ float diff = colordifference(median, h.acolor);
+ return sqrt(diff) * (sqrt(1.0+h.adjusted_weight)-1.0);
+}
+
+static void set_colormap_from_boxes(colormap *map, struct box bv[], unsigned int boxes, hist_item *achv);
+static void adjust_histogram(hist_item *achv, const struct box bv[], unsigned int boxes);
+
+static double box_error(const struct box *box, const hist_item achv[])
+{
+ f_pixel avg = box->color;
+
+ double total_error=0;
+ for (unsigned int i = 0; i < box->colors; ++i) {
+ total_error += colordifference(avg, achv[box->ind + i].acolor) * achv[box->ind + i].perceptual_weight;
+ }
+
+ return total_error;
+}
+
+
+static bool total_box_error_below_target(double target_mse, struct box bv[], unsigned int boxes, const histogram *hist)
+{
+ target_mse *= hist->total_perceptual_weight;
+ double total_error=0;
+
+ for(unsigned int i=0; i < boxes; i++) {
+ // error is (re)calculated lazily
+ if (bv[i].total_error >= 0) {
+ total_error += bv[i].total_error;
+ }
+ if (total_error > target_mse) return false;
+ }
+
+ for(unsigned int i=0; i < boxes; i++) {
+ if (bv[i].total_error < 0) {
+ bv[i].total_error = box_error(&bv[i], hist->achv);
+ total_error += bv[i].total_error;
+ }
+ if (total_error > target_mse) return false;
+ }
+
+ return true;
+}
+
+static void box_init(struct box *box, const hist_item *achv, const unsigned int ind, const unsigned int colors, const double sum) {
+ assert(colors > 0);
+ assert(sum > 0);
+
+ box->ind = ind;
+ box->colors = colors;
+ box->sum = sum;
+ box->total_error = -1;
+
+ box->color = averagepixels(colors, &achv[ind]);
+ box->variance = box_variance(achv, box);
+ box->max_error = box_max_error(achv, box);
+}
+
+/*
+ ** Here is the fun part, the median-cut colormap generator. This is based
+ ** on Paul Heckbert's paper, "Color Image Quantization for Frame Buffer
+ ** Display," SIGGRAPH 1982 Proceedings, page 297.
+ */
+LIQ_PRIVATE colormap *mediancut(histogram *hist, unsigned int newcolors, const double target_mse, const double max_mse, void* (*malloc)(size_t), void (*free)(void*))
+{
+ hist_item *achv = hist->achv;
+ struct box bv[newcolors+16];
+
+ assert(hist->boxes[0].begin == 0);
+ assert(hist->boxes[LIQ_MAXCLUSTER-1].end == hist->size);
+
+ unsigned int boxes = 0;
+ for(int b=0; b < LIQ_MAXCLUSTER; b++) {
+ int begin = hist->boxes[b].begin;
+ int end = hist->boxes[b].end;
+ if (begin == end) {
+ continue;
+ }
+
+ if (boxes >= newcolors/3) {
+ boxes = 0;
+ begin = 0;
+ end = hist->boxes[LIQ_MAXCLUSTER-1].end;
+ b = LIQ_MAXCLUSTER;
+ }
+
+ double sum = 0;
+ for(int i=begin; i < end; i++) {
+ sum += achv[i].adjusted_weight;
+ }
+ box_init(&bv[boxes], achv, begin, end-begin, sum);
+ boxes++;
+ }
+
+ assert(boxes < newcolors);
+
+
+ /*
+ ** Main loop: split boxes until we have enough.
+ */
+ while (boxes < newcolors) {
+
+ // first splits boxes that exceed quality limit (to have colors for things like odd green pixel),
+ // later raises the limit to allow large smooth areas/gradients get colors.
+ const double current_max_mse = max_mse + (boxes/(double)newcolors)*16.0*max_mse;
+ const int bi = best_splittable_box(bv, boxes, current_max_mse);
+ if (bi < 0) {
+ break; /* ran out of colors! */
+ }
+
+ unsigned int indx = bv[bi].ind;
+ unsigned int clrs = bv[bi].colors;
+
+ /*
+ Classic implementation tries to get even number of colors or pixels in each subdivision.
+
+ Here, instead of popularity I use (sqrt(popularity)*variance) metric.
+ Each subdivision balances number of pixels (popular colors) and low variance -
+ boxes can be large if they have similar colors. Later boxes with high variance
+ will be more likely to be split.
+
+ Median used as expected value gives much better results than mean.
+ */
+
+ const double halfvar = prepare_sort(&bv[bi], achv);
+
+ // hist_item_sort_halfvar sorts and sums lowervar at the same time
+ // returns item to break at …minus one, which does smell like an off-by-one error.
+ unsigned int break_at = hist_item_sort_halfvar(&achv[indx], clrs, halfvar);
+ break_at = MIN(clrs-1, break_at + 1);
+
+ /*
+ ** Split the box.
+ */
+ double sm = bv[bi].sum;
+ double lowersum = 0;
+ for(unsigned int i=0; i < break_at; i++) lowersum += achv[indx + i].adjusted_weight;
+
+ box_init(&bv[bi], achv, indx, break_at, lowersum);
+ box_init(&bv[boxes], achv, indx + break_at, clrs - break_at, sm - lowersum);
+
+ ++boxes;
+
+ if (total_box_error_below_target(target_mse, bv, boxes, hist)) {
+ break;
+ }
+ }
+
+ colormap *map = pam_colormap(boxes, malloc, free);
+ set_colormap_from_boxes(map, bv, boxes, achv);
+
+ adjust_histogram(achv, bv, boxes);
+
+ return map;
+}
+
+static void set_colormap_from_boxes(colormap *map, struct box* bv, unsigned int boxes, hist_item *achv)
+{
+ /*
+ ** Ok, we've got enough boxes. Now choose a representative color for
+ ** each box. There are a number of possible ways to make this choice.
+ ** One would be to choose the center of the box; this ignores any structure
+ ** within the boxes. Another method would be to average all the colors in
+ ** the box - this is the method specified in Heckbert's paper.
+ */
+
+ for(unsigned int bi = 0; bi < boxes; ++bi) {
+ map->palette[bi].acolor = bv[bi].color;
+
+ /* store total color popularity (perceptual_weight is approximation of it) */
+ map->palette[bi].popularity = 0;
+ for(unsigned int i=bv[bi].ind; i < bv[bi].ind+bv[bi].colors; i++) {
+ map->palette[bi].popularity += achv[i].perceptual_weight;
+ }
+ }
+}
+
+/* increase histogram popularity by difference from the final color (this is used as part of feedback loop) */
+static void adjust_histogram(hist_item *achv, const struct box* bv, unsigned int boxes)
+{
+ for(unsigned int bi = 0; bi < boxes; ++bi) {
+ for(unsigned int i=bv[bi].ind; i < bv[bi].ind+bv[bi].colors; i++) {
+ achv[i].tmp.likely_colormap_index = bi;
+ }
+ }
+}
+
+static f_pixel averagepixels(unsigned int clrs, const hist_item achv[])
+{
+ double r = 0, g = 0, b = 0, a = 0, sum = 0;
+
+ #pragma omp parallel for if (clrs > 25000) \
+ schedule(static) default(shared) reduction(+:a) reduction(+:r) reduction(+:g) reduction(+:b) reduction(+:sum)
+ for(unsigned int i = 0; i < clrs; i++) {
+ const f_pixel px = achv[i].acolor;
+ const double weight = achv[i].adjusted_weight;
+
+ sum += weight;
+ a += px.a * weight;
+ r += px.r * weight;
+ g += px.g * weight;
+ b += px.b * weight;
+ }
+
+ if (sum) {
+ a /= sum;
+ r /= sum;
+ g /= sum;
+ b /= sum;
+ }
+
+ assert(!isnan(r) && !isnan(g) && !isnan(b) && !isnan(a));
+
+ return (f_pixel){.r=r, .g=g, .b=b, .a=a};
+}
diff --git a/tools/assets/n64texconv/lib/libimagequant/mediancut.h b/tools/assets/n64texconv/lib/libimagequant/mediancut.h
new file mode 100644
index 000000000..9a4cb534b
--- /dev/null
+++ b/tools/assets/n64texconv/lib/libimagequant/mediancut.h
@@ -0,0 +1,6 @@
+#ifndef MEDIANCUT_H
+#define MEDIANCUT_H
+
+LIQ_PRIVATE colormap *mediancut(histogram *hist, unsigned int newcolors, const double target_mse, const double max_mse, void* (*malloc)(size_t), void (*free)(void*));
+
+#endif
diff --git a/tools/assets/n64texconv/lib/libimagequant/mempool.c b/tools/assets/n64texconv/lib/libimagequant/mempool.c
new file mode 100644
index 000000000..cd49f59a2
--- /dev/null
+++ b/tools/assets/n64texconv/lib/libimagequant/mempool.c
@@ -0,0 +1,70 @@
+/*
+** © 2009-2017 by Kornel Lesiński.
+** © 1989, 1991 by Jef Poskanzer.
+** © 1997, 2000, 2002 by Greg Roelofs; based on an idea by Stefan Schneider.
+**
+** See COPYRIGHT file for license.
+*/
+
+#include "libimagequant.h"
+#include "mempool.h"
+#include
+#include
+#include
+
+#define ALIGN_MASK 15UL
+#define MEMPOOL_RESERVED ((sizeof(struct mempool)+ALIGN_MASK) & ~ALIGN_MASK)
+
+struct mempool {
+ unsigned int used, size;
+ void* (*malloc)(size_t);
+ void (*free)(void*);
+ struct mempool *next;
+};
+LIQ_PRIVATE void* mempool_create(mempoolptr *mptr, const unsigned int size, unsigned int max_size, void* (*malloc)(size_t), void (*free)(void*))
+{
+ if (*mptr && ((*mptr)->used+size) <= (*mptr)->size) {
+ unsigned int prevused = (*mptr)->used;
+ (*mptr)->used += (size+15UL) & ~0xFUL;
+ return ((char*)(*mptr)) + prevused;
+ }
+
+ mempoolptr old = *mptr;
+ if (!max_size) max_size = (1<<17);
+ max_size = size+ALIGN_MASK > max_size ? size+ALIGN_MASK : max_size;
+
+ *mptr = malloc(MEMPOOL_RESERVED + max_size);
+ if (!*mptr) return NULL;
+ **mptr = (struct mempool){
+ .malloc = malloc,
+ .free = free,
+ .size = MEMPOOL_RESERVED + max_size,
+ .used = sizeof(struct mempool),
+ .next = old,
+ };
+ uintptr_t mptr_used_start = (uintptr_t)(*mptr) + (*mptr)->used;
+ (*mptr)->used += (ALIGN_MASK + 1 - (mptr_used_start & ALIGN_MASK)) & ALIGN_MASK; // reserve bytes required to make subsequent allocations aligned
+ assert(!(((uintptr_t)(*mptr) + (*mptr)->used) & ALIGN_MASK));
+
+ return mempool_alloc(mptr, size, size);
+}
+
+LIQ_PRIVATE void* mempool_alloc(mempoolptr *mptr, const unsigned int size, const unsigned int max_size)
+{
+ if (((*mptr)->used+size) <= (*mptr)->size) {
+ unsigned int prevused = (*mptr)->used;
+ (*mptr)->used += (size + ALIGN_MASK) & ~ALIGN_MASK;
+ return ((char*)(*mptr)) + prevused;
+ }
+
+ return mempool_create(mptr, size, max_size, (*mptr)->malloc, (*mptr)->free);
+}
+
+LIQ_PRIVATE void mempool_destroy(mempoolptr m)
+{
+ while (m) {
+ mempoolptr next = m->next;
+ m->free(m);
+ m = next;
+ }
+}
diff --git a/tools/assets/n64texconv/lib/libimagequant/mempool.h b/tools/assets/n64texconv/lib/libimagequant/mempool.h
new file mode 100644
index 000000000..9b7333b11
--- /dev/null
+++ b/tools/assets/n64texconv/lib/libimagequant/mempool.h
@@ -0,0 +1,13 @@
+#ifndef MEMPOOL_H
+#define MEMPOOL_H
+
+#include
+
+struct mempool;
+typedef struct mempool *mempoolptr;
+
+LIQ_PRIVATE void* mempool_create(mempoolptr *mptr, const unsigned int size, unsigned int capacity, void* (*malloc)(size_t), void (*free)(void*));
+LIQ_PRIVATE void* mempool_alloc(mempoolptr *mptr, const unsigned int size, const unsigned int capacity);
+LIQ_PRIVATE void mempool_destroy(mempoolptr m);
+
+#endif
diff --git a/tools/assets/n64texconv/lib/libimagequant/nearest.c b/tools/assets/n64texconv/lib/libimagequant/nearest.c
new file mode 100644
index 000000000..7c8ee6af0
--- /dev/null
+++ b/tools/assets/n64texconv/lib/libimagequant/nearest.c
@@ -0,0 +1,230 @@
+/*
+** © 2009-2015 by Kornel Lesiński.
+** © 1989, 1991 by Jef Poskanzer.
+** © 1997, 2000, 2002 by Greg Roelofs; based on an idea by Stefan Schneider.
+**
+** See COPYRIGHT file for license.
+*/
+
+#include "libimagequant.h"
+#include "pam.h"
+#include "nearest.h"
+#include "mempool.h"
+#include
+
+typedef struct vp_sort_tmp {
+ float distance_squared;
+ unsigned int idx;
+} vp_sort_tmp;
+
+typedef struct vp_search_tmp {
+ float distance;
+ float distance_squared;
+ unsigned int idx;
+ int exclude;
+} vp_search_tmp;
+
+struct leaf {
+ f_pixel color;
+ unsigned int idx;
+};
+
+typedef struct vp_node {
+ struct vp_node *near, *far;
+ f_pixel vantage_point;
+ float radius, radius_squared;
+ struct leaf *rest;
+ unsigned short idx;
+ unsigned short restcount;
+} vp_node;
+
+struct nearest_map {
+ vp_node *root;
+ const colormap_item *palette;
+ float nearest_other_color_dist[256];
+ mempoolptr mempool;
+};
+
+static void vp_search_node(const vp_node *node, const f_pixel *const needle, vp_search_tmp *const best_candidate);
+
+static int vp_compare_distance(const void *ap, const void *bp) {
+ float a = ((const vp_sort_tmp*)ap)->distance_squared;
+ float b = ((const vp_sort_tmp*)bp)->distance_squared;
+ return a > b ? 1 : -1;
+}
+
+static void vp_sort_indexes_by_distance(const f_pixel vantage_point, vp_sort_tmp indexes[], int num_indexes, const colormap_item items[]) {
+ for(int i=0; i < num_indexes; i++) {
+ indexes[i].distance_squared = colordifference(vantage_point, items[indexes[i].idx].acolor);
+ }
+ qsort(indexes, num_indexes, sizeof(indexes[0]), vp_compare_distance);
+}
+
+/*
+ * Usually it should pick farthest point, but picking most popular point seems to make search quicker anyway
+ */
+static int vp_find_best_vantage_point_index(vp_sort_tmp indexes[], int num_indexes, const colormap_item items[]) {
+ int best = 0;
+ float best_popularity = items[indexes[0].idx].popularity;
+ for(int i = 1; i < num_indexes; i++) {
+ if (items[indexes[i].idx].popularity > best_popularity) {
+ best_popularity = items[indexes[i].idx].popularity;
+ best = i;
+ }
+ }
+ return best;
+}
+
+static vp_node *vp_create_node(mempoolptr *m, vp_sort_tmp indexes[], int num_indexes, const colormap_item items[]) {
+ if (num_indexes <= 0) {
+ return NULL;
+ }
+
+ vp_node *node = mempool_alloc(m, sizeof(node[0]), 0);
+
+ if (num_indexes == 1) {
+ *node = (vp_node){
+ .vantage_point = items[indexes[0].idx].acolor,
+ .idx = indexes[0].idx,
+ .radius = MAX_DIFF,
+ .radius_squared = MAX_DIFF,
+ };
+ return node;
+ }
+
+ const int ref = vp_find_best_vantage_point_index(indexes, num_indexes, items);
+ const int ref_idx = indexes[ref].idx;
+
+ // Removes the `ref_idx` item from remaining items, because it's included in the current node
+ num_indexes -= 1;
+ indexes[ref] = indexes[num_indexes];
+
+ vp_sort_indexes_by_distance(items[ref_idx].acolor, indexes, num_indexes, items);
+
+ // Remaining items are split by the median distance
+ const int half_idx = num_indexes/2;
+
+ *node = (vp_node){
+ .vantage_point = items[ref_idx].acolor,
+ .idx = ref_idx,
+ .radius = sqrtf(indexes[half_idx].distance_squared),
+ .radius_squared = indexes[half_idx].distance_squared,
+ };
+ if (num_indexes < 7) {
+ node->rest = mempool_alloc(m, sizeof(node->rest[0]) * num_indexes, 0);
+ node->restcount = num_indexes;
+ for(int i=0; i < num_indexes; i++) {
+ node->rest[i].idx = indexes[i].idx;
+ node->rest[i].color = items[indexes[i].idx].acolor;
+ }
+ } else {
+ node->near = vp_create_node(m, indexes, half_idx, items);
+ node->far = vp_create_node(m, &indexes[half_idx], num_indexes - half_idx, items);
+ }
+
+ return node;
+}
+
+LIQ_PRIVATE struct nearest_map *nearest_init(const colormap *map) {
+ mempoolptr m = NULL;
+ struct nearest_map *handle = mempool_create(&m, sizeof(handle[0]), sizeof(handle[0]) + sizeof(vp_node)*map->colors+16, map->malloc, map->free);
+
+ LIQ_ARRAY(vp_sort_tmp, indexes, map->colors);
+
+ for(unsigned int i=0; i < map->colors; i++) {
+ indexes[i].idx = i;
+ }
+
+ vp_node *root = vp_create_node(&m, indexes, map->colors, map->palette);
+ *handle = (struct nearest_map){
+ .root = root,
+ .palette = map->palette,
+ .mempool = m,
+ };
+
+ for(unsigned int i=0; i < map->colors; i++) {
+ vp_search_tmp best = {
+ .distance = MAX_DIFF,
+ .distance_squared = MAX_DIFF,
+ .exclude = i,
+ };
+ vp_search_node(root, &map->palette[i].acolor, &best);
+ handle->nearest_other_color_dist[i] = best.distance * best.distance / 4.f; // half of squared distance
+ }
+
+ return handle;
+}
+
+static void vp_search_node(const vp_node *node, const f_pixel *const needle, vp_search_tmp *const best_candidate) {
+ do {
+ const float distance_squared = colordifference(node->vantage_point, *needle);
+ const float distance = sqrtf(distance_squared);
+
+ if (distance_squared < best_candidate->distance_squared && best_candidate->exclude != node->idx) {
+ best_candidate->distance = distance;
+ best_candidate->distance_squared = distance_squared;
+ best_candidate->idx = node->idx;
+ }
+
+ if (node->restcount) {
+ for(int i=0; i < node->restcount; i++) {
+ const float distance_squared = colordifference(node->rest[i].color, *needle);
+ if (distance_squared < best_candidate->distance_squared && best_candidate->exclude != node->rest[i].idx) {
+ best_candidate->distance = sqrtf(distance_squared);
+ best_candidate->distance_squared = distance_squared;
+ best_candidate->idx = node->rest[i].idx;
+ }
+ }
+ return;
+ }
+
+ // Recurse towards most likely candidate first to narrow best candidate's distance as soon as possible
+ if (distance_squared < node->radius_squared) {
+ if (node->near) {
+ vp_search_node(node->near, needle, best_candidate);
+ }
+ // The best node (final answer) may be just ouside the radius, but not farther than
+ // the best distance we know so far. The vp_search_node above should have narrowed
+ // best_candidate->distance, so this path is rarely taken.
+ if (node->far && distance >= node->radius - best_candidate->distance) {
+ node = node->far; // Fast tail recursion
+ } else {
+ return;
+ }
+ } else {
+ if (node->far) {
+ vp_search_node(node->far, needle, best_candidate);
+ }
+ if (node->near && distance <= node->radius + best_candidate->distance) {
+ node = node->near; // Fast tail recursion
+ } else {
+ return;
+ }
+ }
+ } while(true);
+}
+
+LIQ_PRIVATE unsigned int nearest_search(const struct nearest_map *handle, const f_pixel *px, const int likely_colormap_index, float *diff) {
+ const float guess_diff = colordifference(handle->palette[likely_colormap_index].acolor, *px);
+ if (guess_diff < handle->nearest_other_color_dist[likely_colormap_index]) {
+ if (diff) *diff = guess_diff;
+ return likely_colormap_index;
+ }
+
+ vp_search_tmp best_candidate = {
+ .distance = sqrtf(guess_diff),
+ .distance_squared = guess_diff,
+ .idx = likely_colormap_index,
+ .exclude = -1,
+ };
+ vp_search_node(handle->root, px, &best_candidate);
+ if (diff) {
+ *diff = best_candidate.distance * best_candidate.distance;
+ }
+ return best_candidate.idx;
+}
+
+LIQ_PRIVATE void nearest_free(struct nearest_map *centroids)
+{
+ mempool_destroy(centroids->mempool);
+}
diff --git a/tools/assets/n64texconv/lib/libimagequant/nearest.h b/tools/assets/n64texconv/lib/libimagequant/nearest.h
new file mode 100644
index 000000000..10a0a2c1b
--- /dev/null
+++ b/tools/assets/n64texconv/lib/libimagequant/nearest.h
@@ -0,0 +1,14 @@
+//
+// nearest.h
+// pngquant
+//
+
+#ifndef NEAREST_H
+#define NEAREST_H
+
+struct nearest_map;
+LIQ_PRIVATE struct nearest_map *nearest_init(const colormap *palette);
+LIQ_PRIVATE unsigned int nearest_search(const struct nearest_map *map, const f_pixel *px, const int palette_index_guess, float *diff);
+LIQ_PRIVATE void nearest_free(struct nearest_map *map);
+
+#endif
diff --git a/tools/assets/n64texconv/lib/libimagequant/pam.c b/tools/assets/n64texconv/lib/libimagequant/pam.c
new file mode 100644
index 000000000..5d955e1eb
--- /dev/null
+++ b/tools/assets/n64texconv/lib/libimagequant/pam.c
@@ -0,0 +1,351 @@
+/* pam.c - pam (portable alpha map) utility library
+**
+** © 2009-2017 by Kornel Lesiński.
+** © 1989, 1991 by Jef Poskanzer.
+** © 1997, 2000, 2002 by Greg Roelofs; based on an idea by Stefan Schneider.
+**
+** See COPYRIGHT file for license.
+*/
+
+#include
+#include
+
+#include "libimagequant.h"
+#include "pam.h"
+#include "mempool.h"
+
+LIQ_PRIVATE bool pam_computeacolorhash(struct acolorhash_table *acht, const liq_color *const pixels[], unsigned int cols, unsigned int rows, const unsigned char *importance_map)
+{
+ const unsigned int ignorebits = acht->ignorebits;
+ const unsigned int channel_mask = 255U>>ignorebits<>ignorebits) ^ 0xFFU;
+ const unsigned int posterize_mask = channel_mask << 24 | channel_mask << 16 | channel_mask << 8 | channel_mask;
+ const unsigned int posterize_high_mask = channel_hmask << 24 | channel_hmask << 16 | channel_hmask << 8 | channel_hmask;
+
+ const unsigned int hash_size = acht->hash_size;
+
+ /* Go through the entire image, building a hash table of colors. */
+ for(unsigned int row = 0; row < rows; ++row) {
+
+ for(unsigned int col = 0; col < cols; ++col) {
+ unsigned int boost;
+
+ // RGBA color is casted to long for easier hasing/comparisons
+ union rgba_as_int px = {pixels[row][col]};
+ unsigned int hash;
+ if (px.rgba.a) {
+ // mask posterizes all 4 channels in one go
+ px.l = (px.l & posterize_mask) | ((px.l & posterize_high_mask) >> (8-ignorebits));
+ // fancier hashing algorithms didn't improve much
+ hash = px.l % hash_size;
+
+ if (importance_map) {
+ boost = *importance_map++;
+ } else {
+ boost = 255;
+ }
+ } else {
+ // "dirty alpha" has different RGBA values that end up being the same fully transparent color
+ px.l=0; hash=0;
+
+ boost = 2000;
+ if (importance_map) {
+ importance_map++;
+ }
+ }
+
+ if (!pam_add_to_hash(acht, hash, boost, px, row, rows)) {
+ return false;
+ }
+ }
+ }
+ acht->cols = cols;
+ acht->rows += rows;
+ return true;
+}
+
+LIQ_PRIVATE bool pam_add_to_hash(struct acolorhash_table *acht, unsigned int hash, unsigned int boost, union rgba_as_int px, unsigned int row, unsigned int rows)
+{
+ /* head of the hash function stores first 2 colors inline (achl->used = 1..2),
+ to reduce number of allocations of achl->other_items.
+ */
+ struct acolorhist_arr_head *achl = &acht->buckets[hash];
+ if (achl->inline1.color.l == px.l && achl->used) {
+ achl->inline1.perceptual_weight += boost;
+ return true;
+ }
+ if (achl->used) {
+ if (achl->used > 1) {
+ if (achl->inline2.color.l == px.l) {
+ achl->inline2.perceptual_weight += boost;
+ return true;
+ }
+ // other items are stored as an array (which gets reallocated if needed)
+ struct acolorhist_arr_item *other_items = achl->other_items;
+ unsigned int i = 0;
+ for (; i < achl->used-2; i++) {
+ if (other_items[i].color.l == px.l) {
+ other_items[i].perceptual_weight += boost;
+ return true;
+ }
+ }
+
+ // the array was allocated with spare items
+ if (i < achl->capacity) {
+ other_items[i] = (struct acolorhist_arr_item){
+ .color = px,
+ .perceptual_weight = boost,
+ };
+ achl->used++;
+ ++acht->colors;
+ return true;
+ }
+
+ if (++acht->colors > acht->maxcolors) {
+ return false;
+ }
+
+ struct acolorhist_arr_item *new_items;
+ unsigned int capacity;
+ if (!other_items) { // there was no array previously, alloc "small" array
+ capacity = 8;
+ if (acht->freestackp <= 0) {
+ // estimate how many colors are going to be + headroom
+ const size_t mempool_size = ((acht->rows + rows-row) * 2 * acht->colors / (acht->rows + row + 1) + 1024) * sizeof(struct acolorhist_arr_item);
+ new_items = mempool_alloc(&acht->mempool, sizeof(struct acolorhist_arr_item)*capacity, mempool_size);
+ } else {
+ // freestack stores previously freed (reallocated) arrays that can be reused
+ // (all pesimistically assumed to be capacity = 8)
+ new_items = acht->freestack[--acht->freestackp];
+ }
+ } else {
+ const unsigned int stacksize = sizeof(acht->freestack)/sizeof(acht->freestack[0]);
+
+ // simply reallocs and copies array to larger capacity
+ capacity = achl->capacity*2 + 16;
+ if (acht->freestackp < stacksize-1) {
+ acht->freestack[acht->freestackp++] = other_items;
+ }
+ const size_t mempool_size = ((acht->rows + rows-row) * 2 * acht->colors / (acht->rows + row + 1) + 32*capacity) * sizeof(struct acolorhist_arr_item);
+ new_items = mempool_alloc(&acht->mempool, sizeof(struct acolorhist_arr_item)*capacity, mempool_size);
+ if (!new_items) return false;
+ memcpy(new_items, other_items, sizeof(other_items[0])*achl->capacity);
+ }
+
+ achl->other_items = new_items;
+ achl->capacity = capacity;
+ new_items[i] = (struct acolorhist_arr_item){
+ .color = px,
+ .perceptual_weight = boost,
+ };
+ achl->used++;
+ } else {
+ // these are elses for first checks whether first and second inline-stored colors are used
+ achl->inline2.color.l = px.l;
+ achl->inline2.perceptual_weight = boost;
+ achl->used = 2;
+ ++acht->colors;
+ }
+ } else {
+ achl->inline1.color.l = px.l;
+ achl->inline1.perceptual_weight = boost;
+ achl->used = 1;
+ ++acht->colors;
+ }
+ return true;
+}
+
+LIQ_PRIVATE struct acolorhash_table *pam_allocacolorhash(unsigned int maxcolors, unsigned int surface, unsigned int ignorebits, void* (*malloc)(size_t), void (*free)(void*))
+{
+ const size_t estimated_colors = MIN(maxcolors, surface/(ignorebits + (surface > 512*512 ? 6 : 5)));
+ const size_t hash_size = estimated_colors < 66000 ? 6673 : (estimated_colors < 200000 ? 12011 : 24019);
+
+ mempoolptr m = NULL;
+ const size_t buckets_size = hash_size * sizeof(struct acolorhist_arr_head);
+ const size_t mempool_size = sizeof(struct acolorhash_table) + buckets_size + estimated_colors * sizeof(struct acolorhist_arr_item);
+ struct acolorhash_table *t = mempool_create(&m, sizeof(*t) + buckets_size, mempool_size, malloc, free);
+ if (!t) return NULL;
+ *t = (struct acolorhash_table){
+ .mempool = m,
+ .hash_size = hash_size,
+ .maxcolors = maxcolors,
+ .ignorebits = ignorebits,
+ };
+ memset(t->buckets, 0, buckets_size);
+ return t;
+}
+
+ALWAYS_INLINE static float pam_add_to_hist(struct temp_hist_item achv[], unsigned int *j, const struct acolorhist_arr_item *entry, const float max_perceptual_weight, int counts[])
+{
+ if (entry->perceptual_weight == 0 && *j > 0) {
+ return 0;
+ }
+ const liq_color px = entry->color.rgba;
+ achv[*j].color = px;
+ const short cluster = ((px.r>>7)<<3) | ((px.g>>7)<<2) | ((px.b>>7)<<1) | (px.a>>7);
+ counts[cluster]++;
+ achv[*j].cluster = cluster;
+ const float w = MIN(entry->perceptual_weight/170.f, max_perceptual_weight);
+ achv[*j].weight = w;
+ *j += 1;
+ return w;
+}
+
+LIQ_PRIVATE histogram *pam_acolorhashtoacolorhist(const struct acolorhash_table *acht, const double gamma, void* (*malloc)(size_t), void (*free)(void*))
+{
+ histogram *hist = malloc(sizeof(hist[0]));
+ if (!hist || !acht) return NULL;
+ *hist = (histogram){
+ .achv = malloc(MAX(1,acht->colors) * sizeof(hist->achv[0])),
+ .size = acht->colors,
+ .free = free,
+ .ignorebits = acht->ignorebits,
+ };
+ if (!hist->achv) return NULL;
+
+ /// Clusters form initial boxes for quantization, to ensure extreme colors are better represented
+ int counts[LIQ_MAXCLUSTER] = {};
+ struct temp_hist_item *temp = malloc(MAX(1, acht->colors) * sizeof(temp[0]));
+
+ /* Limit perceptual weight to 1/10th of the image surface area to prevent
+ a single color from dominating all others. */
+ float max_perceptual_weight = 0.1f * acht->cols * acht->rows;
+ double total_weight = 0;
+
+ unsigned int j=0;
+ for(unsigned int i=0; i < acht->hash_size; ++i) {
+ const struct acolorhist_arr_head *const achl = &acht->buckets[i];
+ if (achl->used) {
+ total_weight += pam_add_to_hist(temp, &j, &achl->inline1, max_perceptual_weight, counts);
+
+ if (achl->used > 1) {
+ total_weight += pam_add_to_hist(temp, &j, &achl->inline2, max_perceptual_weight, counts);
+
+ for(unsigned int k=0; k < achl->used-2; k++) {
+ total_weight += pam_add_to_hist(temp, &j, &achl->other_items[k], max_perceptual_weight, counts);
+ }
+ }
+ }
+ }
+ hist->total_perceptual_weight = total_weight;
+
+ int begin = 0;
+ for(int i=0; i < LIQ_MAXCLUSTER; i++) {
+ hist->boxes[i].begin = begin;
+ hist->boxes[i].end = begin;
+ begin = begin + counts[i];
+ }
+
+ hist->size = j;
+ hist->total_perceptual_weight = total_weight;
+ for(unsigned int k=0; k < hist->size; k++) {
+ hist->achv[k].tmp.likely_colormap_index = 0;
+ }
+ if (!j) {
+ free(temp);
+ pam_freeacolorhist(hist);
+ return NULL;
+ }
+
+ float gamma_lut[256];
+ to_f_set_gamma(gamma_lut, gamma);
+ for(int i=0; i < hist->size; i++) {
+ int j = hist->boxes[temp[i].cluster].end++;
+ hist->achv[j].acolor = rgba_to_f(gamma_lut, temp[i].color);
+ hist->achv[j].perceptual_weight = temp[i].weight;
+ hist->achv[j].adjusted_weight = temp[i].weight;
+ }
+ free(temp);
+
+ return hist;
+}
+
+
+LIQ_PRIVATE void pam_freeacolorhash(struct acolorhash_table *acht)
+{
+ if (acht) {
+ mempool_destroy(acht->mempool);
+ }
+}
+
+LIQ_PRIVATE void pam_freeacolorhist(histogram *hist)
+{
+ hist->free(hist->achv);
+ hist->free(hist);
+}
+
+LIQ_PRIVATE LIQ_NONNULL colormap *pam_colormap(unsigned int colors, void* (*malloc)(size_t), void (*free)(void*))
+{
+ assert(colors > 0 && colors < 65536);
+
+ colormap *map;
+ const size_t colors_size = colors * sizeof(map->palette[0]);
+ map = malloc(sizeof(colormap) + colors_size);
+ if (!map) return NULL;
+ *map = (colormap){
+ .malloc = malloc,
+ .free = free,
+ .colors = colors,
+ };
+ memset(map->palette, 0, colors_size);
+ return map;
+}
+
+LIQ_PRIVATE colormap *pam_duplicate_colormap(colormap *map)
+{
+ colormap *dupe = pam_colormap(map->colors, map->malloc, map->free);
+ for(unsigned int i=0; i < map->colors; i++) {
+ dupe->palette[i] = map->palette[i];
+ }
+ return dupe;
+}
+
+LIQ_PRIVATE void pam_freecolormap(colormap *c)
+{
+ c->free(c);
+}
+
+LIQ_PRIVATE void to_f_set_gamma(float gamma_lut[], const double gamma)
+{
+ for(int i=0; i < 256; i++) {
+ gamma_lut[i] = pow((double)i/255.0, internal_gamma/gamma);
+ }
+}
+
+
+/* fixed colors are always included in the palette, so it would be wasteful to duplicate them in palette from histogram */
+LIQ_PRIVATE LIQ_NONNULL void remove_fixed_colors_from_histogram(histogram *hist, const int fixed_colors_count, const f_pixel fixed_colors[], const float target_mse)
+{
+ const float max_difference = MAX(target_mse/2.f, 2.f/256.f/256.f);
+ if (fixed_colors_count) {
+ for(int j=0; j < hist->size; j++) {
+ for(unsigned int i=0; i < fixed_colors_count; i++) {
+ if (colordifference(hist->achv[j].acolor, fixed_colors[i]) < max_difference) {
+ hist->achv[j] = hist->achv[--hist->size]; // remove color from histogram by overwriting with the last entry
+ j--; break; // continue searching histogram
+ }
+ }
+ }
+ }
+}
+
+LIQ_PRIVATE LIQ_NONNULL colormap *histogram_to_palette(const histogram *hist, void* (*malloc)(size_t), void (*free)(void*)) {
+ if (!hist->size) {
+ return NULL;
+ }
+ colormap *acolormap = pam_colormap(hist->size, malloc, free);
+ for(unsigned int i=0; i < hist->size; i++) {
+ acolormap->palette[i].acolor = hist->achv[i].acolor;
+ acolormap->palette[i].popularity = hist->achv[i].perceptual_weight;
+ }
+ return acolormap;
+}
+
+LIQ_PRIVATE LIQ_NONNULL void hist_reset_colors(const histogram *hist, const unsigned int colors) {
+ // likely_colormap_index (used and set in kmeans_do_iteration) can't point to index outside colormap
+ if (colors < 256) for(unsigned int j=0; j < hist->size; j++) {
+ if (hist->achv[j].tmp.likely_colormap_index >= colors) {
+ hist->achv[j].tmp.likely_colormap_index = 0; // actual value doesn't matter, as the guess is out of date anyway
+ }
+ }
+}
diff --git a/tools/assets/n64texconv/lib/libimagequant/pam.h b/tools/assets/n64texconv/lib/libimagequant/pam.h
new file mode 100644
index 000000000..4ab4e0de2
--- /dev/null
+++ b/tools/assets/n64texconv/lib/libimagequant/pam.h
@@ -0,0 +1,312 @@
+/* pam.h - pam (portable alpha map) utility library
+ **
+ ** Colormap routines.
+ **
+ ** Copyright (C) 1989, 1991 by Jef Poskanzer.
+ ** Copyright (C) 1997 by Greg Roelofs.
+ **
+ ** Permission to use, copy, modify, and distribute this software and its
+ ** documentation for any purpose and without fee is hereby granted, provided
+ ** that the above copyright notice appear in all copies and that both that
+ ** copyright notice and this permission notice appear in supporting
+ ** documentation. This software is provided "as is" without express or
+ ** implied warranty.
+ */
+
+#ifndef PAM_H
+#define PAM_H
+
+// accidental debug assertions make color search much slower,
+// so force assertions off if there's no explicit setting
+#if !defined(NDEBUG) && !defined(DEBUG)
+#define NDEBUG
+#endif
+
+#include
+#include
+#include
+#include
+
+#ifndef MAX
+# define MAX(a,b) ((a) > (b)? (a) : (b))
+# define MIN(a,b) ((a) < (b)? (a) : (b))
+#endif
+
+#define MAX_DIFF 1e20
+
+#ifndef USE_SSE
+# if defined(__SSE__) && (defined(__amd64__) || defined(__X86_64__) || defined(_WIN64) || defined(WIN32) || defined(__WIN32__))
+# define USE_SSE 1
+# else
+# define USE_SSE 0
+# endif
+#endif
+
+#if USE_SSE
+# include
+# ifdef _MSC_VER
+# include
+# define SSE_ALIGN
+# else
+# define SSE_ALIGN __attribute__ ((aligned (16)))
+# if defined(__i386__) && defined(__PIC__)
+# define cpuid(func,ax,bx,cx,dx)\
+ __asm__ __volatile__ ( \
+ "push %%ebx\n" \
+ "cpuid\n" \
+ "mov %%ebx, %1\n" \
+ "pop %%ebx\n" \
+ : "=a" (ax), "=r" (bx), "=c" (cx), "=d" (dx) \
+ : "a" (func));
+# else
+# define cpuid(func,ax,bx,cx,dx)\
+ __asm__ __volatile__ ("cpuid":\
+ "=a" (ax), "=b" (bx), "=c" (cx), "=d" (dx) : "a" (func));
+# endif
+#endif
+#else
+# define SSE_ALIGN
+#endif
+
+#ifndef _MSC_VER
+#define LIQ_ARRAY(type, var, count) type var[count]
+#else
+#define LIQ_ARRAY(type, var, count) type* var = (type*)_alloca(sizeof(type)*(count))
+#endif
+
+#if defined(__GNUC__) || defined (__llvm__)
+#define ALWAYS_INLINE __attribute__((always_inline)) inline
+#define NEVER_INLINE __attribute__ ((noinline))
+#elif defined(_MSC_VER)
+#define inline __inline
+#define restrict __restrict
+#define ALWAYS_INLINE __forceinline
+#define NEVER_INLINE __declspec(noinline)
+#else
+#define ALWAYS_INLINE inline
+#define NEVER_INLINE
+#endif
+
+/* from pam.h */
+
+typedef struct {
+ float a, r, g, b;
+} SSE_ALIGN f_pixel;
+
+static const float internal_gamma = 0.57f;
+
+LIQ_PRIVATE void to_f_set_gamma(float gamma_lut[], const double gamma);
+
+#define MIN_OPAQUE_A (1.f / 256.f * LIQ_WEIGHT_A)
+
+#define LIQ_WEIGHT_A 0.625f
+#define LIQ_WEIGHT_R 0.5f
+#define LIQ_WEIGHT_G 1.0f
+#define LIQ_WEIGHT_B 0.45f
+#define LIQ_WEIGHT_MSE 0.45 // fudge factor for compensating that colors aren't 0..1 range
+
+/**
+ Converts 8-bit color to internal gamma and premultiplied alpha.
+ (premultiplied color space is much better for blending of semitransparent colors)
+ */
+ALWAYS_INLINE static f_pixel rgba_to_f(const float gamma_lut[], const liq_color px);
+inline static f_pixel rgba_to_f(const float gamma_lut[], const liq_color px)
+{
+ float a = px.a/255.f;
+
+ return (f_pixel) {
+ .a = a * LIQ_WEIGHT_A,
+ .r = gamma_lut[px.r] * LIQ_WEIGHT_R * a,
+ .g = gamma_lut[px.g] * LIQ_WEIGHT_G * a,
+ .b = gamma_lut[px.b] * LIQ_WEIGHT_B * a,
+ };
+}
+
+inline static liq_color f_to_rgb(const float gamma, const f_pixel px)
+{
+ if (px.a < MIN_OPAQUE_A) {
+ return (liq_color){0,0,0,0};
+ }
+
+ float r = (LIQ_WEIGHT_A / LIQ_WEIGHT_R) * px.r / px.a,
+ g = (LIQ_WEIGHT_A / LIQ_WEIGHT_G) * px.g / px.a,
+ b = (LIQ_WEIGHT_A / LIQ_WEIGHT_B) * px.b / px.a;
+
+ r = powf(r, gamma/internal_gamma);
+ g = powf(g, gamma/internal_gamma);
+ b = powf(b, gamma/internal_gamma);
+
+ // 256, because numbers are in range 1..255.9999… rounded down
+ r *= 256.f;
+ g *= 256.f;
+ b *= 256.f;
+ float a = (256.f / LIQ_WEIGHT_A) * px.a;
+
+ return (liq_color){
+ .r = r>=255.f ? 255 : r,
+ .g = g>=255.f ? 255 : g,
+ .b = b>=255.f ? 255 : b,
+ .a = a>=255.f ? 255 : a,
+ };
+}
+
+ALWAYS_INLINE static float colordifference_ch(const float x, const float y, const float alphas);
+inline static float colordifference_ch(const float x, const float y, const float alphas)
+{
+ // maximum of channel blended on white, and blended on black
+ // premultiplied alpha and backgrounds 0/1 shorten the formula
+ const float black = x-y, white = black+alphas;
+ return MAX(black*black, white*white);
+}
+
+ALWAYS_INLINE static float colordifference_stdc(const f_pixel px, const f_pixel py);
+inline static float colordifference_stdc(const f_pixel px, const f_pixel py)
+{
+ // px_b.rgb = px.rgb + 0*(1-px.a) // blend px on black
+ // px_b.a = px.a + 1*(1-px.a)
+ // px_w.rgb = px.rgb + 1*(1-px.a) // blend px on white
+ // px_w.a = px.a + 1*(1-px.a)
+
+ // px_b.rgb = px.rgb // difference same as in opaque RGB
+ // px_b.a = 1
+ // px_w.rgb = px.rgb - px.a // difference simplifies to formula below
+ // px_w.a = 1
+
+ // (px.rgb - px.a) - (py.rgb - py.a)
+ // (px.rgb - py.rgb) + (py.a - px.a)
+
+ const float alphas = py.a-px.a;
+ return colordifference_ch(px.r, py.r, alphas) +
+ colordifference_ch(px.g, py.g, alphas) +
+ colordifference_ch(px.b, py.b, alphas);
+}
+
+ALWAYS_INLINE static float colordifference(f_pixel px, f_pixel py);
+inline static float colordifference(f_pixel px, f_pixel py)
+{
+#if USE_SSE
+#ifdef _MSC_VER
+ /* In MSVC we cannot use the align attribute in parameters.
+ * This is used a lot, so we just use an unaligned load.
+ * Also the compiler incorrectly inlines vpx and vpy without
+ * the volatile when optimization is applied for x86_64. */
+ const volatile __m128 vpx = _mm_loadu_ps((const float*)&px);
+ const volatile __m128 vpy = _mm_loadu_ps((const float*)&py);
+#else
+ const __m128 vpx = _mm_load_ps((const float*)&px);
+ const __m128 vpy = _mm_load_ps((const float*)&py);
+#endif
+
+ // y.a - x.a
+ __m128 alphas = _mm_sub_ss(vpy, vpx);
+ alphas = _mm_shuffle_ps(alphas,alphas,0); // copy first to all four
+
+ __m128 onblack = _mm_sub_ps(vpx, vpy); // x - y
+ __m128 onwhite = _mm_add_ps(onblack, alphas); // x - y + (y.a - x.a)
+
+ onblack = _mm_mul_ps(onblack, onblack);
+ onwhite = _mm_mul_ps(onwhite, onwhite);
+ const __m128 max = _mm_max_ps(onwhite, onblack);
+
+ // add rgb, not a
+ const __m128 maxhl = _mm_movehl_ps(max, max);
+ const __m128 tmp = _mm_add_ps(max, maxhl);
+ const __m128 sum = _mm_add_ss(maxhl, _mm_shuffle_ps(tmp, tmp, 1));
+
+ const float res = _mm_cvtss_f32(sum);
+ assert(fabs(res - colordifference_stdc(px,py)) < 0.001);
+ return res;
+#else
+ return colordifference_stdc(px,py);
+#endif
+}
+
+/* from pamcmap.h */
+union rgba_as_int {
+ liq_color rgba;
+ unsigned int l;
+};
+
+typedef struct {
+ f_pixel acolor;
+ float adjusted_weight, // perceptual weight changed to tweak how mediancut selects colors
+ perceptual_weight; // number of pixels weighted by importance of different areas of the picture
+
+ float color_weight; // these two change every time histogram subset is sorted
+ union {
+ unsigned int sort_value;
+ unsigned char likely_colormap_index;
+ } tmp;
+} hist_item;
+
+#define LIQ_MAXCLUSTER 16
+
+struct temp_hist_item {
+ liq_color color;
+ float weight;
+ short cluster;
+};
+
+struct histogram_box {
+ int begin, end;
+};
+
+typedef struct {
+ hist_item *achv;
+ void (*free)(void*);
+ double total_perceptual_weight;
+ unsigned int size;
+ unsigned int ignorebits;
+ struct histogram_box boxes[LIQ_MAXCLUSTER];
+} histogram;
+
+typedef struct {
+ f_pixel acolor;
+ float popularity;
+ bool fixed; // if true it's user-supplied and must not be changed (e.g in K-Means iteration)
+} colormap_item;
+
+typedef struct colormap {
+ unsigned int colors;
+ void* (*malloc)(size_t);
+ void (*free)(void*);
+ colormap_item palette[];
+} colormap;
+
+struct acolorhist_arr_item {
+ union rgba_as_int color;
+ unsigned int perceptual_weight;
+};
+
+struct acolorhist_arr_head {
+ struct acolorhist_arr_item inline1, inline2;
+ unsigned int used, capacity;
+ struct acolorhist_arr_item *other_items;
+};
+
+struct acolorhash_table {
+ struct mempool *mempool;
+ unsigned int ignorebits, maxcolors, colors, cols, rows;
+ unsigned int hash_size;
+ unsigned int freestackp;
+ struct acolorhist_arr_item *freestack[512];
+ struct acolorhist_arr_head buckets[];
+};
+
+LIQ_PRIVATE void pam_freeacolorhash(struct acolorhash_table *acht);
+LIQ_PRIVATE struct acolorhash_table *pam_allocacolorhash(unsigned int maxcolors, unsigned int surface, unsigned int ignorebits, void* (*malloc)(size_t), void (*free)(void*));
+LIQ_PRIVATE histogram *pam_acolorhashtoacolorhist(const struct acolorhash_table *acht, const double gamma, void* (*malloc)(size_t), void (*free)(void*));
+LIQ_PRIVATE bool pam_computeacolorhash(struct acolorhash_table *acht, const liq_color *const pixels[], unsigned int cols, unsigned int rows, const unsigned char *importance_map);
+LIQ_PRIVATE bool pam_add_to_hash(struct acolorhash_table *acht, unsigned int hash, unsigned int boost, union rgba_as_int px, unsigned int row, unsigned int rows);
+
+LIQ_PRIVATE void pam_freeacolorhist(histogram *h);
+
+LIQ_PRIVATE colormap *pam_colormap(unsigned int colors, void* (*malloc)(size_t), void (*free)(void*)) LIQ_NONNULL;
+LIQ_PRIVATE colormap *pam_duplicate_colormap(colormap *map) LIQ_NONNULL;
+LIQ_PRIVATE void pam_freecolormap(colormap *c);
+
+LIQ_PRIVATE void remove_fixed_colors_from_histogram(histogram *hist, const int fixed_colors_count, const f_pixel fixed_colors[], const float target_mse) LIQ_NONNULL;
+LIQ_PRIVATE colormap *histogram_to_palette(const histogram *hist, void* (*malloc)(size_t), void (*free)(void*)) LIQ_NONNULL;
+LIQ_PRIVATE void hist_reset_colors(const histogram *hist, const unsigned int colors) LIQ_NONNULL;
+
+#endif
diff --git a/tools/assets/n64texconv/lib/libimagequant/remap.c b/tools/assets/n64texconv/lib/libimagequant/remap.c
new file mode 100644
index 000000000..449581013
--- /dev/null
+++ b/tools/assets/n64texconv/lib/libimagequant/remap.c
@@ -0,0 +1,300 @@
+#include
+#include
+
+#include "libimagequant.h"
+#include "pam.h"
+#include "libimagequant_private.h"
+
+#include "nearest.h"
+#include "kmeans.h"
+
+LIQ_PRIVATE LIQ_NONNULL float remap_to_palette(liq_image *const input_image, unsigned char *const *const output_pixels, colormap *const map)
+{
+ const int rows = input_image->height;
+ const unsigned int cols = input_image->width;
+ double remapping_error=0;
+
+ if (!liq_image_get_row_f_init(input_image)) {
+ return -1;
+ }
+ if (input_image->background && !liq_image_get_row_f_init(input_image->background)) {
+ return -1;
+ }
+
+ const colormap_item *acolormap = map->palette;
+
+ struct nearest_map *const n = nearest_init(map);
+ liq_image *background = input_image->background;
+ const int transparent_index = background ? nearest_search(n, &(f_pixel){0,0,0,0}, 0, NULL) : -1;
+ if (background && acolormap[transparent_index].acolor.a > 1.f/256.f) {
+ // palette unsuitable for using the bg
+ background = NULL;
+ }
+
+
+ const unsigned int max_threads = omp_get_max_threads();
+ LIQ_ARRAY(kmeans_state, average_color, (KMEANS_CACHE_LINE_GAP+map->colors) * max_threads);
+ kmeans_init(map, max_threads, average_color);
+
+#if __GNUC__ >= 9 || __clang__
+ #pragma omp parallel for if (rows*cols > 3000) \
+ schedule(static) default(none) shared(background,acolormap,average_color,cols,input_image,map,n,output_pixels,rows,transparent_index) reduction(+:remapping_error)
+#endif
+ for(int row = 0; row < rows; ++row) {
+ const f_pixel *const row_pixels = liq_image_get_row_f(input_image, row);
+ const f_pixel *const bg_pixels = background && acolormap[transparent_index].acolor.a < MIN_OPAQUE_A ? liq_image_get_row_f(background, row) : NULL;
+
+ unsigned int last_match=0;
+ for(unsigned int col = 0; col < cols; ++col) {
+ float diff;
+ last_match = nearest_search(n, &row_pixels[col], last_match, &diff);
+ if (bg_pixels) {
+ float bg_diff = colordifference(bg_pixels[col], acolormap[last_match].acolor);
+ if (bg_diff <= diff) {
+ diff = bg_diff;
+ last_match = transparent_index;
+ }
+ }
+ output_pixels[row][col] = last_match;
+
+ remapping_error += diff;
+ if (last_match != transparent_index) {
+ kmeans_update_color(row_pixels[col], 1.0, map, last_match, omp_get_thread_num(), average_color);
+ }
+ }
+ }
+
+ kmeans_finalize(map, max_threads, average_color);
+
+ nearest_free(n);
+
+ return remapping_error / (input_image->width * input_image->height);
+}
+
+inline static f_pixel get_dithered_pixel(const float dither_level, const float max_dither_error, const f_pixel thiserr, const f_pixel px)
+{
+ /* Use Floyd-Steinberg errors to adjust actual color. */
+ const float sr = thiserr.r * dither_level,
+ sg = thiserr.g * dither_level,
+ sb = thiserr.b * dither_level,
+ sa = thiserr.a * dither_level;
+
+ float ratio = 1.0;
+ const float max_overflow = 1.1f;
+ const float max_underflow = -0.1f;
+
+ // allowing some overflow prevents undithered bands caused by clamping of all channels
+ if (px.r + sr > max_overflow) ratio = MIN(ratio, (max_overflow -px.r)/sr);
+ else { if (px.r + sr < max_underflow) ratio = MIN(ratio, (max_underflow-px.r)/sr); }
+ if (px.g + sg > max_overflow) ratio = MIN(ratio, (max_overflow -px.g)/sg);
+ else { if (px.g + sg < max_underflow) ratio = MIN(ratio, (max_underflow-px.g)/sg); }
+ if (px.b + sb > max_overflow) ratio = MIN(ratio, (max_overflow -px.b)/sb);
+ else { if (px.b + sb < max_underflow) ratio = MIN(ratio, (max_underflow-px.b)/sb); }
+
+ float a = px.a + sa;
+ if (a > 1.f) { a = 1.f; }
+ else if (a < 0) { a = 0; }
+
+ // If dithering error is crazy high, don't propagate it that much
+ // This prevents crazy geen pixels popping out of the blue (or red or black! ;)
+ const float dither_error = sr*sr + sg*sg + sb*sb + sa*sa;
+ if (dither_error > max_dither_error) {
+ ratio *= 0.8f;
+ } else if (dither_error < 2.f/256.f/256.f) {
+ // don't dither areas that don't have noticeable error — makes file smaller
+ return px;
+ }
+
+ return (f_pixel) {
+ .r=px.r + sr * ratio,
+ .g=px.g + sg * ratio,
+ .b=px.b + sb * ratio,
+ .a=a,
+ };
+}
+
+/**
+ Uses edge/noise map to apply dithering only to flat areas. Dithering on edges creates jagged lines, and noisy areas are "naturally" dithered.
+
+ If output_image_is_remapped is true, only pixels noticeably changed by error diffusion will be written to output image.
+ */
+LIQ_PRIVATE LIQ_NONNULL bool remap_to_palette_floyd(liq_image *input_image, unsigned char *const output_pixels[], liq_remapping_result *quant, const float max_dither_error, const bool output_image_is_remapped)
+{
+ const int rows = input_image->height, cols = input_image->width;
+ const unsigned char *dither_map = quant->use_dither_map ? (input_image->dither_map ? input_image->dither_map : input_image->edges) : NULL;
+
+ const colormap *map = quant->palette;
+ const colormap_item *acolormap = map->palette;
+
+ if (!liq_image_get_row_f_init(input_image)) {
+ return false;
+ }
+ if (input_image->background && !liq_image_get_row_f_init(input_image->background)) {
+ return false;
+ }
+
+ /* Initialize Floyd-Steinberg error vectors. */
+ const size_t errwidth = cols+2;
+ f_pixel *restrict thiserr = input_image->malloc(errwidth * sizeof(thiserr[0]) * 2); // +2 saves from checking out of bounds access
+ if (!thiserr) return false;
+ f_pixel *restrict nexterr = thiserr + errwidth;
+ memset(thiserr, 0, errwidth * sizeof(thiserr[0]));
+
+ bool ok = true;
+ struct nearest_map *const n = nearest_init(map);
+ liq_image *background = input_image->background;
+ const int transparent_index = background ? nearest_search(n, &(f_pixel){0,0,0,0}, 0, NULL) : -1;
+ if (background && acolormap[transparent_index].acolor.a > 1.f/256.f) {
+ // palette unsuitable for using the bg
+ background = NULL;
+ }
+
+ // response to this value is non-linear and without it any value < 0.8 would give almost no dithering
+ float base_dithering_level = quant->dither_level;
+ base_dithering_level = 1.f - (1.f-base_dithering_level)*(1.f-base_dithering_level);
+
+ if (dither_map) {
+ base_dithering_level *= 1.f/255.f; // convert byte to float
+ }
+ base_dithering_level *= 15.f/16.f; // prevent small errors from accumulating
+
+ int fs_direction = 1;
+ unsigned int last_match=0;
+ for (int row = 0; row < rows; ++row) {
+ if (liq_remap_progress(quant, quant->progress_stage1 + row * (100.f - quant->progress_stage1) / rows)) {
+ ok = false;
+ break;
+ }
+
+ memset(nexterr, 0, errwidth * sizeof(nexterr[0]));
+
+ int col = (fs_direction > 0) ? 0 : (cols - 1);
+ const f_pixel *const row_pixels = liq_image_get_row_f(input_image, row);
+ const f_pixel *const bg_pixels = background && acolormap[transparent_index].acolor.a < MIN_OPAQUE_A ? liq_image_get_row_f(background, row) : NULL;
+ int undithered_bg_used = 0;
+
+ do {
+ float dither_level = base_dithering_level;
+ if (dither_map) {
+ dither_level *= dither_map[row*cols + col];
+ }
+
+ const f_pixel spx = get_dithered_pixel(dither_level, max_dither_error, thiserr[col + 1], row_pixels[col]);
+
+ const unsigned int guessed_match = output_image_is_remapped ? output_pixels[row][col] : last_match;
+ float dither_diff;
+ last_match = nearest_search(n, &spx, guessed_match, &dither_diff);
+ f_pixel output_px = acolormap[last_match].acolor;
+ // this is for animgifs
+ if (bg_pixels) {
+ // if the background makes better match *with* dithering, it's a definitive win
+ float bg_for_dither_diff = colordifference(spx, bg_pixels[col]);
+ if (bg_for_dither_diff <= dither_diff) {
+ output_px = bg_pixels[col];
+ last_match = transparent_index;
+ } else if (undithered_bg_used > 1) {
+ // the undithered fallback can cause artifacts when too many undithered pixels accumulate a big dithering error
+ // so periodically ignore undithered fallback to prevent that
+ undithered_bg_used = 0;
+ } else {
+ // if dithering is not applied, there's a high risk of creating artifacts (flat areas, error accumulating badly),
+ // OTOH poor dithering disturbs static backgrounds and creates oscilalting frames that break backgrounds
+ // back and forth in two differently bad ways
+ float max_diff = colordifference(row_pixels[col], bg_pixels[col]);
+ float dithered_diff = colordifference(row_pixels[col], output_px);
+ // if dithering is worse than natural difference between frames
+ // (this rule dithers moving areas, but does not dither static areas)
+ if (dithered_diff > max_diff) {
+ // then see if an undithered color is closer to the ideal
+ float undithered_diff = colordifference(row_pixels[col], acolormap[guessed_match].acolor);
+ if (undithered_diff < max_diff) {
+ undithered_bg_used++;
+ output_px = acolormap[guessed_match].acolor;
+ last_match = guessed_match;
+ }
+ }
+ }
+ }
+
+ output_pixels[row][col] = last_match;
+
+ f_pixel err = {
+ .r = (spx.r - output_px.r),
+ .g = (spx.g - output_px.g),
+ .b = (spx.b - output_px.b),
+ .a = (spx.a - output_px.a),
+ };
+
+ // If dithering error is crazy high, don't propagate it that much
+ // This prevents crazy geen pixels popping out of the blue (or red or black! ;)
+ if (err.r*err.r + err.g*err.g + err.b*err.b + err.a*err.a > max_dither_error) {
+ err.r *= 0.75f;
+ err.g *= 0.75f;
+ err.b *= 0.75f;
+ err.a *= 0.75f;
+ }
+
+ /* Propagate Floyd-Steinberg error terms. */
+ if (fs_direction > 0) {
+ thiserr[col + 2].a += err.a * (7.f/16.f);
+ thiserr[col + 2].r += err.r * (7.f/16.f);
+ thiserr[col + 2].g += err.g * (7.f/16.f);
+ thiserr[col + 2].b += err.b * (7.f/16.f);
+
+ nexterr[col + 2].a = err.a * (1.f/16.f);
+ nexterr[col + 2].r = err.r * (1.f/16.f);
+ nexterr[col + 2].g = err.g * (1.f/16.f);
+ nexterr[col + 2].b = err.b * (1.f/16.f);
+
+ nexterr[col + 1].a += err.a * (5.f/16.f);
+ nexterr[col + 1].r += err.r * (5.f/16.f);
+ nexterr[col + 1].g += err.g * (5.f/16.f);
+ nexterr[col + 1].b += err.b * (5.f/16.f);
+
+ nexterr[col ].a += err.a * (3.f/16.f);
+ nexterr[col ].r += err.r * (3.f/16.f);
+ nexterr[col ].g += err.g * (3.f/16.f);
+ nexterr[col ].b += err.b * (3.f/16.f);
+
+ } else {
+ thiserr[col ].a += err.a * (7.f/16.f);
+ thiserr[col ].r += err.r * (7.f/16.f);
+ thiserr[col ].g += err.g * (7.f/16.f);
+ thiserr[col ].b += err.b * (7.f/16.f);
+
+ nexterr[col ].a = err.a * (1.f/16.f);
+ nexterr[col ].r = err.r * (1.f/16.f);
+ nexterr[col ].g = err.g * (1.f/16.f);
+ nexterr[col ].b = err.b * (1.f/16.f);
+
+ nexterr[col + 1].a += err.a * (5.f/16.f);
+ nexterr[col + 1].r += err.r * (5.f/16.f);
+ nexterr[col + 1].g += err.g * (5.f/16.f);
+ nexterr[col + 1].b += err.b * (5.f/16.f);
+
+ nexterr[col + 2].a += err.a * (3.f/16.f);
+ nexterr[col + 2].r += err.r * (3.f/16.f);
+ nexterr[col + 2].g += err.g * (3.f/16.f);
+ nexterr[col + 2].b += err.b * (3.f/16.f);
+ }
+
+ // remapping is done in zig-zag
+ col += fs_direction;
+ if (fs_direction > 0) {
+ if (col >= cols) break;
+ } else {
+ if (col < 0) break;
+ }
+ } while(1);
+
+ f_pixel *const temperr = thiserr;
+ thiserr = nexterr;
+ nexterr = temperr;
+ fs_direction = -fs_direction;
+ }
+
+ input_image->free(MIN(thiserr, nexterr)); // MIN because pointers were swapped
+ nearest_free(n);
+
+ return ok;
+}
diff --git a/tools/assets/n64texconv/lib/libimagequant/remap.h b/tools/assets/n64texconv/lib/libimagequant/remap.h
new file mode 100644
index 000000000..59d509b7a
--- /dev/null
+++ b/tools/assets/n64texconv/lib/libimagequant/remap.h
@@ -0,0 +1,7 @@
+#ifndef REMAP_H
+#define REMAP_H
+
+LIQ_PRIVATE float remap_to_palette(liq_image *const input_image, unsigned char *const *const output_pixels, colormap *const map) LIQ_NONNULL;
+LIQ_PRIVATE bool remap_to_palette_floyd(liq_image *input_image, unsigned char *const output_pixels[], liq_remapping_result *quant, const float max_dither_error, const bool output_image_is_remapped) LIQ_NONNULL;
+
+#endif
diff --git a/tools/assets/n64texconv/lib/spng/LICENSE b/tools/assets/n64texconv/lib/spng/LICENSE
new file mode 100644
index 000000000..05234f0ea
--- /dev/null
+++ b/tools/assets/n64texconv/lib/spng/LICENSE
@@ -0,0 +1,25 @@
+BSD 2-Clause License
+
+Copyright (c) 2018-2023, Randy
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice, this
+ list of conditions and the following disclaimer.
+
+* Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/tools/assets/n64texconv/lib/spng/spng.c b/tools/assets/n64texconv/lib/spng/spng.c
new file mode 100644
index 000000000..b22b7110a
--- /dev/null
+++ b/tools/assets/n64texconv/lib/spng/spng.c
@@ -0,0 +1,6980 @@
+/* SPDX-License-Identifier: (BSD-2-Clause AND libpng-2.0) */
+
+#define SPNG__BUILD
+
+#include "spng.h"
+
+#include
+#include
+#include
+#include
+
+#define ZLIB_CONST
+
+#ifdef __FRAMAC__
+ #define SPNG_DISABLE_OPT
+ #include "tests/framac_stubs.h"
+#else
+ #ifdef SPNG_USE_MINIZ
+ #include
+ #else
+ #include
+ #endif
+#endif
+
+#ifdef SPNG_MULTITHREADING
+ #include
+#endif
+
+/* Not build options, edit at your own risk! */
+#define SPNG_READ_SIZE (8192)
+#define SPNG_WRITE_SIZE SPNG_READ_SIZE
+#define SPNG_MAX_CHUNK_COUNT (1000)
+
+#define SPNG_TARGET_CLONES(x)
+
+#ifndef SPNG_DISABLE_OPT
+
+ #if defined(__i386__) || defined(__x86_64__) || defined(_M_IX86) || defined(_M_X64)
+ #define SPNG_X86
+
+ #if defined(__x86_64__) || defined(_M_X64)
+ #define SPNG_X86_64
+ #endif
+
+ #elif defined(__aarch64__) || defined(_M_ARM64) /* || defined(__ARM_NEON) */
+ #define SPNG_ARM /* NOTE: only arm64 builds are tested! */
+ #else
+ #pragma message "disabling SIMD optimizations for unknown target"
+ #define SPNG_DISABLE_OPT
+ #endif
+
+ #if defined(SPNG_X86_64) && defined(SPNG_ENABLE_TARGET_CLONES)
+ #undef SPNG_TARGET_CLONES
+ #define SPNG_TARGET_CLONES(x) __attribute__((target_clones(x)))
+ #else
+ #define SPNG_TARGET_CLONES(x)
+ #endif
+
+ #ifndef SPNG_DISABLE_OPT
+ static void defilter_sub3(size_t rowbytes, unsigned char *row);
+ static void defilter_sub4(size_t rowbytes, unsigned char *row);
+ static void defilter_avg3(size_t rowbytes, unsigned char *row, const unsigned char *prev);
+ static void defilter_avg4(size_t rowbytes, unsigned char *row, const unsigned char *prev);
+ static void defilter_paeth3(size_t rowbytes, unsigned char *row, const unsigned char *prev);
+ static void defilter_paeth4(size_t rowbytes, unsigned char *row, const unsigned char *prev);
+
+ #if defined(SPNG_ARM)
+ static uint32_t expand_palette_rgba8_neon(unsigned char *row, const unsigned char *scanline, const unsigned char *plte, uint32_t width);
+ static uint32_t expand_palette_rgb8_neon(unsigned char *row, const unsigned char *scanline, const unsigned char *plte, uint32_t width);
+ #endif
+ #endif
+#endif
+
+#if defined(_MSC_VER)
+ #pragma warning(push)
+ #pragma warning(disable: 4244)
+#endif
+
+#if (defined(__BYTE_ORDER__) && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__) || defined(__BIG_ENDIAN__)
+ #define SPNG_BIG_ENDIAN
+#else
+ #define SPNG_LITTLE_ENDIAN
+#endif
+
+enum spng_state
+{
+ SPNG_STATE_INVALID = 0,
+ SPNG_STATE_INIT = 1, /* No PNG buffer/stream is set */
+ SPNG_STATE_INPUT, /* Decoder input PNG was set */
+ SPNG_STATE_OUTPUT = SPNG_STATE_INPUT, /* Encoder output was set */
+ SPNG_STATE_IHDR, /* IHDR was read/written */
+ SPNG_STATE_FIRST_IDAT, /* Encoded up to / reached first IDAT */
+ SPNG_STATE_DECODE_INIT, /* Decoder is ready for progressive reads */
+ SPNG_STATE_ENCODE_INIT = SPNG_STATE_DECODE_INIT,
+ SPNG_STATE_EOI, /* Reached the last scanline/row */
+ SPNG_STATE_LAST_IDAT, /* Reached last IDAT, set at end of decode_image() */
+ SPNG_STATE_AFTER_IDAT, /* */
+ SPNG_STATE_IEND, /* Reached IEND */
+};
+
+enum spng__internal
+{
+ SPNG__IO_SIGNAL = 1 << 9,
+ SPNG__CTX_FLAGS_ALL = (SPNG_CTX_IGNORE_ADLER32 | SPNG_CTX_ENCODER)
+};
+
+#define SPNG_STR(x) _SPNG_STR(x)
+#define _SPNG_STR(x) #x
+
+#define SPNG_VERSION_STRING SPNG_STR(SPNG_VERSION_MAJOR) "." \
+ SPNG_STR(SPNG_VERSION_MINOR) "." \
+ SPNG_STR(SPNG_VERSION_PATCH)
+
+#define SPNG_GET_CHUNK_BOILERPLATE(chunk) \
+ if(ctx == NULL) return 1; \
+ int ret = read_chunks(ctx, 0); \
+ if(ret) return ret; \
+ if(!ctx->stored.chunk) return SPNG_ECHUNKAVAIL; \
+ if(chunk == NULL) return 1
+
+#define SPNG_SET_CHUNK_BOILERPLATE(chunk) \
+ if(ctx == NULL || chunk == NULL) return 1; \
+ if(ctx->data == NULL && !ctx->encode_only) return SPNG_ENOSRC; \
+ int ret = read_chunks(ctx, 0); \
+ if(ret) return ret
+
+/* Determine if the spng_option can be overriden/optimized */
+#define spng__optimize(option) (ctx->optimize_option & (1 << option))
+
+struct spng_subimage
+{
+ uint32_t width;
+ uint32_t height;
+ size_t out_width; /* byte width based on output format */
+ size_t scanline_width;
+};
+
+struct spng_text2
+{
+ int type;
+ char *keyword;
+ char *text;
+
+ size_t text_length;
+
+ uint8_t compression_flag; /* iTXt only */
+ char *language_tag; /* iTXt only */
+ char *translated_keyword; /* iTXt only */
+
+ size_t cache_usage;
+ char user_keyword_storage[80];
+};
+
+struct decode_flags
+{
+ unsigned apply_trns: 1;
+ unsigned apply_gamma: 1;
+ unsigned use_sbit: 1;
+ unsigned indexed: 1;
+ unsigned do_scaling: 1;
+ unsigned interlaced: 1;
+ unsigned same_layout: 1;
+ unsigned zerocopy: 1;
+ unsigned unpack: 1;
+};
+
+struct encode_flags
+{
+ unsigned interlace: 1;
+ unsigned same_layout: 1;
+ unsigned to_bigendian: 1;
+ unsigned progressive: 1;
+ unsigned finalize: 1;
+
+ enum spng_filter_choice filter_choice;
+};
+
+struct spng_chunk_bitfield
+{
+ unsigned ihdr: 1;
+ unsigned plte: 1;
+ unsigned chrm: 1;
+ unsigned iccp: 1;
+ unsigned gama: 1;
+ unsigned sbit: 1;
+ unsigned srgb: 1;
+ unsigned text: 1;
+ unsigned bkgd: 1;
+ unsigned hist: 1;
+ unsigned trns: 1;
+ unsigned phys: 1;
+ unsigned splt: 1;
+ unsigned time: 1;
+ unsigned offs: 1;
+ unsigned exif: 1;
+ unsigned unknown: 1;
+};
+
+/* Packed sample iterator */
+struct spng__iter
+{
+ const uint8_t mask;
+ unsigned shift_amount;
+ const unsigned initial_shift, bit_depth;
+ const unsigned char *samples;
+};
+
+union spng__decode_plte
+{
+ struct spng_plte_entry rgba[256];
+ unsigned char rgb[256 * 3];
+ unsigned char raw[256 * 4];
+ uint32_t align_this;
+};
+
+struct spng__zlib_options
+{
+ int compression_level;
+ int window_bits;
+ int mem_level;
+ int strategy;
+ int data_type;
+};
+
+typedef void spng__undo(spng_ctx *ctx);
+
+struct spng_ctx
+{
+ size_t data_size;
+ size_t bytes_read;
+ size_t stream_buf_size;
+ unsigned char *stream_buf;
+ const unsigned char *data;
+
+ /* User-defined pointers for streaming */
+ spng_read_fn *read_fn;
+ spng_write_fn *write_fn;
+ void *stream_user_ptr;
+
+ /* Used for buffer reads */
+ const unsigned char *png_base;
+ size_t bytes_left;
+ size_t last_read_size;
+
+ /* Used for encoding */
+ int user_owns_out_png;
+ unsigned char *out_png;
+ unsigned char *write_ptr;
+ size_t out_png_size;
+ size_t bytes_encoded;
+
+ /* These are updated by read/write_header()/read_chunk_bytes() */
+ struct spng_chunk current_chunk;
+ uint32_t cur_chunk_bytes_left;
+ uint32_t cur_actual_crc;
+
+ struct spng_alloc alloc;
+
+ enum spng_ctx_flags flags;
+ enum spng_format fmt;
+
+ enum spng_state state;
+
+ unsigned streaming: 1;
+ unsigned internal_buffer: 1; /* encoding to internal buffer */
+
+ unsigned inflate: 1;
+ unsigned deflate: 1;
+ unsigned encode_only: 1;
+ unsigned strict: 1;
+ unsigned discard: 1;
+ unsigned skip_crc: 1;
+ unsigned keep_unknown: 1;
+ unsigned prev_was_idat: 1;
+
+ struct spng__zlib_options image_options;
+ struct spng__zlib_options text_options;
+
+ spng__undo *undo;
+
+ /* input file contains this chunk */
+ struct spng_chunk_bitfield file;
+
+ /* chunk was stored with spng_set_*() */
+ struct spng_chunk_bitfield user;
+
+ /* chunk was stored by reading or with spng_set_*() */
+ struct spng_chunk_bitfield stored;
+
+ /* used to reset the above in case of an error */
+ struct spng_chunk_bitfield prev_stored;
+
+ struct spng_chunk first_idat, last_idat;
+
+ uint32_t max_width, max_height;
+
+ size_t max_chunk_size;
+ size_t chunk_cache_limit;
+ size_t chunk_cache_usage;
+ uint32_t chunk_count_limit;
+ uint32_t chunk_count_total;
+
+ int crc_action_critical;
+ int crc_action_ancillary;
+
+ uint32_t optimize_option;
+
+ struct spng_ihdr ihdr;
+
+ struct spng_plte plte;
+
+ struct spng_chrm_int chrm_int;
+ struct spng_iccp iccp;
+
+ uint32_t gama;
+
+ struct spng_sbit sbit;
+
+ uint8_t srgb_rendering_intent;
+
+ uint32_t n_text;
+ struct spng_text2 *text_list;
+
+ struct spng_bkgd bkgd;
+ struct spng_hist hist;
+ struct spng_trns trns;
+ struct spng_phys phys;
+
+ uint32_t n_splt;
+ struct spng_splt *splt_list;
+
+ struct spng_time time;
+ struct spng_offs offs;
+ struct spng_exif exif;
+
+ uint32_t n_chunks;
+ struct spng_unknown_chunk *chunk_list;
+
+ struct spng_subimage subimage[7];
+
+ z_stream zstream;
+ unsigned char *scanline_buf, *prev_scanline_buf, *row_buf, *filtered_scanline_buf;
+ unsigned char *scanline, *prev_scanline, *row, *filtered_scanline;
+
+ /* based on fmt */
+ size_t image_size; /* may be zero */
+ size_t image_width;
+
+ unsigned bytes_per_pixel; /* derived from ihdr */
+ unsigned pixel_size; /* derived from spng_format+ihdr */
+ int widest_pass;
+ int last_pass; /* last non-empty pass */
+
+ uint16_t *gamma_lut; /* points to either _lut8 or _lut16 */
+ uint16_t *gamma_lut16;
+ uint16_t gamma_lut8[256];
+ unsigned char trns_px[8];
+ union spng__decode_plte decode_plte;
+ struct spng_sbit decode_sb;
+ struct decode_flags decode_flags;
+ struct spng_row_info row_info;
+
+ struct encode_flags encode_flags;
+};
+
+static const uint32_t spng_u32max = INT32_MAX;
+
+static const uint32_t adam7_x_start[7] = { 0, 4, 0, 2, 0, 1, 0 };
+static const uint32_t adam7_y_start[7] = { 0, 0, 4, 0, 2, 0, 1 };
+static const uint32_t adam7_x_delta[7] = { 8, 8, 4, 4, 2, 2, 1 };
+static const uint32_t adam7_y_delta[7] = { 8, 8, 8, 4, 4, 2, 2 };
+
+static const uint8_t spng_signature[8] = { 137, 80, 78, 71, 13, 10, 26, 10 };
+
+static const uint8_t type_ihdr[4] = { 73, 72, 68, 82 };
+static const uint8_t type_plte[4] = { 80, 76, 84, 69 };
+static const uint8_t type_idat[4] = { 73, 68, 65, 84 };
+static const uint8_t type_iend[4] = { 73, 69, 78, 68 };
+
+static const uint8_t type_trns[4] = { 116, 82, 78, 83 };
+static const uint8_t type_chrm[4] = { 99, 72, 82, 77 };
+static const uint8_t type_gama[4] = { 103, 65, 77, 65 };
+static const uint8_t type_iccp[4] = { 105, 67, 67, 80 };
+static const uint8_t type_sbit[4] = { 115, 66, 73, 84 };
+static const uint8_t type_srgb[4] = { 115, 82, 71, 66 };
+static const uint8_t type_text[4] = { 116, 69, 88, 116 };
+static const uint8_t type_ztxt[4] = { 122, 84, 88, 116 };
+static const uint8_t type_itxt[4] = { 105, 84, 88, 116 };
+static const uint8_t type_bkgd[4] = { 98, 75, 71, 68 };
+static const uint8_t type_hist[4] = { 104, 73, 83, 84 };
+static const uint8_t type_phys[4] = { 112, 72, 89, 115 };
+static const uint8_t type_splt[4] = { 115, 80, 76, 84 };
+static const uint8_t type_time[4] = { 116, 73, 77, 69 };
+
+static const uint8_t type_offs[4] = { 111, 70, 70, 115 };
+static const uint8_t type_exif[4] = { 101, 88, 73, 102 };
+
+static inline void *spng__malloc(spng_ctx *ctx, size_t size)
+{
+ return ctx->alloc.malloc_fn(size);
+}
+
+static inline void *spng__calloc(spng_ctx *ctx, size_t nmemb, size_t size)
+{
+ return ctx->alloc.calloc_fn(nmemb, size);
+}
+
+static inline void *spng__realloc(spng_ctx *ctx, void *ptr, size_t size)
+{
+ return ctx->alloc.realloc_fn(ptr, size);
+}
+
+static inline void spng__free(spng_ctx *ctx, void *ptr)
+{
+ ctx->alloc.free_fn(ptr);
+}
+
+#if defined(SPNG_USE_MINIZ)
+static void *spng__zalloc(void *opaque, size_t items, size_t size)
+#else
+static void *spng__zalloc(void *opaque, uInt items, uInt size)
+#endif
+{
+ spng_ctx *ctx = opaque;
+
+ if(size > SIZE_MAX / items) return NULL;
+
+ size_t len = (size_t)items * size;
+
+ return spng__malloc(ctx, len);
+}
+
+static void spng__zfree(void *opqaue, void *ptr)
+{
+ spng_ctx *ctx = opqaue;
+ spng__free(ctx, ptr);
+}
+
+static inline uint16_t read_u16(const void *src)
+{
+ const unsigned char *data = src;
+
+ return (data[0] & 0xFFU) << 8 | (data[1] & 0xFFU);
+}
+
+static inline uint32_t read_u32(const void *src)
+{
+ const unsigned char *data = src;
+
+ return (data[0] & 0xFFUL) << 24 | (data[1] & 0xFFUL) << 16 |
+ (data[2] & 0xFFUL) << 8 | (data[3] & 0xFFUL);
+}
+
+static inline int32_t read_s32(const void *src)
+{
+ int32_t ret = (int32_t)read_u32(src);
+
+ return ret;
+}
+
+static inline void write_u16(void *dest, uint16_t x)
+{
+ unsigned char *data = dest;
+
+ data[0] = x >> 8;
+ data[1] = x & 0xFF;
+}
+
+static inline void write_u32(void *dest, uint32_t x)
+{
+ unsigned char *data = dest;
+
+ data[0] = (x >> 24);
+ data[1] = (x >> 16) & 0xFF;
+ data[2] = (x >> 8) & 0xFF;
+ data[3] = x & 0xFF;
+}
+
+static inline void write_s32(void *dest, int32_t x)
+{
+ uint32_t n = x;
+ write_u32(dest, n);
+}
+
+/* Returns an iterator for 1,2,4,8-bit samples */
+static struct spng__iter spng__iter_init(unsigned bit_depth, const unsigned char *samples)
+{
+ struct spng__iter iter =
+ {
+ .mask = (uint32_t)(1 << bit_depth) - 1,
+ .shift_amount = 8 - bit_depth,
+ .initial_shift = 8 - bit_depth,
+ .bit_depth = bit_depth,
+ .samples = samples
+ };
+
+ return iter;
+}
+
+/* Returns the current sample unpacked, iterates to the next one */
+static inline uint8_t get_sample(struct spng__iter *iter)
+{
+ uint8_t x = (iter->samples[0] >> iter->shift_amount) & iter->mask;
+
+ iter->shift_amount -= iter->bit_depth;
+
+ if(iter->shift_amount > 7)
+ {
+ iter->shift_amount = iter->initial_shift;
+ iter->samples++;
+ }
+
+ return x;
+}
+
+static void u16_row_to_host(void *row, size_t size)
+{
+ uint16_t *px = row;
+ size_t i, n = size / 2;
+
+ for(i=0; i < n; i++)
+ {
+ px[i] = read_u16(&px[i]);
+ }
+}
+
+static void u16_row_to_bigendian(void *row, size_t size)
+{
+ uint16_t *px = (uint16_t*)row;
+ size_t i, n = size / 2;
+
+ for(i=0; i < n; i++)
+ {
+ write_u16(&px[i], px[i]);
+ }
+}
+
+static void rgb8_row_to_rgba8(const unsigned char *row, unsigned char *out, uint32_t n)
+{
+ uint32_t i;
+ for(i=0; i < n; i++)
+ {
+ memcpy(out + i * 4, row + i * 3, 3);
+ out[i*4+3] = 255;
+ }
+}
+
+static unsigned num_channels(const struct spng_ihdr *ihdr)
+{
+ switch(ihdr->color_type)
+ {
+ case SPNG_COLOR_TYPE_TRUECOLOR: return 3;
+ case SPNG_COLOR_TYPE_GRAYSCALE_ALPHA: return 2;
+ case SPNG_COLOR_TYPE_TRUECOLOR_ALPHA: return 4;
+ case SPNG_COLOR_TYPE_GRAYSCALE:
+ case SPNG_COLOR_TYPE_INDEXED:
+ return 1;
+ default: return 0;
+ }
+}
+
+/* Calculate scanline width in bits, round up to the nearest byte */
+static int calculate_scanline_width(const struct spng_ihdr *ihdr, uint32_t width, size_t *scanline_width)
+{
+ if(ihdr == NULL || !width) return SPNG_EINTERNAL;
+
+ size_t res = num_channels(ihdr) * ihdr->bit_depth;
+
+ if(res > SIZE_MAX / width) return SPNG_EOVERFLOW;
+ res = res * width;
+
+ res += 15; /* Filter byte + 7 for rounding */
+
+ if(res < 15) return SPNG_EOVERFLOW;
+
+ res /= 8;
+
+ if(res > UINT32_MAX) return SPNG_EOVERFLOW;
+
+ *scanline_width = res;
+
+ return 0;
+}
+
+static int calculate_subimages(struct spng_ctx *ctx)
+{
+ if(ctx == NULL) return SPNG_EINTERNAL;
+
+ struct spng_ihdr *ihdr = &ctx->ihdr;
+ struct spng_subimage *sub = ctx->subimage;
+
+ if(ihdr->interlace_method == 1)
+ {
+ sub[0].width = (ihdr->width + 7) >> 3;
+ sub[0].height = (ihdr->height + 7) >> 3;
+ sub[1].width = (ihdr->width + 3) >> 3;
+ sub[1].height = (ihdr->height + 7) >> 3;
+ sub[2].width = (ihdr->width + 3) >> 2;
+ sub[2].height = (ihdr->height + 3) >> 3;
+ sub[3].width = (ihdr->width + 1) >> 2;
+ sub[3].height = (ihdr->height + 3) >> 2;
+ sub[4].width = (ihdr->width + 1) >> 1;
+ sub[4].height = (ihdr->height + 1) >> 2;
+ sub[5].width = ihdr->width >> 1;
+ sub[5].height = (ihdr->height + 1) >> 1;
+ sub[6].width = ihdr->width;
+ sub[6].height = ihdr->height >> 1;
+ }
+ else
+ {
+ sub[0].width = ihdr->width;
+ sub[0].height = ihdr->height;
+ }
+
+ int i;
+ for(i=0; i < 7; i++)
+ {
+ if(sub[i].width == 0 || sub[i].height == 0) continue;
+
+ int ret = calculate_scanline_width(ihdr, sub[i].width, &sub[i].scanline_width);
+ if(ret) return ret;
+
+ if(sub[ctx->widest_pass].scanline_width < sub[i].scanline_width) ctx->widest_pass = i;
+
+ ctx->last_pass = i;
+ }
+
+ return 0;
+}
+
+static int check_decode_fmt(const struct spng_ihdr *ihdr, const int fmt)
+{
+ switch(fmt)
+ {
+ case SPNG_FMT_RGBA8:
+ case SPNG_FMT_RGBA16:
+ case SPNG_FMT_RGB8:
+ case SPNG_FMT_PNG:
+ case SPNG_FMT_RAW:
+ return 0;
+ case SPNG_FMT_G8:
+ case SPNG_FMT_GA8:
+ if(ihdr->color_type == SPNG_COLOR_TYPE_GRAYSCALE && ihdr->bit_depth <= 8) return 0;
+ else return SPNG_EFMT;
+ case SPNG_FMT_GA16:
+ if(ihdr->color_type == SPNG_COLOR_TYPE_GRAYSCALE && ihdr->bit_depth == 16) return 0;
+ else return SPNG_EFMT;
+ default: return SPNG_EFMT;
+ }
+}
+
+static int calculate_image_width(const struct spng_ihdr *ihdr, int fmt, size_t *len)
+{
+ if(ihdr == NULL || len == NULL) return SPNG_EINTERNAL;
+
+ size_t res = ihdr->width;
+ unsigned bytes_per_pixel;
+
+ switch(fmt)
+ {
+ case SPNG_FMT_RGBA8:
+ case SPNG_FMT_GA16:
+ bytes_per_pixel = 4;
+ break;
+ case SPNG_FMT_RGBA16:
+ bytes_per_pixel = 8;
+ break;
+ case SPNG_FMT_RGB8:
+ bytes_per_pixel = 3;
+ break;
+ case SPNG_FMT_PNG:
+ case SPNG_FMT_RAW:
+ {
+ int ret = calculate_scanline_width(ihdr, ihdr->width, &res);
+ if(ret) return ret;
+
+ res -= 1; /* exclude filter byte */
+ bytes_per_pixel = 1;
+ break;
+ }
+ case SPNG_FMT_G8:
+ bytes_per_pixel = 1;
+ break;
+ case SPNG_FMT_GA8:
+ bytes_per_pixel = 2;
+ break;
+ default: return SPNG_EINTERNAL;
+ }
+
+ if(res > SIZE_MAX / bytes_per_pixel) return SPNG_EOVERFLOW;
+ res = res * bytes_per_pixel;
+
+ *len = res;
+
+ return 0;
+}
+
+static int calculate_image_size(const struct spng_ihdr *ihdr, int fmt, size_t *len)
+{
+ if(ihdr == NULL || len == NULL) return SPNG_EINTERNAL;
+
+ size_t res = 0;
+
+ int ret = calculate_image_width(ihdr, fmt, &res);
+ if(ret) return ret;
+
+ if(res > SIZE_MAX / ihdr->height) return SPNG_EOVERFLOW;
+ res = res * ihdr->height;
+
+ *len = res;
+
+ return 0;
+}
+
+static int increase_cache_usage(spng_ctx *ctx, size_t bytes, int new_chunk)
+{
+ if(ctx == NULL || !bytes) return SPNG_EINTERNAL;
+
+ if(new_chunk)
+ {
+ ctx->chunk_count_total++;
+ if(ctx->chunk_count_total < 1) return SPNG_EOVERFLOW;
+
+ if(ctx->chunk_count_total > ctx->chunk_count_limit) return SPNG_ECHUNK_LIMITS;
+ }
+
+ size_t new_usage = ctx->chunk_cache_usage + bytes;
+
+ if(new_usage < ctx->chunk_cache_usage) return SPNG_EOVERFLOW;
+
+ if(new_usage > ctx->chunk_cache_limit) return SPNG_ECHUNK_LIMITS;
+
+ ctx->chunk_cache_usage = new_usage;
+
+ return 0;
+}
+
+static int decrease_cache_usage(spng_ctx *ctx, size_t usage)
+{
+ if(ctx == NULL || !usage) return SPNG_EINTERNAL;
+ if(usage > ctx->chunk_cache_usage) return SPNG_EINTERNAL;
+
+ ctx->chunk_cache_usage -= usage;
+
+ return 0;
+}
+
+static int is_critical_chunk(struct spng_chunk *chunk)
+{
+ if(chunk == NULL) return 0;
+ if((chunk->type[0] & (1 << 5)) == 0) return 1;
+
+ return 0;
+}
+
+static int decode_err(spng_ctx *ctx, int err)
+{
+ ctx->state = SPNG_STATE_INVALID;
+
+ return err;
+}
+
+static int encode_err(spng_ctx *ctx, int err)
+{
+ ctx->state = SPNG_STATE_INVALID;
+
+ return err;
+}
+
+static inline int read_data(spng_ctx *ctx, size_t bytes)
+{
+ if(ctx == NULL) return SPNG_EINTERNAL;
+ if(!bytes) return 0;
+
+ if(ctx->streaming && (bytes > SPNG_READ_SIZE)) return SPNG_EINTERNAL;
+
+ int ret = ctx->read_fn(ctx, ctx->stream_user_ptr, ctx->stream_buf, bytes);
+
+ if(ret)
+ {
+ if(ret > 0 || ret < SPNG_IO_ERROR) ret = SPNG_IO_ERROR;
+
+ return ret;
+ }
+
+ ctx->bytes_read += bytes;
+ if(ctx->bytes_read < bytes) return SPNG_EOVERFLOW;
+
+ return 0;
+}
+
+/* Ensure there is enough space for encoding starting at ctx->write_ptr */
+static int require_bytes(spng_ctx *ctx, size_t bytes)
+{
+ if(ctx == NULL) return SPNG_EINTERNAL;
+
+ if(ctx->streaming)
+ {
+ if(bytes > ctx->stream_buf_size)
+ {
+ size_t new_size = ctx->stream_buf_size;
+
+ /* Start at default IDAT size + header + crc */
+ if(new_size < (SPNG_WRITE_SIZE + 12)) new_size = SPNG_WRITE_SIZE + 12;
+
+ if(new_size < bytes) new_size = bytes;
+
+ void *temp = spng__realloc(ctx, ctx->stream_buf, new_size);
+
+ if(temp == NULL) return encode_err(ctx, SPNG_EMEM);
+
+ ctx->stream_buf = temp;
+ ctx->stream_buf_size = bytes;
+ ctx->write_ptr = ctx->stream_buf;
+ }
+
+ return 0;
+ }
+
+ if(!ctx->internal_buffer) return SPNG_ENODST;
+
+ size_t required = ctx->bytes_encoded + bytes;
+ if(required < bytes) return SPNG_EOVERFLOW;
+
+ if(required > ctx->out_png_size)
+ {
+ size_t new_size = ctx->out_png_size;
+
+ /* Start with a size that doesn't require a realloc() 100% of the time */
+ if(new_size < (SPNG_WRITE_SIZE * 2)) new_size = SPNG_WRITE_SIZE * 2;
+
+ /* Prefer the next power of two over the requested size */
+ while(new_size < required)
+ {
+ if(new_size / SIZE_MAX > 2) return encode_err(ctx, SPNG_EOVERFLOW);
+
+ new_size *= 2;
+ }
+
+ void *temp = spng__realloc(ctx, ctx->out_png, new_size);
+
+ if(temp == NULL) return encode_err(ctx, SPNG_EMEM);
+
+ ctx->out_png = temp;
+ ctx->out_png_size = new_size;
+ ctx->write_ptr = ctx->out_png + ctx->bytes_encoded;
+ }
+
+ return 0;
+}
+
+static int write_data(spng_ctx *ctx, const void *data, size_t bytes)
+{
+ if(ctx == NULL) return SPNG_EINTERNAL;
+ if(!bytes) return 0;
+
+ if(ctx->streaming)
+ {
+ if(bytes > SPNG_WRITE_SIZE) return SPNG_EINTERNAL;
+
+ int ret = ctx->write_fn(ctx, ctx->stream_user_ptr, (void*)data, bytes);
+
+ if(ret)
+ {
+ if(ret > 0 || ret < SPNG_IO_ERROR) ret = SPNG_IO_ERROR;
+
+ return encode_err(ctx, ret);
+ }
+ }
+ else
+ {
+ int ret = require_bytes(ctx, bytes);
+ if(ret) return encode_err(ctx, ret);
+
+ memcpy(ctx->write_ptr, data, bytes);
+
+ ctx->write_ptr += bytes;
+ }
+
+ ctx->bytes_encoded += bytes;
+ if(ctx->bytes_encoded < bytes) return SPNG_EOVERFLOW;
+
+ return 0;
+}
+
+static int write_header(spng_ctx *ctx, const uint8_t chunk_type[4], size_t chunk_length, unsigned char **data)
+{
+ if(ctx == NULL || chunk_type == NULL) return SPNG_EINTERNAL;
+ if(chunk_length > spng_u32max) return SPNG_EINTERNAL;
+
+ size_t total = chunk_length + 12;
+
+ int ret = require_bytes(ctx, total);
+ if(ret) return ret;
+
+ uint32_t crc = crc32(0, NULL, 0);
+ ctx->current_chunk.crc = crc32(crc, chunk_type, 4);
+
+ memcpy(&ctx->current_chunk.type, chunk_type, 4);
+ ctx->current_chunk.length = (uint32_t)chunk_length;
+
+ if(!data) return SPNG_EINTERNAL;
+
+ if(ctx->streaming) *data = ctx->stream_buf + 8;
+ else *data = ctx->write_ptr + 8;
+
+ return 0;
+}
+
+static int trim_chunk(spng_ctx *ctx, uint32_t length)
+{
+ if(length > spng_u32max) return SPNG_EINTERNAL;
+ if(length > ctx->current_chunk.length) return SPNG_EINTERNAL;
+
+ ctx->current_chunk.length = length;
+
+ return 0;
+}
+
+static int finish_chunk(spng_ctx *ctx)
+{
+ if(ctx == NULL) return SPNG_EINTERNAL;
+
+ struct spng_chunk *chunk = &ctx->current_chunk;
+
+ unsigned char *header;
+ unsigned char *chunk_data;
+
+ if(ctx->streaming)
+ {
+ chunk_data = ctx->stream_buf + 8;
+ header = ctx->stream_buf;
+ }
+ else
+ {
+ chunk_data = ctx->write_ptr + 8;
+ header = ctx->write_ptr;
+ }
+
+ write_u32(header, chunk->length);
+ memcpy(header + 4, chunk->type, 4);
+
+ chunk->crc = crc32(chunk->crc, chunk_data, chunk->length);
+
+ write_u32(chunk_data + chunk->length, chunk->crc);
+
+ if(ctx->streaming)
+ {
+ const unsigned char *ptr = ctx->stream_buf;
+ uint32_t bytes_left = chunk->length + 12;
+ uint32_t len = 0;
+
+ while(bytes_left)
+ {
+ ptr += len;
+ len = SPNG_WRITE_SIZE;
+
+ if(len > bytes_left) len = bytes_left;
+
+ int ret = write_data(ctx, ptr, len);
+ if(ret) return ret;
+
+ bytes_left -= len;
+ }
+ }
+ else
+ {
+ ctx->bytes_encoded += chunk->length;
+ if(ctx->bytes_encoded < chunk->length) return SPNG_EOVERFLOW;
+
+ ctx->bytes_encoded += 12;
+ if(ctx->bytes_encoded < 12) return SPNG_EOVERFLOW;
+
+ ctx->write_ptr += chunk->length + 12;
+ }
+
+ return 0;
+}
+
+static int write_chunk(spng_ctx *ctx, const uint8_t type[4], const void *data, size_t length)
+{
+ if(ctx == NULL || type == NULL) return SPNG_EINTERNAL;
+ if(length && data == NULL) return SPNG_EINTERNAL;
+
+ unsigned char *write_ptr;
+
+ int ret = write_header(ctx, type, length, &write_ptr);
+ if(ret) return ret;
+
+ if(length) memcpy(write_ptr, data, length);
+
+ return finish_chunk(ctx);
+}
+
+static int write_iend(spng_ctx *ctx)
+{
+ unsigned char iend_chunk[12] = { 0, 0, 0, 0, 73, 69, 78, 68, 174, 66, 96, 130 };
+ return write_data(ctx, iend_chunk, 12);
+}
+
+static int write_unknown_chunks(spng_ctx *ctx, enum spng_location location)
+{
+ if(!ctx->stored.unknown) return 0;
+
+ const struct spng_unknown_chunk *chunk = ctx->chunk_list;
+
+ uint32_t i;
+ for(i=0; i < ctx->n_chunks; i++, chunk++)
+ {
+ if(chunk->location != location) continue;
+
+ int ret = write_chunk(ctx, chunk->type, chunk->data, chunk->length);
+ if(ret) return ret;
+ }
+
+ return 0;
+}
+
+/* Read and check the current chunk's crc,
+ returns -SPNG_CRC_DISCARD if the chunk should be discarded */
+static inline int read_and_check_crc(spng_ctx *ctx)
+{
+ if(ctx == NULL) return SPNG_EINTERNAL;
+
+ int ret;
+ ret = read_data(ctx, 4);
+ if(ret) return ret;
+
+ ctx->current_chunk.crc = read_u32(ctx->data);
+
+ if(ctx->skip_crc) return 0;
+
+ if(ctx->cur_actual_crc != ctx->current_chunk.crc)
+ {
+ if(is_critical_chunk(&ctx->current_chunk))
+ {
+ if(ctx->crc_action_critical == SPNG_CRC_USE) return 0;
+ }
+ else
+ {
+ if(ctx->crc_action_ancillary == SPNG_CRC_USE) return 0;
+ if(ctx->crc_action_ancillary == SPNG_CRC_DISCARD) return -SPNG_CRC_DISCARD;
+ }
+
+ return SPNG_ECHUNK_CRC;
+ }
+
+ return 0;
+}
+
+/* Read and validate the current chunk's crc and the next chunk header */
+static inline int read_header(spng_ctx *ctx)
+{
+ if(ctx == NULL) return SPNG_EINTERNAL;
+
+ int ret;
+ struct spng_chunk chunk = { 0 };
+
+ ret = read_and_check_crc(ctx);
+ if(ret)
+ {
+ if(ret == -SPNG_CRC_DISCARD)
+ {
+ ctx->discard = 1;
+ }
+ else return ret;
+ }
+
+ ret = read_data(ctx, 8);
+ if(ret) return ret;
+
+ chunk.offset = ctx->bytes_read - 8;
+
+ chunk.length = read_u32(ctx->data);
+
+ memcpy(&chunk.type, ctx->data + 4, 4);
+
+ if(chunk.length > spng_u32max) return SPNG_ECHUNK_STDLEN;
+
+ ctx->cur_chunk_bytes_left = chunk.length;
+
+ if(is_critical_chunk(&chunk) && ctx->crc_action_critical == SPNG_CRC_USE) ctx->skip_crc = 1;
+ else if(ctx->crc_action_ancillary == SPNG_CRC_USE) ctx->skip_crc = 1;
+ else ctx->skip_crc = 0;
+
+ if(!ctx->skip_crc)
+ {
+ ctx->cur_actual_crc = crc32(0, NULL, 0);
+ ctx->cur_actual_crc = crc32(ctx->cur_actual_crc, chunk.type, 4);
+ }
+
+ ctx->current_chunk = chunk;
+
+ return 0;
+}
+
+/* Read chunk bytes and update crc */
+static int read_chunk_bytes(spng_ctx *ctx, uint32_t bytes)
+{
+ if(ctx == NULL) return SPNG_EINTERNAL;
+ if(!ctx->cur_chunk_bytes_left || !bytes) return SPNG_EINTERNAL;
+ if(bytes > ctx->cur_chunk_bytes_left) return SPNG_EINTERNAL; /* XXX: more specific error? */
+
+ int ret;
+
+ ret = read_data(ctx, bytes);
+ if(ret) return ret;
+
+ if(!ctx->skip_crc) ctx->cur_actual_crc = crc32(ctx->cur_actual_crc, ctx->data, bytes);
+
+ ctx->cur_chunk_bytes_left -= bytes;
+
+ return ret;
+}
+
+/* read_chunk_bytes() + read_data() with custom output buffer */
+static int read_chunk_bytes2(spng_ctx *ctx, void *out, uint32_t bytes)
+{
+ if(ctx == NULL) return SPNG_EINTERNAL;
+ if(!ctx->cur_chunk_bytes_left || !bytes) return SPNG_EINTERNAL;
+ if(bytes > ctx->cur_chunk_bytes_left) return SPNG_EINTERNAL; /* XXX: more specific error? */
+
+ int ret;
+ uint32_t len = bytes;
+
+ if(ctx->streaming && len > SPNG_READ_SIZE) len = SPNG_READ_SIZE;
+
+ while(bytes)
+ {
+ if(len > bytes) len = bytes;
+
+ ret = ctx->read_fn(ctx, ctx->stream_user_ptr, out, len);
+ if(ret) return ret;
+
+ if(!ctx->streaming) memcpy(out, ctx->data, len);
+
+ ctx->bytes_read += len;
+ if(ctx->bytes_read < len) return SPNG_EOVERFLOW;
+
+ if(!ctx->skip_crc) ctx->cur_actual_crc = crc32(ctx->cur_actual_crc, out, len);
+
+ ctx->cur_chunk_bytes_left -= len;
+
+ out = (char*)out + len;
+ bytes -= len;
+ len = SPNG_READ_SIZE;
+ }
+
+ return 0;
+}
+
+static int discard_chunk_bytes(spng_ctx *ctx, uint32_t bytes)
+{
+ if(ctx == NULL) return SPNG_EINTERNAL;
+ if(!bytes) return 0;
+
+ int ret;
+
+ if(ctx->streaming) /* Do small, consecutive reads */
+ {
+ while(bytes)
+ {
+ uint32_t len = SPNG_READ_SIZE;
+
+ if(len > bytes) len = bytes;
+
+ ret = read_chunk_bytes(ctx, len);
+ if(ret) return ret;
+
+ bytes -= len;
+ }
+ }
+ else
+ {
+ ret = read_chunk_bytes(ctx, bytes);
+ if(ret) return ret;
+ }
+
+ return 0;
+}
+
+static int spng__inflate_init(spng_ctx *ctx, int window_bits)
+{
+ if(ctx->zstream.state) inflateEnd(&ctx->zstream);
+
+ ctx->inflate = 1;
+
+ ctx->zstream.zalloc = spng__zalloc;
+ ctx->zstream.zfree = spng__zfree;
+ ctx->zstream.opaque = ctx;
+
+ if(inflateInit2(&ctx->zstream, window_bits) != Z_OK) return SPNG_EZLIB_INIT;
+
+#if ZLIB_VERNUM >= 0x1290 && !defined(SPNG_USE_MINIZ)
+
+ int validate = 1;
+
+ if(ctx->flags & SPNG_CTX_IGNORE_ADLER32) validate = 0;
+
+ if(is_critical_chunk(&ctx->current_chunk))
+ {
+ if(ctx->crc_action_critical == SPNG_CRC_USE) validate = 0;
+ }
+ else /* ancillary */
+ {
+ if(ctx->crc_action_ancillary == SPNG_CRC_USE) validate = 0;
+ }
+
+ if(inflateValidate(&ctx->zstream, validate)) return SPNG_EZLIB_INIT;
+
+#else /* This requires zlib >= 1.2.11 */
+ #pragma message ("inflateValidate() not available, SPNG_CTX_IGNORE_ADLER32 will be ignored")
+#endif
+
+ return 0;
+}
+
+static int spng__deflate_init(spng_ctx *ctx, struct spng__zlib_options *options)
+{
+ if(ctx->zstream.state) deflateEnd(&ctx->zstream);
+
+ ctx->deflate = 1;
+
+ z_stream *zstream = &ctx->zstream;
+ zstream->zalloc = spng__zalloc;
+ zstream->zfree = spng__zfree;
+ zstream->opaque = ctx;
+ zstream->data_type = options->data_type;
+
+ int ret = deflateInit2(zstream, options->compression_level, Z_DEFLATED, options->window_bits, options->mem_level, options->strategy);
+
+ if(ret != Z_OK) return SPNG_EZLIB_INIT;
+
+ return 0;
+}
+
+/* Inflate a zlib stream starting with start_buf if non-NULL,
+ continuing from the datastream till an end marker,
+ allocating and writing the inflated stream to *out,
+ leaving "extra" bytes at the end, final buffer length is *len.
+
+ Takes into account the chunk size and cache limits.
+*/
+static int spng__inflate_stream(spng_ctx *ctx, char **out, size_t *len, size_t extra, const void *start_buf, size_t start_len)
+{
+ int ret = spng__inflate_init(ctx, 15);
+ if(ret) return ret;
+
+ size_t max = ctx->chunk_cache_limit - ctx->chunk_cache_usage;
+
+ if(ctx->max_chunk_size < max) max = ctx->max_chunk_size;
+
+ if(extra > max) return SPNG_ECHUNK_LIMITS;
+ max -= extra;
+
+ uint32_t read_size;
+ size_t size = 8 * 1024;
+ void *t, *buf = spng__malloc(ctx, size);
+
+ if(buf == NULL) return SPNG_EMEM;
+
+ z_stream *stream = &ctx->zstream;
+
+ if(start_buf != NULL && start_len)
+ {
+ stream->avail_in = (uInt)start_len;
+ stream->next_in = start_buf;
+ }
+ else
+ {
+ stream->avail_in = 0;
+ stream->next_in = NULL;
+ }
+
+ stream->avail_out = (uInt)size;
+ stream->next_out = buf;
+
+ while(ret != Z_STREAM_END)
+ {
+ ret = inflate(stream, Z_NO_FLUSH);
+
+ if(ret == Z_STREAM_END) break;
+
+ if(ret != Z_OK && ret != Z_BUF_ERROR)
+ {
+ ret = SPNG_EZLIB;
+ goto err;
+ }
+
+ if(!stream->avail_out) /* Resize buffer */
+ {
+ /* overflow or reached chunk/cache limit */
+ if( (2 > SIZE_MAX / size) || (size > max / 2) )
+ {
+ ret = SPNG_ECHUNK_LIMITS;
+ goto err;
+ }
+
+ size *= 2;
+
+ t = spng__realloc(ctx, buf, size);
+ if(t == NULL) goto mem;
+
+ buf = t;
+
+ stream->avail_out = (uInt)size / 2;
+ stream->next_out = (unsigned char*)buf + size / 2;
+ }
+ else if(!stream->avail_in) /* Read more chunk bytes */
+ {
+ read_size = ctx->cur_chunk_bytes_left;
+ if(ctx->streaming && read_size > SPNG_READ_SIZE) read_size = SPNG_READ_SIZE;
+
+ ret = read_chunk_bytes(ctx, read_size);
+
+ if(ret)
+ {
+ if(!read_size) ret = SPNG_EZLIB;
+
+ goto err;
+ }
+
+ stream->avail_in = read_size;
+ stream->next_in = ctx->data;
+ }
+ }
+
+ size = stream->total_out;
+
+ if(!size)
+ {
+ ret = SPNG_EZLIB;
+ goto err;
+ }
+
+ size += extra;
+ if(size < extra) goto mem;
+
+ t = spng__realloc(ctx, buf, size);
+ if(t == NULL) goto mem;
+
+ buf = t;
+
+ (void)increase_cache_usage(ctx, size, 0);
+
+ *out = buf;
+ *len = size;
+
+ return 0;
+
+mem:
+ ret = SPNG_EMEM;
+err:
+ spng__free(ctx, buf);
+ return ret;
+}
+
+/* Read at least one byte from the IDAT stream */
+static int read_idat_bytes(spng_ctx *ctx, uint32_t *bytes_read)
+{
+ if(ctx == NULL || bytes_read == NULL) return SPNG_EINTERNAL;
+ if(memcmp(ctx->current_chunk.type, type_idat, 4)) return SPNG_EIDAT_TOO_SHORT;
+
+ int ret;
+ uint32_t len;
+
+ while(!ctx->cur_chunk_bytes_left)
+ {
+ ret = read_header(ctx);
+ if(ret) return ret;
+
+ if(memcmp(ctx->current_chunk.type, type_idat, 4)) return SPNG_EIDAT_TOO_SHORT;
+ }
+
+ if(ctx->streaming)
+ {/* TODO: estimate bytes to read for progressive reads */
+ len = SPNG_READ_SIZE;
+ if(len > ctx->cur_chunk_bytes_left) len = ctx->cur_chunk_bytes_left;
+ }
+ else len = ctx->current_chunk.length;
+
+ ret = read_chunk_bytes(ctx, len);
+
+ *bytes_read = len;
+
+ return ret;
+}
+
+static int read_scanline_bytes(spng_ctx *ctx, unsigned char *dest, size_t len)
+{
+ if(ctx == NULL || dest == NULL) return SPNG_EINTERNAL;
+
+ int ret = Z_OK;
+ uint32_t bytes_read;
+
+ z_stream *zstream = &ctx->zstream;
+
+ zstream->avail_out = (uInt)len;
+ zstream->next_out = dest;
+
+ while(zstream->avail_out != 0)
+ {
+ ret = inflate(zstream, Z_NO_FLUSH);
+
+ if(ret == Z_OK) continue;
+
+ if(ret == Z_STREAM_END) /* Reached an end-marker */
+ {
+ if(zstream->avail_out != 0) return SPNG_EIDAT_TOO_SHORT;
+ }
+ else if(ret == Z_BUF_ERROR) /* Read more IDAT bytes */
+ {
+ ret = read_idat_bytes(ctx, &bytes_read);
+ if(ret) return ret;
+
+ zstream->avail_in = bytes_read;
+ zstream->next_in = ctx->data;
+ }
+ else return SPNG_EIDAT_STREAM;
+ }
+
+ return 0;
+}
+
+static uint8_t paeth(uint8_t a, uint8_t b, uint8_t c)
+{
+ int16_t p = a + b - c;
+ int16_t pa = abs(p - a);
+ int16_t pb = abs(p - b);
+ int16_t pc = abs(p - c);
+
+ if(pa <= pb && pa <= pc) return a;
+ else if(pb <= pc) return b;
+
+ return c;
+}
+
+SPNG_TARGET_CLONES("default,avx2")
+static void defilter_up(size_t bytes, unsigned char *row, const unsigned char *prev)
+{
+ size_t i;
+ for(i=0; i < bytes; i++)
+ {
+ row[i] += prev[i];
+ }
+}
+
+/* Defilter *scanline in-place.
+ *prev_scanline and *scanline should point to the first pixel,
+ scanline_width is the width of the scanline including the filter byte.
+*/
+static int defilter_scanline(const unsigned char *prev_scanline, unsigned char *scanline,
+ size_t scanline_width, unsigned bytes_per_pixel, unsigned filter)
+{
+ if(prev_scanline == NULL || scanline == NULL || !scanline_width) return SPNG_EINTERNAL;
+
+ size_t i;
+ scanline_width--;
+
+ if(filter == 0) return 0;
+
+#ifndef SPNG_DISABLE_OPT
+ if(filter == SPNG_FILTER_UP) goto no_opt;
+
+ if(bytes_per_pixel == 4)
+ {
+ if(filter == SPNG_FILTER_SUB)
+ defilter_sub4(scanline_width, scanline);
+ else if(filter == SPNG_FILTER_AVERAGE)
+ defilter_avg4(scanline_width, scanline, prev_scanline);
+ else if(filter == SPNG_FILTER_PAETH)
+ defilter_paeth4(scanline_width, scanline, prev_scanline);
+ else return SPNG_EFILTER;
+
+ return 0;
+ }
+ else if(bytes_per_pixel == 3)
+ {
+ if(filter == SPNG_FILTER_SUB)
+ defilter_sub3(scanline_width, scanline);
+ else if(filter == SPNG_FILTER_AVERAGE)
+ defilter_avg3(scanline_width, scanline, prev_scanline);
+ else if(filter == SPNG_FILTER_PAETH)
+ defilter_paeth3(scanline_width, scanline, prev_scanline);
+ else return SPNG_EFILTER;
+
+ return 0;
+ }
+no_opt:
+#endif
+
+ if(filter == SPNG_FILTER_UP)
+ {
+ defilter_up(scanline_width, scanline, prev_scanline);
+ return 0;
+ }
+
+ for(i=0; i < scanline_width; i++)
+ {
+ uint8_t x, a, b, c;
+
+ if(i >= bytes_per_pixel)
+ {
+ a = scanline[i - bytes_per_pixel];
+ b = prev_scanline[i];
+ c = prev_scanline[i - bytes_per_pixel];
+ }
+ else /* First pixel in row */
+ {
+ a = 0;
+ b = prev_scanline[i];
+ c = 0;
+ }
+
+ x = scanline[i];
+
+ switch(filter)
+ {
+ case SPNG_FILTER_SUB:
+ {
+ x = x + a;
+ break;
+ }
+ case SPNG_FILTER_AVERAGE:
+ {
+ uint16_t avg = (a + b) / 2;
+ x = x + avg;
+ break;
+ }
+ case SPNG_FILTER_PAETH:
+ {
+ x = x + paeth(a,b,c);
+ break;
+ }
+ }
+
+ scanline[i] = x;
+ }
+
+ return 0;
+}
+
+static int filter_scanline(unsigned char *filtered, const unsigned char *prev_scanline, const unsigned char *scanline,
+ size_t scanline_width, unsigned bytes_per_pixel, const unsigned filter)
+{
+ if(prev_scanline == NULL || scanline == NULL || scanline_width <= 1) return SPNG_EINTERNAL;
+
+ if(filter > 4) return SPNG_EFILTER;
+ if(filter == 0) return 0;
+
+ scanline_width--;
+
+ uint32_t i;
+ for(i=0; i < scanline_width; i++)
+ {
+ uint8_t x, a, b, c;
+
+ if(i >= bytes_per_pixel)
+ {
+ a = scanline[i - bytes_per_pixel];
+ b = prev_scanline[i];
+ c = prev_scanline[i - bytes_per_pixel];
+ }
+ else /* first pixel in row */
+ {
+ a = 0;
+ b = prev_scanline[i];
+ c = 0;
+ }
+
+ x = scanline[i];
+
+ switch(filter)
+ {
+ case SPNG_FILTER_SUB:
+ {
+ x = x - a;
+ break;
+ }
+ case SPNG_FILTER_UP:
+ {
+ x = x - b;
+ break;
+ }
+ case SPNG_FILTER_AVERAGE:
+ {
+ uint16_t avg = (a + b) / 2;
+ x = x - avg;
+ break;
+ }
+ case SPNG_FILTER_PAETH:
+ {
+ x = x - paeth(a,b,c);
+ break;
+ }
+ }
+
+ filtered[i] = x;
+ }
+
+ return 0;
+}
+
+static int32_t filter_sum(const unsigned char *prev_scanline, const unsigned char *scanline,
+ size_t size, unsigned bytes_per_pixel, const unsigned filter)
+{
+ /* prevent potential over/underflow, bails out at a width of ~8M pixels for RGBA8 */
+ if(size > (INT32_MAX / 128)) return INT32_MAX;
+
+ uint32_t i;
+ int32_t sum = 0;
+ uint8_t x, a, b, c;
+
+ for(i=0; i < size; i++)
+ {
+ if(i >= bytes_per_pixel)
+ {
+ a = scanline[i - bytes_per_pixel];
+ b = prev_scanline[i];
+ c = prev_scanline[i - bytes_per_pixel];
+ }
+ else /* first pixel in row */
+ {
+ a = 0;
+ b = prev_scanline[i];
+ c = 0;
+ }
+
+ x = scanline[i];
+
+ switch(filter)
+ {
+ case SPNG_FILTER_NONE:
+ {
+ break;
+ }
+ case SPNG_FILTER_SUB:
+ {
+ x = x - a;
+ break;
+ }
+ case SPNG_FILTER_UP:
+ {
+ x = x - b;
+ break;
+ }
+ case SPNG_FILTER_AVERAGE:
+ {
+ uint16_t avg = (a + b) / 2;
+ x = x - avg;
+ break;
+ }
+ case SPNG_FILTER_PAETH:
+ {
+ x = x - paeth(a,b,c);
+ break;
+ }
+ }
+
+ sum += 128 - abs((int)x - 128);
+ }
+
+ return sum;
+}
+
+static unsigned get_best_filter(const unsigned char *prev_scanline, const unsigned char *scanline,
+ size_t scanline_width, unsigned bytes_per_pixel, const int choices)
+{
+ if(!choices) return SPNG_FILTER_NONE;
+
+ scanline_width--;
+
+ int i;
+ unsigned int best_filter = 0;
+ enum spng_filter_choice flag;
+ int32_t sum, best_score = INT32_MAX;
+ int32_t filter_scores[5] = { INT32_MAX, INT32_MAX, INT32_MAX, INT32_MAX, INT32_MAX };
+
+ if( !(choices & (choices - 1)) )
+ {/* only one choice/bit is set */
+ for(i=0; i < 5; i++)
+ {
+ if(choices == 1 << (i + 3)) return i;
+ }
+ }
+
+ for(i=0; i < 5; i++)
+ {
+ flag = 1 << (i + 3);
+
+ if(choices & flag) sum = filter_sum(prev_scanline, scanline, scanline_width, bytes_per_pixel, i);
+ else continue;
+
+ filter_scores[i] = abs(sum);
+
+ if(filter_scores[i] < best_score)
+ {
+ best_score = filter_scores[i];
+ best_filter = i;
+ }
+ }
+
+ return best_filter;
+}
+
+/* Scale "sbits" significant bits in "sample" from "bit_depth" to "target"
+
+ "bit_depth" must be a valid PNG depth
+ "sbits" must be less than or equal to "bit_depth"
+ "target" must be between 1 and 16
+*/
+static uint16_t sample_to_target(uint16_t sample, unsigned bit_depth, unsigned sbits, unsigned target)
+{
+ if(bit_depth == sbits)
+ {
+ if(target == sbits) return sample; /* No scaling */
+ }/* bit_depth > sbits */
+ else sample = sample >> (bit_depth - sbits); /* Shift significant bits to bottom */
+
+ /* Downscale */
+ if(target < sbits) return sample >> (sbits - target);
+
+ /* Upscale using left bit replication */
+ int8_t shift_amount = target - sbits;
+ uint16_t sample_bits = sample;
+ sample = 0;
+
+ while(shift_amount >= 0)
+ {
+ sample = sample | (sample_bits << shift_amount);
+ shift_amount -= sbits;
+ }
+
+ int8_t partial = shift_amount + (int8_t)sbits;
+
+ if(partial != 0) sample = sample | (sample_bits >> abs(shift_amount));
+
+ return sample;
+}
+
+static inline void gamma_correct_row(unsigned char *row, uint32_t pixels, int fmt, const uint16_t *gamma_lut)
+{
+ uint32_t i;
+
+ if(fmt == SPNG_FMT_RGBA8)
+ {
+ unsigned char *px;
+ for(i=0; i < pixels; i++)
+ {
+ px = row + i * 4;
+
+ px[0] = gamma_lut[px[0]];
+ px[1] = gamma_lut[px[1]];
+ px[2] = gamma_lut[px[2]];
+ }
+ }
+ else if(fmt == SPNG_FMT_RGBA16)
+ {
+ for(i=0; i < pixels; i++)
+ {
+ uint16_t px[4];
+ memcpy(px, row + i * 8, 8);
+
+ px[0] = gamma_lut[px[0]];
+ px[1] = gamma_lut[px[1]];
+ px[2] = gamma_lut[px[2]];
+
+ memcpy(row + i * 8, px, 8);
+ }
+ }
+ else if(fmt == SPNG_FMT_RGB8)
+ {
+ unsigned char *px;
+ for(i=0; i < pixels; i++)
+ {
+ px = row + i * 3;
+
+ px[0] = gamma_lut[px[0]];
+ px[1] = gamma_lut[px[1]];
+ px[2] = gamma_lut[px[2]];
+ }
+ }
+}
+
+/* Apply transparency to output row */
+static inline void trns_row(unsigned char *row,
+ const unsigned char *scanline,
+ const unsigned char *trns,
+ unsigned scanline_stride,
+ struct spng_ihdr *ihdr,
+ uint32_t pixels,
+ int fmt)
+{
+ uint32_t i;
+ unsigned row_stride;
+ unsigned depth = ihdr->bit_depth;
+
+ if(fmt == SPNG_FMT_RGBA8)
+ {
+ if(ihdr->color_type == SPNG_COLOR_TYPE_GRAYSCALE) return; /* already applied in the decoding loop */
+
+ row_stride = 4;
+ for(i=0; i < pixels; i++, scanline+=scanline_stride, row+=row_stride)
+ {
+ if(!memcmp(scanline, trns, scanline_stride)) row[3] = 0;
+ }
+ }
+ else if(fmt == SPNG_FMT_RGBA16)
+ {
+ if(ihdr->color_type == SPNG_COLOR_TYPE_GRAYSCALE) return; /* already applied in the decoding loop */
+
+ row_stride = 8;
+ for(i=0; i < pixels; i++, scanline+=scanline_stride, row+=row_stride)
+ {
+ if(!memcmp(scanline, trns, scanline_stride)) memset(row + 6, 0, 2);
+ }
+ }
+ else if(fmt == SPNG_FMT_GA8)
+ {
+ row_stride = 2;
+
+ if(depth == 16)
+ {
+ for(i=0; i < pixels; i++, scanline+=scanline_stride, row+=row_stride)
+ {
+ if(!memcmp(scanline, trns, scanline_stride)) memset(row + 1, 0, 1);
+ }
+ }
+ else /* depth <= 8 */
+ {
+ struct spng__iter iter = spng__iter_init(depth, scanline);
+
+ for(i=0; i < pixels; i++, row+=row_stride)
+ {
+ if(trns[0] == get_sample(&iter)) row[1] = 0;
+ }
+ }
+ }
+ else if(fmt == SPNG_FMT_GA16)
+ {
+ row_stride = 4;
+
+ if(depth == 16)
+ {
+ for(i=0; i< pixels; i++, scanline+=scanline_stride, row+=row_stride)
+ {
+ if(!memcmp(scanline, trns, 2)) memset(row + 2, 0, 2);
+ }
+ }
+ else
+ {
+ struct spng__iter iter = spng__iter_init(depth, scanline);
+
+ for(i=0; i< pixels; i++, row+=row_stride)
+ {
+ if(trns[0] == get_sample(&iter)) memset(row + 2, 0, 2);
+ }
+ }
+ }
+ else return;
+}
+
+static inline void scale_row(unsigned char *row, uint32_t pixels, int fmt, unsigned depth, const struct spng_sbit *sbit)
+{
+ uint32_t i;
+
+ if(fmt == SPNG_FMT_RGBA8)
+ {
+ unsigned char px[4];
+ for(i=0; i < pixels; i++)
+ {
+ memcpy(px, row + i * 4, 4);
+
+ px[0] = sample_to_target(px[0], depth, sbit->red_bits, 8);
+ px[1] = sample_to_target(px[1], depth, sbit->green_bits, 8);
+ px[2] = sample_to_target(px[2], depth, sbit->blue_bits, 8);
+ px[3] = sample_to_target(px[3], depth, sbit->alpha_bits, 8);
+
+ memcpy(row + i * 4, px, 4);
+ }
+ }
+ else if(fmt == SPNG_FMT_RGBA16)
+ {
+ uint16_t px[4];
+ for(i=0; i < pixels; i++)
+ {
+ memcpy(px, row + i * 8, 8);
+
+ px[0] = sample_to_target(px[0], depth, sbit->red_bits, 16);
+ px[1] = sample_to_target(px[1], depth, sbit->green_bits, 16);
+ px[2] = sample_to_target(px[2], depth, sbit->blue_bits, 16);
+ px[3] = sample_to_target(px[3], depth, sbit->alpha_bits, 16);
+
+ memcpy(row + i * 8, px, 8);
+ }
+ }
+ else if(fmt == SPNG_FMT_RGB8)
+ {
+ unsigned char px[4];
+ for(i=0; i < pixels; i++)
+ {
+ memcpy(px, row + i * 3, 3);
+
+ px[0] = sample_to_target(px[0], depth, sbit->red_bits, 8);
+ px[1] = sample_to_target(px[1], depth, sbit->green_bits, 8);
+ px[2] = sample_to_target(px[2], depth, sbit->blue_bits, 8);
+
+ memcpy(row + i * 3, px, 3);
+ }
+ }
+ else if(fmt == SPNG_FMT_G8)
+ {
+ for(i=0; i < pixels; i++)
+ {
+ row[i] = sample_to_target(row[i], depth, sbit->grayscale_bits, 8);
+ }
+ }
+ else if(fmt == SPNG_FMT_GA8)
+ {
+ for(i=0; i < pixels; i++)
+ {
+ row[i*2] = sample_to_target(row[i*2], depth, sbit->grayscale_bits, 8);
+ }
+ }
+}
+
+/* Expand to *row using 8-bit palette indices from *scanline */
+static void expand_row(unsigned char *row,
+ const unsigned char *scanline,
+ const union spng__decode_plte *decode_plte,
+ uint32_t width,
+ int fmt)
+{
+ uint32_t i = 0;
+ unsigned char *px;
+ unsigned char entry;
+ const struct spng_plte_entry *plte = decode_plte->rgba;
+
+#if defined(SPNG_ARM)
+ if(fmt == SPNG_FMT_RGBA8) i = expand_palette_rgba8_neon(row, scanline, decode_plte->raw, width);
+ else if(fmt == SPNG_FMT_RGB8)
+ {
+ i = expand_palette_rgb8_neon(row, scanline, decode_plte->raw, width);
+
+ for(; i < width; i++)
+ {/* In this case the LUT is 3 bytes packed */
+ px = row + i * 3;
+ entry = scanline[i];
+ px[0] = decode_plte->raw[entry * 3 + 0];
+ px[1] = decode_plte->raw[entry * 3 + 1];
+ px[2] = decode_plte->raw[entry * 3 + 2];
+ }
+ return;
+ }
+#endif
+
+ if(fmt == SPNG_FMT_RGBA8)
+ {
+ for(; i < width; i++)
+ {
+ px = row + i * 4;
+ entry = scanline[i];
+ px[0] = plte[entry].red;
+ px[1] = plte[entry].green;
+ px[2] = plte[entry].blue;
+ px[3] = plte[entry].alpha;
+ }
+ }
+ else if(fmt == SPNG_FMT_RGB8)
+ {
+ for(; i < width; i++)
+ {
+ px = row + i * 3;
+ entry = scanline[i];
+ px[0] = plte[entry].red;
+ px[1] = plte[entry].green;
+ px[2] = plte[entry].blue;
+ }
+ }
+}
+
+/* Unpack 1/2/4/8-bit samples to G8/GA8/GA16 or G16 -> GA16 */
+static void unpack_scanline(unsigned char *out, const unsigned char *scanline, uint32_t width, unsigned bit_depth, int fmt)
+{
+ struct spng__iter iter = spng__iter_init(bit_depth, scanline);
+ uint32_t i;
+ uint16_t sample, alpha = 65535;
+
+
+ if(fmt == SPNG_FMT_GA8) goto ga8;
+ else if(fmt == SPNG_FMT_GA16) goto ga16;
+
+ /* 1/2/4-bit -> 8-bit */
+ for(i=0; i < width; i++) out[i] = get_sample(&iter);
+
+ return;
+
+ga8:
+ /* 1/2/4/8-bit -> GA8 */
+ for(i=0; i < width; i++)
+ {
+ out[i*2] = get_sample(&iter);
+ out[i*2 + 1] = 255;
+ }
+
+ return;
+
+ga16:
+
+ /* 16 -> GA16 */
+ if(bit_depth == 16)
+ {
+ for(i=0; i < width; i++)
+ {
+ memcpy(out + i * 4, scanline + i * 2, 2);
+ memcpy(out + i * 4 + 2, &alpha, 2);
+ }
+ return;
+ }
+
+ /* 1/2/4/8-bit -> GA16 */
+ for(i=0; i < width; i++)
+ {
+ sample = get_sample(&iter);
+ memcpy(out + i * 4, &sample, 2);
+ memcpy(out + i * 4 + 2, &alpha, 2);
+ }
+}
+
+static int check_ihdr(const struct spng_ihdr *ihdr, uint32_t max_width, uint32_t max_height)
+{
+ if(ihdr->width > spng_u32max || !ihdr->width) return SPNG_EWIDTH;
+ if(ihdr->height > spng_u32max || !ihdr->height) return SPNG_EHEIGHT;
+
+ if(ihdr->width > max_width) return SPNG_EUSER_WIDTH;
+ if(ihdr->height > max_height) return SPNG_EUSER_HEIGHT;
+
+ switch(ihdr->color_type)
+ {
+ case SPNG_COLOR_TYPE_GRAYSCALE:
+ {
+ if( !(ihdr->bit_depth == 1 || ihdr->bit_depth == 2 ||
+ ihdr->bit_depth == 4 || ihdr->bit_depth == 8 ||
+ ihdr->bit_depth == 16) )
+ return SPNG_EBIT_DEPTH;
+
+ break;
+ }
+ case SPNG_COLOR_TYPE_TRUECOLOR:
+ case SPNG_COLOR_TYPE_GRAYSCALE_ALPHA:
+ case SPNG_COLOR_TYPE_TRUECOLOR_ALPHA:
+ {
+ if( !(ihdr->bit_depth == 8 || ihdr->bit_depth == 16) )
+ return SPNG_EBIT_DEPTH;
+
+ break;
+ }
+ case SPNG_COLOR_TYPE_INDEXED:
+ {
+ if( !(ihdr->bit_depth == 1 || ihdr->bit_depth == 2 ||
+ ihdr->bit_depth == 4 || ihdr->bit_depth == 8) )
+ return SPNG_EBIT_DEPTH;
+
+ break;
+ }
+ default: return SPNG_ECOLOR_TYPE;
+ }
+
+ if(ihdr->compression_method) return SPNG_ECOMPRESSION_METHOD;
+ if(ihdr->filter_method) return SPNG_EFILTER_METHOD;
+
+ if(ihdr->interlace_method > 1) return SPNG_EINTERLACE_METHOD;
+
+ return 0;
+}
+
+static int check_plte(const struct spng_plte *plte, const struct spng_ihdr *ihdr)
+{
+ if(plte == NULL || ihdr == NULL) return 1;
+
+ if(plte->n_entries == 0) return 1;
+ if(plte->n_entries > 256) return 1;
+
+ if(ihdr->color_type == SPNG_COLOR_TYPE_INDEXED)
+ {
+ if(plte->n_entries > (1U << ihdr->bit_depth)) return 1;
+ }
+
+ return 0;
+}
+
+static int check_sbit(const struct spng_sbit *sbit, const struct spng_ihdr *ihdr)
+{
+ if(sbit == NULL || ihdr == NULL) return 1;
+
+ if(ihdr->color_type == 0)
+ {
+ if(sbit->grayscale_bits == 0) return SPNG_ESBIT;
+ if(sbit->grayscale_bits > ihdr->bit_depth) return SPNG_ESBIT;
+ }
+ else if(ihdr->color_type == 2 || ihdr->color_type == 3)
+ {
+ if(sbit->red_bits == 0) return SPNG_ESBIT;
+ if(sbit->green_bits == 0) return SPNG_ESBIT;
+ if(sbit->blue_bits == 0) return SPNG_ESBIT;
+
+ uint8_t bit_depth;
+ if(ihdr->color_type == 3) bit_depth = 8;
+ else bit_depth = ihdr->bit_depth;
+
+ if(sbit->red_bits > bit_depth) return SPNG_ESBIT;
+ if(sbit->green_bits > bit_depth) return SPNG_ESBIT;
+ if(sbit->blue_bits > bit_depth) return SPNG_ESBIT;
+ }
+ else if(ihdr->color_type == 4)
+ {
+ if(sbit->grayscale_bits == 0) return SPNG_ESBIT;
+ if(sbit->alpha_bits == 0) return SPNG_ESBIT;
+
+ if(sbit->grayscale_bits > ihdr->bit_depth) return SPNG_ESBIT;
+ if(sbit->alpha_bits > ihdr->bit_depth) return SPNG_ESBIT;
+ }
+ else if(ihdr->color_type == 6)
+ {
+ if(sbit->red_bits == 0) return SPNG_ESBIT;
+ if(sbit->green_bits == 0) return SPNG_ESBIT;
+ if(sbit->blue_bits == 0) return SPNG_ESBIT;
+ if(sbit->alpha_bits == 0) return SPNG_ESBIT;
+
+ if(sbit->red_bits > ihdr->bit_depth) return SPNG_ESBIT;
+ if(sbit->green_bits > ihdr->bit_depth) return SPNG_ESBIT;
+ if(sbit->blue_bits > ihdr->bit_depth) return SPNG_ESBIT;
+ if(sbit->alpha_bits > ihdr->bit_depth) return SPNG_ESBIT;
+ }
+
+ return 0;
+}
+
+static int check_chrm_int(const struct spng_chrm_int *chrm_int)
+{
+ if(chrm_int == NULL) return 1;
+
+ if(chrm_int->white_point_x > spng_u32max ||
+ chrm_int->white_point_y > spng_u32max ||
+ chrm_int->red_x > spng_u32max ||
+ chrm_int->red_y > spng_u32max ||
+ chrm_int->green_x > spng_u32max ||
+ chrm_int->green_y > spng_u32max ||
+ chrm_int->blue_x > spng_u32max ||
+ chrm_int->blue_y > spng_u32max) return SPNG_ECHRM;
+
+ return 0;
+}
+
+static int check_phys(const struct spng_phys *phys)
+{
+ if(phys == NULL) return 1;
+
+ if(phys->unit_specifier > 1) return SPNG_EPHYS;
+
+ if(phys->ppu_x > spng_u32max) return SPNG_EPHYS;
+ if(phys->ppu_y > spng_u32max) return SPNG_EPHYS;
+
+ return 0;
+}
+
+static int check_time(const struct spng_time *time)
+{
+ if(time == NULL) return 1;
+
+ if(time->month == 0 || time->month > 12) return 1;
+ if(time->day == 0 || time->day > 31) return 1;
+ if(time->hour > 23) return 1;
+ if(time->minute > 59) return 1;
+ if(time->second > 60) return 1;
+
+ return 0;
+}
+
+static int check_offs(const struct spng_offs *offs)
+{
+ if(offs == NULL) return 1;
+
+ if(offs->unit_specifier > 1) return 1;
+
+ return 0;
+}
+
+static int check_exif(const struct spng_exif *exif)
+{
+ if(exif == NULL) return 1;
+ if(exif->data == NULL) return 1;
+
+ if(exif->length < 4) return SPNG_ECHUNK_SIZE;
+ if(exif->length > spng_u32max) return SPNG_ECHUNK_STDLEN;
+
+ const uint8_t exif_le[4] = { 73, 73, 42, 0 };
+ const uint8_t exif_be[4] = { 77, 77, 0, 42 };
+
+ if(memcmp(exif->data, exif_le, 4) && memcmp(exif->data, exif_be, 4)) return 1;
+
+ return 0;
+}
+
+/* Validate PNG keyword */
+static int check_png_keyword(const char *str)
+{
+ if(str == NULL) return 1;
+ size_t len = strlen(str);
+ const char *end = str + len;
+
+ if(!len) return 1;
+ if(len > 79) return 1;
+ if(str[0] == ' ') return 1; /* Leading space */
+ if(end[-1] == ' ') return 1; /* Trailing space */
+ if(strstr(str, " ") != NULL) return 1; /* Consecutive spaces */
+
+ uint8_t c;
+ while(str != end)
+ {
+ memcpy(&c, str, 1);
+
+ if( (c >= 32 && c <= 126) || (c >= 161) ) str++;
+ else return 1; /* Invalid character */
+ }
+
+ return 0;
+}
+
+/* Validate PNG text *str up to 'len' bytes */
+static int check_png_text(const char *str, size_t len)
+{/* XXX: are consecutive newlines permitted? */
+ if(str == NULL || len == 0) return 1;
+
+ uint8_t c;
+ size_t i = 0;
+ while(i < len)
+ {
+ memcpy(&c, str + i, 1);
+
+ if( (c >= 32 && c <= 126) || (c >= 161) || c == 10) i++;
+ else return 1; /* Invalid character */
+ }
+
+ return 0;
+}
+
+/* Returns non-zero for standard chunks which are stored without allocating memory */
+static int is_small_chunk(uint8_t type[4])
+{
+ if(!memcmp(type, type_plte, 4)) return 1;
+ else if(!memcmp(type, type_chrm, 4)) return 1;
+ else if(!memcmp(type, type_gama, 4)) return 1;
+ else if(!memcmp(type, type_sbit, 4)) return 1;
+ else if(!memcmp(type, type_srgb, 4)) return 1;
+ else if(!memcmp(type, type_bkgd, 4)) return 1;
+ else if(!memcmp(type, type_trns, 4)) return 1;
+ else if(!memcmp(type, type_hist, 4)) return 1;
+ else if(!memcmp(type, type_phys, 4)) return 1;
+ else if(!memcmp(type, type_time, 4)) return 1;
+ else if(!memcmp(type, type_offs, 4)) return 1;
+ else return 0;
+}
+
+static int read_ihdr(spng_ctx *ctx)
+{
+ int ret;
+ struct spng_chunk *chunk = &ctx->current_chunk;
+ const unsigned char *data;
+
+ chunk->offset = 8;
+ chunk->length = 13;
+ size_t sizeof_sig_ihdr = 29;
+
+ ret = read_data(ctx, sizeof_sig_ihdr);
+ if(ret) return ret;
+
+ data = ctx->data;
+
+ if(memcmp(data, spng_signature, sizeof(spng_signature))) return SPNG_ESIGNATURE;
+
+ chunk->length = read_u32(data + 8);
+ memcpy(&chunk->type, data + 12, 4);
+
+ if(chunk->length != 13) return SPNG_EIHDR_SIZE;
+ if(memcmp(chunk->type, type_ihdr, 4)) return SPNG_ENOIHDR;
+
+ ctx->cur_actual_crc = crc32(0, NULL, 0);
+ ctx->cur_actual_crc = crc32(ctx->cur_actual_crc, data + 12, 17);
+
+ ctx->ihdr.width = read_u32(data + 16);
+ ctx->ihdr.height = read_u32(data + 20);
+ ctx->ihdr.bit_depth = data[24];
+ ctx->ihdr.color_type = data[25];
+ ctx->ihdr.compression_method = data[26];
+ ctx->ihdr.filter_method = data[27];
+ ctx->ihdr.interlace_method = data[28];
+
+ ret = check_ihdr(&ctx->ihdr, ctx->max_width, ctx->max_height);
+ if(ret) return ret;
+
+ ctx->file.ihdr = 1;
+ ctx->stored.ihdr = 1;
+
+ if(ctx->ihdr.bit_depth < 8) ctx->bytes_per_pixel = 1;
+ else ctx->bytes_per_pixel = num_channels(&ctx->ihdr) * (ctx->ihdr.bit_depth / 8);
+
+ ret = calculate_subimages(ctx);
+ if(ret) return ret;
+
+ return 0;
+}
+
+static void splt_undo(spng_ctx *ctx)
+{
+ struct spng_splt *splt = &ctx->splt_list[ctx->n_splt - 1];
+
+ spng__free(ctx, splt->entries);
+
+ decrease_cache_usage(ctx, sizeof(struct spng_splt));
+ decrease_cache_usage(ctx, splt->n_entries * sizeof(struct spng_splt_entry));
+
+ splt->entries = NULL;
+
+ ctx->n_splt--;
+}
+
+static void text_undo(spng_ctx *ctx)
+{
+ struct spng_text2 *text = &ctx->text_list[ctx->n_text - 1];
+
+ spng__free(ctx, text->keyword);
+ if(text->compression_flag) spng__free(ctx, text->text);
+
+ decrease_cache_usage(ctx, text->cache_usage);
+ decrease_cache_usage(ctx, sizeof(struct spng_text2));
+
+ text->keyword = NULL;
+ text->text = NULL;
+
+ ctx->n_text--;
+}
+
+static void chunk_undo(spng_ctx *ctx)
+{
+ struct spng_unknown_chunk *chunk = &ctx->chunk_list[ctx->n_chunks - 1];
+
+ spng__free(ctx, chunk->data);
+
+ decrease_cache_usage(ctx, chunk->length);
+ decrease_cache_usage(ctx, sizeof(struct spng_unknown_chunk));
+
+ chunk->data = NULL;
+
+ ctx->n_chunks--;
+}
+
+static int read_non_idat_chunks(spng_ctx *ctx)
+{
+ int ret;
+ struct spng_chunk chunk;
+ const unsigned char *data;
+
+ ctx->discard = 0;
+ ctx->undo = NULL;
+ ctx->prev_stored = ctx->stored;
+
+ while( !(ret = read_header(ctx)))
+ {
+ if(ctx->discard)
+ {
+ if(ctx->undo) ctx->undo(ctx);
+
+ ctx->stored = ctx->prev_stored;
+ }
+
+ ctx->discard = 0;
+ ctx->undo = NULL;
+
+ ctx->prev_stored = ctx->stored;
+ chunk = ctx->current_chunk;
+
+ if(!memcmp(chunk.type, type_idat, 4))
+ {
+ if(ctx->state < SPNG_STATE_FIRST_IDAT)
+ {
+ if(ctx->ihdr.color_type == 3 && !ctx->stored.plte) return SPNG_ENOPLTE;
+
+ ctx->first_idat = chunk;
+ return 0;
+ }
+
+ if(ctx->prev_was_idat)
+ {
+ /* Ignore extra IDAT's */
+ ret = discard_chunk_bytes(ctx, chunk.length);
+ if(ret) return ret;
+
+ continue;
+ }
+ else return SPNG_ECHUNK_POS; /* IDAT chunk not at the end of the IDAT sequence */
+ }
+
+ ctx->prev_was_idat = 0;
+
+ if(is_small_chunk(chunk.type))
+ {
+ /* None of the known chunks can be zero length */
+ if(!chunk.length) return SPNG_ECHUNK_SIZE;
+
+ /* The largest of these chunks is PLTE with 256 entries */
+ ret = read_chunk_bytes(ctx, chunk.length > 768 ? 768 : chunk.length);
+ if(ret) return ret;
+ }
+
+ data = ctx->data;
+
+ if(is_critical_chunk(&chunk))
+ {
+ if(!memcmp(chunk.type, type_plte, 4))
+ {
+ if(ctx->file.trns || ctx->file.hist || ctx->file.bkgd) return SPNG_ECHUNK_POS;
+ if(chunk.length % 3 != 0) return SPNG_ECHUNK_SIZE;
+
+ ctx->plte.n_entries = chunk.length / 3;
+
+ if(check_plte(&ctx->plte, &ctx->ihdr)) return SPNG_ECHUNK_SIZE; /* XXX: EPLTE? */
+
+ size_t i;
+ for(i=0; i < ctx->plte.n_entries; i++)
+ {
+ ctx->plte.entries[i].red = data[i * 3];
+ ctx->plte.entries[i].green = data[i * 3 + 1];
+ ctx->plte.entries[i].blue = data[i * 3 + 2];
+ }
+
+ ctx->file.plte = 1;
+ ctx->stored.plte = 1;
+ }
+ else if(!memcmp(chunk.type, type_iend, 4))
+ {
+ if(ctx->state == SPNG_STATE_AFTER_IDAT)
+ {
+ if(chunk.length) return SPNG_ECHUNK_SIZE;
+
+ ret = read_and_check_crc(ctx);
+ if(ret == -SPNG_CRC_DISCARD) ret = 0;
+
+ return ret;
+ }
+ else return SPNG_ECHUNK_POS;
+ }
+ else if(!memcmp(chunk.type, type_ihdr, 4)) return SPNG_ECHUNK_POS;
+ else return SPNG_ECHUNK_UNKNOWN_CRITICAL;
+ }
+ else if(!memcmp(chunk.type, type_chrm, 4)) /* Ancillary chunks */
+ {
+ if(ctx->file.plte) return SPNG_ECHUNK_POS;
+ if(ctx->state == SPNG_STATE_AFTER_IDAT) return SPNG_ECHUNK_POS;
+ if(ctx->file.chrm) return SPNG_EDUP_CHRM;
+
+ if(chunk.length != 32) return SPNG_ECHUNK_SIZE;
+
+ ctx->chrm_int.white_point_x = read_u32(data);
+ ctx->chrm_int.white_point_y = read_u32(data + 4);
+ ctx->chrm_int.red_x = read_u32(data + 8);
+ ctx->chrm_int.red_y = read_u32(data + 12);
+ ctx->chrm_int.green_x = read_u32(data + 16);
+ ctx->chrm_int.green_y = read_u32(data + 20);
+ ctx->chrm_int.blue_x = read_u32(data + 24);
+ ctx->chrm_int.blue_y = read_u32(data + 28);
+
+ if(check_chrm_int(&ctx->chrm_int)) return SPNG_ECHRM;
+
+ ctx->file.chrm = 1;
+ ctx->stored.chrm = 1;
+ }
+ else if(!memcmp(chunk.type, type_gama, 4))
+ {
+ if(ctx->file.plte) return SPNG_ECHUNK_POS;
+ if(ctx->state == SPNG_STATE_AFTER_IDAT) return SPNG_ECHUNK_POS;
+ if(ctx->file.gama) return SPNG_EDUP_GAMA;
+
+ if(chunk.length != 4) return SPNG_ECHUNK_SIZE;
+
+ ctx->gama = read_u32(data);
+
+ if(!ctx->gama) return SPNG_EGAMA;
+ if(ctx->gama > spng_u32max) return SPNG_EGAMA;
+
+ ctx->file.gama = 1;
+ ctx->stored.gama = 1;
+ }
+ else if(!memcmp(chunk.type, type_sbit, 4))
+ {
+ if(ctx->file.plte) return SPNG_ECHUNK_POS;
+ if(ctx->state == SPNG_STATE_AFTER_IDAT) return SPNG_ECHUNK_POS;
+ if(ctx->file.sbit) return SPNG_EDUP_SBIT;
+
+ if(ctx->ihdr.color_type == 0)
+ {
+ if(chunk.length != 1) return SPNG_ECHUNK_SIZE;
+
+ ctx->sbit.grayscale_bits = data[0];
+ }
+ else if(ctx->ihdr.color_type == 2 || ctx->ihdr.color_type == 3)
+ {
+ if(chunk.length != 3) return SPNG_ECHUNK_SIZE;
+
+ ctx->sbit.red_bits = data[0];
+ ctx->sbit.green_bits = data[1];
+ ctx->sbit.blue_bits = data[2];
+ }
+ else if(ctx->ihdr.color_type == 4)
+ {
+ if(chunk.length != 2) return SPNG_ECHUNK_SIZE;
+
+ ctx->sbit.grayscale_bits = data[0];
+ ctx->sbit.alpha_bits = data[1];
+ }
+ else if(ctx->ihdr.color_type == 6)
+ {
+ if(chunk.length != 4) return SPNG_ECHUNK_SIZE;
+
+ ctx->sbit.red_bits = data[0];
+ ctx->sbit.green_bits = data[1];
+ ctx->sbit.blue_bits = data[2];
+ ctx->sbit.alpha_bits = data[3];
+ }
+
+ if(check_sbit(&ctx->sbit, &ctx->ihdr)) return SPNG_ESBIT;
+
+ ctx->file.sbit = 1;
+ ctx->stored.sbit = 1;
+ }
+ else if(!memcmp(chunk.type, type_srgb, 4))
+ {
+ if(ctx->file.plte) return SPNG_ECHUNK_POS;
+ if(ctx->state == SPNG_STATE_AFTER_IDAT) return SPNG_ECHUNK_POS;
+ if(ctx->file.srgb) return SPNG_EDUP_SRGB;
+
+ if(chunk.length != 1) return SPNG_ECHUNK_SIZE;
+
+ ctx->srgb_rendering_intent = data[0];
+
+ if(ctx->srgb_rendering_intent > 3) return SPNG_ESRGB;
+
+ ctx->file.srgb = 1;
+ ctx->stored.srgb = 1;
+ }
+ else if(!memcmp(chunk.type, type_bkgd, 4))
+ {
+ if(ctx->state == SPNG_STATE_AFTER_IDAT) return SPNG_ECHUNK_POS;
+ if(ctx->file.bkgd) return SPNG_EDUP_BKGD;
+
+ if(ctx->ihdr.color_type == 0 || ctx->ihdr.color_type == 4)
+ {
+ if(chunk.length != 2) return SPNG_ECHUNK_SIZE;
+
+ ctx->bkgd.gray = read_u16(data);
+ }
+ else if(ctx->ihdr.color_type == 2 || ctx->ihdr.color_type == 6)
+ {
+ if(chunk.length != 6) return SPNG_ECHUNK_SIZE;
+
+ ctx->bkgd.red = read_u16(data);
+ ctx->bkgd.green = read_u16(data + 2);
+ ctx->bkgd.blue = read_u16(data + 4);
+ }
+ else if(ctx->ihdr.color_type == 3)
+ {
+ if(chunk.length != 1) return SPNG_ECHUNK_SIZE;
+ if(!ctx->file.plte) return SPNG_EBKGD_NO_PLTE;
+
+ ctx->bkgd.plte_index = data[0];
+ if(ctx->bkgd.plte_index >= ctx->plte.n_entries) return SPNG_EBKGD_PLTE_IDX;
+ }
+
+ ctx->file.bkgd = 1;
+ ctx->stored.bkgd = 1;
+ }
+ else if(!memcmp(chunk.type, type_trns, 4))
+ {
+ if(ctx->state == SPNG_STATE_AFTER_IDAT) return SPNG_ECHUNK_POS;
+ if(ctx->file.trns) return SPNG_EDUP_TRNS;
+ if(!chunk.length) return SPNG_ECHUNK_SIZE;
+
+ if(ctx->ihdr.color_type == 0)
+ {
+ if(chunk.length != 2) return SPNG_ECHUNK_SIZE;
+
+ ctx->trns.gray = read_u16(data);
+ }
+ else if(ctx->ihdr.color_type == 2)
+ {
+ if(chunk.length != 6) return SPNG_ECHUNK_SIZE;
+
+ ctx->trns.red = read_u16(data);
+ ctx->trns.green = read_u16(data + 2);
+ ctx->trns.blue = read_u16(data + 4);
+ }
+ else if(ctx->ihdr.color_type == 3)
+ {
+ if(chunk.length > ctx->plte.n_entries) return SPNG_ECHUNK_SIZE;
+ if(!ctx->file.plte) return SPNG_ETRNS_NO_PLTE;
+
+ memcpy(ctx->trns.type3_alpha, data, chunk.length);
+ ctx->trns.n_type3_entries = chunk.length;
+ }
+
+ if(ctx->ihdr.color_type == 4 || ctx->ihdr.color_type == 6) return SPNG_ETRNS_COLOR_TYPE;
+
+ ctx->file.trns = 1;
+ ctx->stored.trns = 1;
+ }
+ else if(!memcmp(chunk.type, type_hist, 4))
+ {
+ if(!ctx->file.plte) return SPNG_EHIST_NO_PLTE;
+ if(ctx->state == SPNG_STATE_AFTER_IDAT) return SPNG_ECHUNK_POS;
+ if(ctx->file.hist) return SPNG_EDUP_HIST;
+
+ if( (chunk.length / 2) != (ctx->plte.n_entries) ) return SPNG_ECHUNK_SIZE;
+
+ size_t k;
+ for(k=0; k < (chunk.length / 2); k++)
+ {
+ ctx->hist.frequency[k] = read_u16(data + k*2);
+ }
+
+ ctx->file.hist = 1;
+ ctx->stored.hist = 1;
+ }
+ else if(!memcmp(chunk.type, type_phys, 4))
+ {
+ if(ctx->state == SPNG_STATE_AFTER_IDAT) return SPNG_ECHUNK_POS;
+ if(ctx->file.phys) return SPNG_EDUP_PHYS;
+
+ if(chunk.length != 9) return SPNG_ECHUNK_SIZE;
+
+ ctx->phys.ppu_x = read_u32(data);
+ ctx->phys.ppu_y = read_u32(data + 4);
+ ctx->phys.unit_specifier = data[8];
+
+ if(check_phys(&ctx->phys)) return SPNG_EPHYS;
+
+ ctx->file.phys = 1;
+ ctx->stored.phys = 1;
+ }
+ else if(!memcmp(chunk.type, type_time, 4))
+ {
+ if(ctx->file.time) return SPNG_EDUP_TIME;
+
+ if(chunk.length != 7) return SPNG_ECHUNK_SIZE;
+
+ struct spng_time time;
+
+ time.year = read_u16(data);
+ time.month = data[2];
+ time.day = data[3];
+ time.hour = data[4];
+ time.minute = data[5];
+ time.second = data[6];
+
+ if(check_time(&time)) return SPNG_ETIME;
+
+ ctx->file.time = 1;
+
+ if(!ctx->user.time) ctx->time = time;
+
+ ctx->stored.time = 1;
+ }
+ else if(!memcmp(chunk.type, type_offs, 4))
+ {
+ if(ctx->state == SPNG_STATE_AFTER_IDAT) return SPNG_ECHUNK_POS;
+ if(ctx->file.offs) return SPNG_EDUP_OFFS;
+
+ if(chunk.length != 9) return SPNG_ECHUNK_SIZE;
+
+ ctx->offs.x = read_s32(data);
+ ctx->offs.y = read_s32(data + 4);
+ ctx->offs.unit_specifier = data[8];
+
+ if(check_offs(&ctx->offs)) return SPNG_EOFFS;
+
+ ctx->file.offs = 1;
+ ctx->stored.offs = 1;
+ }
+ else /* Arbitrary-length chunk */
+ {
+
+ if(!memcmp(chunk.type, type_exif, 4))
+ {
+ if(ctx->file.exif) return SPNG_EDUP_EXIF;
+ if(!chunk.length) return SPNG_EEXIF;
+
+ ctx->file.exif = 1;
+
+ if(ctx->user.exif) goto discard;
+
+ if(increase_cache_usage(ctx, chunk.length, 1)) return SPNG_ECHUNK_LIMITS;
+
+ struct spng_exif exif;
+
+ exif.length = chunk.length;
+
+ exif.data = spng__malloc(ctx, chunk.length);
+ if(exif.data == NULL) return SPNG_EMEM;
+
+ ret = read_chunk_bytes2(ctx, exif.data, chunk.length);
+ if(ret)
+ {
+ spng__free(ctx, exif.data);
+ return ret;
+ }
+
+ if(check_exif(&exif))
+ {
+ spng__free(ctx, exif.data);
+ return SPNG_EEXIF;
+ }
+
+ ctx->exif = exif;
+
+ ctx->stored.exif = 1;
+ }
+ else if(!memcmp(chunk.type, type_iccp, 4))
+ {/* TODO: add test file with color profile */
+ if(ctx->file.plte) return SPNG_ECHUNK_POS;
+ if(ctx->state == SPNG_STATE_AFTER_IDAT) return SPNG_ECHUNK_POS;
+ if(ctx->file.iccp) return SPNG_EDUP_ICCP;
+ if(!chunk.length) return SPNG_ECHUNK_SIZE;
+
+ ctx->file.iccp = 1;
+
+ uint32_t peek_bytes = 81 > chunk.length ? chunk.length : 81;
+
+ ret = read_chunk_bytes(ctx, peek_bytes);
+ if(ret) return ret;
+
+ unsigned char *keyword_nul = memchr(ctx->data, '\0', peek_bytes);
+ if(keyword_nul == NULL) return SPNG_EICCP_NAME;
+
+ uint32_t keyword_len = keyword_nul - ctx->data;
+
+ if(keyword_len > 79) return SPNG_EICCP_NAME;
+
+ memcpy(ctx->iccp.profile_name, ctx->data, keyword_len);
+
+ if(check_png_keyword(ctx->iccp.profile_name)) return SPNG_EICCP_NAME;
+
+ if(chunk.length < (keyword_len + 2)) return SPNG_ECHUNK_SIZE;
+
+ if(ctx->data[keyword_len + 1] != 0) return SPNG_EICCP_COMPRESSION_METHOD;
+
+ ret = spng__inflate_stream(ctx, &ctx->iccp.profile, &ctx->iccp.profile_len, 0, ctx->data + keyword_len + 2, peek_bytes - (keyword_len + 2));
+
+ if(ret) return ret;
+
+ ctx->stored.iccp = 1;
+ }
+ else if(!memcmp(chunk.type, type_text, 4) ||
+ !memcmp(chunk.type, type_ztxt, 4) ||
+ !memcmp(chunk.type, type_itxt, 4))
+ {
+ if(!chunk.length) return SPNG_ECHUNK_SIZE;
+
+ ctx->file.text = 1;
+
+ if(ctx->user.text) goto discard;
+
+ if(increase_cache_usage(ctx, sizeof(struct spng_text2), 1)) return SPNG_ECHUNK_LIMITS;
+
+ ctx->n_text++;
+ if(ctx->n_text < 1) return SPNG_EOVERFLOW;
+ if(sizeof(struct spng_text2) > SIZE_MAX / ctx->n_text) return SPNG_EOVERFLOW;
+
+ void *buf = spng__realloc(ctx, ctx->text_list, ctx->n_text * sizeof(struct spng_text2));
+ if(buf == NULL) return SPNG_EMEM;
+ ctx->text_list = buf;
+
+ struct spng_text2 *text = &ctx->text_list[ctx->n_text - 1];
+ memset(text, 0, sizeof(struct spng_text2));
+
+ ctx->undo = text_undo;
+
+ uint32_t text_offset = 0, language_tag_offset = 0, translated_keyword_offset = 0;
+ uint32_t peek_bytes = 256; /* enough for 3 80-byte keywords and some text bytes */
+ uint32_t keyword_len;
+
+ if(peek_bytes > chunk.length) peek_bytes = chunk.length;
+
+ ret = read_chunk_bytes(ctx, peek_bytes);
+ if(ret) return ret;
+
+ data = ctx->data;
+
+ const unsigned char *zlib_stream = NULL;
+ const unsigned char *peek_end = data + peek_bytes;
+ const unsigned char *keyword_nul = memchr(data, 0, chunk.length > 80 ? 80 : chunk.length);
+
+ if(keyword_nul == NULL) return SPNG_ETEXT_KEYWORD;
+
+ keyword_len = keyword_nul - data;
+
+ if(!memcmp(chunk.type, type_text, 4))
+ {
+ text->type = SPNG_TEXT;
+
+ text->text_length = chunk.length - keyword_len - 1;
+
+ text_offset = keyword_len;
+
+ /* increment past nul if there is a text field */
+ if(text->text_length) text_offset++;
+ }
+ else if(!memcmp(chunk.type, type_ztxt, 4))
+ {
+ text->type = SPNG_ZTXT;
+
+ if((peek_bytes - keyword_len) <= 2) return SPNG_EZTXT;
+
+ if(keyword_nul[1]) return SPNG_EZTXT_COMPRESSION_METHOD;
+
+ text->compression_flag = 1;
+
+ text_offset = keyword_len + 2;
+ }
+ else if(!memcmp(chunk.type, type_itxt, 4))
+ {
+ text->type = SPNG_ITXT;
+
+ /* at least two 1-byte fields, two >=0 length strings, and one byte of (compressed) text */
+ if((peek_bytes - keyword_len) < 5) return SPNG_EITXT;
+
+ text->compression_flag = keyword_nul[1];
+
+ if(text->compression_flag > 1) return SPNG_EITXT_COMPRESSION_FLAG;
+
+ if(keyword_nul[2]) return SPNG_EITXT_COMPRESSION_METHOD;
+
+ language_tag_offset = keyword_len + 3;
+
+ const unsigned char *term;
+ term = memchr(data + language_tag_offset, 0, peek_bytes - language_tag_offset);
+ if(term == NULL) return SPNG_EITXT_LANG_TAG;
+
+ if((peek_end - term) < 2) return SPNG_EITXT;
+
+ translated_keyword_offset = term - data + 1;
+
+ zlib_stream = memchr(data + translated_keyword_offset, 0, peek_bytes - translated_keyword_offset);
+ if(zlib_stream == NULL) return SPNG_EITXT;
+ if(zlib_stream == peek_end) return SPNG_EITXT;
+
+ text_offset = zlib_stream - data + 1;
+ text->text_length = chunk.length - text_offset;
+ }
+ else return SPNG_EINTERNAL;
+
+
+ if(text->compression_flag)
+ {
+ /* cache usage = peek_bytes + decompressed text size + nul */
+ if(increase_cache_usage(ctx, peek_bytes, 0)) return SPNG_ECHUNK_LIMITS;
+
+ text->keyword = spng__calloc(ctx, 1, peek_bytes);
+ if(text->keyword == NULL) return SPNG_EMEM;
+
+ memcpy(text->keyword, data, peek_bytes);
+
+ zlib_stream = ctx->data + text_offset;
+
+ ret = spng__inflate_stream(ctx, &text->text, &text->text_length, 1, zlib_stream, peek_bytes - text_offset);
+
+ if(ret) return ret;
+
+ text->text[text->text_length - 1] = '\0';
+ text->cache_usage = text->text_length + peek_bytes;
+ }
+ else
+ {
+ if(increase_cache_usage(ctx, chunk.length + 1, 0)) return SPNG_ECHUNK_LIMITS;
+
+ text->keyword = spng__malloc(ctx, chunk.length + 1);
+ if(text->keyword == NULL) return SPNG_EMEM;
+
+ memcpy(text->keyword, data, peek_bytes);
+
+ if(chunk.length > peek_bytes)
+ {
+ ret = read_chunk_bytes2(ctx, text->keyword + peek_bytes, chunk.length - peek_bytes);
+ if(ret) return ret;
+ }
+
+ text->text = text->keyword + text_offset;
+
+ text->text_length = chunk.length - text_offset;
+
+ text->text[text->text_length] = '\0';
+ text->cache_usage = chunk.length + 1;
+ }
+
+ if(check_png_keyword(text->keyword)) return SPNG_ETEXT_KEYWORD;
+
+ text->text_length = strlen(text->text);
+
+ if(text->type != SPNG_ITXT)
+ {
+ language_tag_offset = keyword_len;
+ translated_keyword_offset = keyword_len;
+
+ if(ctx->strict && check_png_text(text->text, text->text_length))
+ {
+ if(text->type == SPNG_ZTXT) return SPNG_EZTXT;
+ else return SPNG_ETEXT;
+ }
+ }
+
+ text->language_tag = text->keyword + language_tag_offset;
+ text->translated_keyword = text->keyword + translated_keyword_offset;
+
+ ctx->stored.text = 1;
+ }
+ else if(!memcmp(chunk.type, type_splt, 4))
+ {
+ if(ctx->state == SPNG_STATE_AFTER_IDAT) return SPNG_ECHUNK_POS;
+ if(ctx->user.splt) goto discard; /* XXX: could check profile names for uniqueness */
+ if(!chunk.length) return SPNG_ECHUNK_SIZE;
+
+ ctx->file.splt = 1;
+
+ /* chunk.length + sizeof(struct spng_splt) + splt->n_entries * sizeof(struct spng_splt_entry) */
+ if(increase_cache_usage(ctx, chunk.length + sizeof(struct spng_splt), 1)) return SPNG_ECHUNK_LIMITS;
+
+ ctx->n_splt++;
+ if(ctx->n_splt < 1) return SPNG_EOVERFLOW;
+ if(sizeof(struct spng_splt) > SIZE_MAX / ctx->n_splt) return SPNG_EOVERFLOW;
+
+ void *buf = spng__realloc(ctx, ctx->splt_list, ctx->n_splt * sizeof(struct spng_splt));
+ if(buf == NULL) return SPNG_EMEM;
+ ctx->splt_list = buf;
+
+ struct spng_splt *splt = &ctx->splt_list[ctx->n_splt - 1];
+
+ memset(splt, 0, sizeof(struct spng_splt));
+
+ ctx->undo = splt_undo;
+
+ void *t = spng__malloc(ctx, chunk.length);
+ if(t == NULL) return SPNG_EMEM;
+
+ splt->entries = t; /* simplifies error handling */
+ data = t;
+
+ ret = read_chunk_bytes2(ctx, t, chunk.length);
+ if(ret) return ret;
+
+ uint32_t keyword_len = chunk.length < 80 ? chunk.length : 80;
+
+ const unsigned char *keyword_nul = memchr(data, 0, keyword_len);
+ if(keyword_nul == NULL) return SPNG_ESPLT_NAME;
+
+ keyword_len = keyword_nul - data;
+
+ memcpy(splt->name, data, keyword_len);
+
+ if(check_png_keyword(splt->name)) return SPNG_ESPLT_NAME;
+
+ uint32_t j;
+ for(j=0; j < (ctx->n_splt - 1); j++)
+ {
+ if(!strcmp(ctx->splt_list[j].name, splt->name)) return SPNG_ESPLT_DUP_NAME;
+ }
+
+ if( (chunk.length - keyword_len) <= 2) return SPNG_ECHUNK_SIZE;
+
+ splt->sample_depth = data[keyword_len + 1];
+
+ uint32_t entries_len = chunk.length - keyword_len - 2;
+ if(!entries_len) return SPNG_ECHUNK_SIZE;
+
+ if(splt->sample_depth == 16)
+ {
+ if(entries_len % 10 != 0) return SPNG_ECHUNK_SIZE;
+ splt->n_entries = entries_len / 10;
+ }
+ else if(splt->sample_depth == 8)
+ {
+ if(entries_len % 6 != 0) return SPNG_ECHUNK_SIZE;
+ splt->n_entries = entries_len / 6;
+ }
+ else return SPNG_ESPLT_DEPTH;
+
+ if(!splt->n_entries) return SPNG_ECHUNK_SIZE;
+
+ size_t list_size = splt->n_entries;
+
+ if(list_size > SIZE_MAX / sizeof(struct spng_splt_entry)) return SPNG_EOVERFLOW;
+
+ list_size *= sizeof(struct spng_splt_entry);
+
+ if(increase_cache_usage(ctx, list_size, 0)) return SPNG_ECHUNK_LIMITS;
+
+ splt->entries = spng__malloc(ctx, list_size);
+ if(splt->entries == NULL)
+ {
+ spng__free(ctx, t);
+ return SPNG_EMEM;
+ }
+
+ data = (unsigned char*)t + keyword_len + 2;
+
+ uint32_t k;
+ if(splt->sample_depth == 16)
+ {
+ for(k=0; k < splt->n_entries; k++)
+ {
+ splt->entries[k].red = read_u16(data + k * 10);
+ splt->entries[k].green = read_u16(data + k * 10 + 2);
+ splt->entries[k].blue = read_u16(data + k * 10 + 4);
+ splt->entries[k].alpha = read_u16(data + k * 10 + 6);
+ splt->entries[k].frequency = read_u16(data + k * 10 + 8);
+ }
+ }
+ else if(splt->sample_depth == 8)
+ {
+ for(k=0; k < splt->n_entries; k++)
+ {
+ splt->entries[k].red = data[k * 6];
+ splt->entries[k].green = data[k * 6 + 1];
+ splt->entries[k].blue = data[k * 6 + 2];
+ splt->entries[k].alpha = data[k * 6 + 3];
+ splt->entries[k].frequency = read_u16(data + k * 6 + 4);
+ }
+ }
+
+ spng__free(ctx, t);
+ decrease_cache_usage(ctx, chunk.length);
+
+ ctx->stored.splt = 1;
+ }
+ else /* Unknown chunk */
+ {
+ ctx->file.unknown = 1;
+
+ if(!ctx->keep_unknown) goto discard;
+ if(ctx->user.unknown) goto discard;
+
+ if(increase_cache_usage(ctx, chunk.length + sizeof(struct spng_unknown_chunk), 1)) return SPNG_ECHUNK_LIMITS;
+
+ ctx->n_chunks++;
+ if(ctx->n_chunks < 1) return SPNG_EOVERFLOW;
+ if(sizeof(struct spng_unknown_chunk) > SIZE_MAX / ctx->n_chunks) return SPNG_EOVERFLOW;
+
+ void *buf = spng__realloc(ctx, ctx->chunk_list, ctx->n_chunks * sizeof(struct spng_unknown_chunk));
+ if(buf == NULL) return SPNG_EMEM;
+ ctx->chunk_list = buf;
+
+ struct spng_unknown_chunk *chunkp = &ctx->chunk_list[ctx->n_chunks - 1];
+
+ memset(chunkp, 0, sizeof(struct spng_unknown_chunk));
+
+ ctx->undo = chunk_undo;
+
+ memcpy(chunkp->type, chunk.type, 4);
+
+ if(ctx->state < SPNG_STATE_FIRST_IDAT)
+ {
+ if(ctx->file.plte) chunkp->location = SPNG_AFTER_PLTE;
+ else chunkp->location = SPNG_AFTER_IHDR;
+ }
+ else if(ctx->state >= SPNG_STATE_AFTER_IDAT) chunkp->location = SPNG_AFTER_IDAT;
+
+ if(chunk.length > 0)
+ {
+ void *t = spng__malloc(ctx, chunk.length);
+ if(t == NULL) return SPNG_EMEM;
+
+ ret = read_chunk_bytes2(ctx, t, chunk.length);
+ if(ret)
+ {
+ spng__free(ctx, t);
+ return ret;
+ }
+
+ chunkp->length = chunk.length;
+ chunkp->data = t;
+ }
+
+ ctx->stored.unknown = 1;
+ }
+
+discard:
+ ret = discard_chunk_bytes(ctx, ctx->cur_chunk_bytes_left);
+ if(ret) return ret;
+ }
+
+ }
+
+ return ret;
+}
+
+/* Read chunks before or after the IDAT chunks depending on state */
+static int read_chunks(spng_ctx *ctx, int only_ihdr)
+{
+ if(ctx == NULL) return SPNG_EINTERNAL;
+ if(!ctx->state) return SPNG_EBADSTATE;
+ if(ctx->data == NULL)
+ {
+ if(ctx->encode_only) return 0;
+ else return SPNG_EINTERNAL;
+ }
+
+ int ret = 0;
+
+ if(ctx->state == SPNG_STATE_INPUT)
+ {
+ ret = read_ihdr(ctx);
+
+ if(ret) return decode_err(ctx, ret);
+
+ ctx->state = SPNG_STATE_IHDR;
+ }
+
+ if(only_ihdr) return 0;
+
+ if(ctx->state == SPNG_STATE_EOI)
+ {
+ ctx->state = SPNG_STATE_AFTER_IDAT;
+ ctx->prev_was_idat = 1;
+ }
+
+ while(ctx->state < SPNG_STATE_FIRST_IDAT || ctx->state == SPNG_STATE_AFTER_IDAT)
+ {
+ ret = read_non_idat_chunks(ctx);
+
+ if(!ret)
+ {
+ if(ctx->state < SPNG_STATE_FIRST_IDAT) ctx->state = SPNG_STATE_FIRST_IDAT;
+ else if(ctx->state == SPNG_STATE_AFTER_IDAT) ctx->state = SPNG_STATE_IEND;
+ }
+ else
+ {
+ switch(ret)
+ {
+ case SPNG_ECHUNK_POS:
+ case SPNG_ECHUNK_SIZE: /* size != expected size, SPNG_ECHUNK_STDLEN = invalid size */
+ case SPNG_EDUP_PLTE:
+ case SPNG_EDUP_CHRM:
+ case SPNG_EDUP_GAMA:
+ case SPNG_EDUP_ICCP:
+ case SPNG_EDUP_SBIT:
+ case SPNG_EDUP_SRGB:
+ case SPNG_EDUP_BKGD:
+ case SPNG_EDUP_HIST:
+ case SPNG_EDUP_TRNS:
+ case SPNG_EDUP_PHYS:
+ case SPNG_EDUP_TIME:
+ case SPNG_EDUP_OFFS:
+ case SPNG_EDUP_EXIF:
+ case SPNG_ECHRM:
+ case SPNG_ETRNS_COLOR_TYPE:
+ case SPNG_ETRNS_NO_PLTE:
+ case SPNG_EGAMA:
+ case SPNG_EICCP_NAME:
+ case SPNG_EICCP_COMPRESSION_METHOD:
+ case SPNG_ESBIT:
+ case SPNG_ESRGB:
+ case SPNG_ETEXT:
+ case SPNG_ETEXT_KEYWORD:
+ case SPNG_EZTXT:
+ case SPNG_EZTXT_COMPRESSION_METHOD:
+ case SPNG_EITXT:
+ case SPNG_EITXT_COMPRESSION_FLAG:
+ case SPNG_EITXT_COMPRESSION_METHOD:
+ case SPNG_EITXT_LANG_TAG:
+ case SPNG_EITXT_TRANSLATED_KEY:
+ case SPNG_EBKGD_NO_PLTE:
+ case SPNG_EBKGD_PLTE_IDX:
+ case SPNG_EHIST_NO_PLTE:
+ case SPNG_EPHYS:
+ case SPNG_ESPLT_NAME:
+ case SPNG_ESPLT_DUP_NAME:
+ case SPNG_ESPLT_DEPTH:
+ case SPNG_ETIME:
+ case SPNG_EOFFS:
+ case SPNG_EEXIF:
+ case SPNG_EZLIB:
+ {
+ if(!ctx->strict && !is_critical_chunk(&ctx->current_chunk))
+ {
+ ret = discard_chunk_bytes(ctx, ctx->cur_chunk_bytes_left);
+ if(ret) return decode_err(ctx, ret);
+
+ if(ctx->undo) ctx->undo(ctx);
+
+ ctx->stored = ctx->prev_stored;
+
+ ctx->discard = 0;
+ ctx->undo = NULL;
+
+ continue;
+ }
+ else return decode_err(ctx, ret);
+
+ break;
+ }
+ default: return decode_err(ctx, ret);
+ }
+ }
+ }
+
+ return ret;
+}
+
+static int read_scanline(spng_ctx *ctx)
+{
+ int ret, pass = ctx->row_info.pass;
+ struct spng_row_info *ri = &ctx->row_info;
+ const struct spng_subimage *sub = ctx->subimage;
+ size_t scanline_width = sub[pass].scanline_width;
+ uint32_t scanline_idx = ri->scanline_idx;
+
+ uint8_t next_filter = 0;
+
+ if(scanline_idx == (sub[pass].height - 1) && ri->pass == ctx->last_pass)
+ {
+ ret = read_scanline_bytes(ctx, ctx->scanline, scanline_width - 1);
+ }
+ else
+ {
+ ret = read_scanline_bytes(ctx, ctx->scanline, scanline_width);
+ if(ret) return ret;
+
+ next_filter = ctx->scanline[scanline_width - 1];
+ if(next_filter > 4) ret = SPNG_EFILTER;
+ }
+
+ if(ret) return ret;
+
+ if(!scanline_idx && ri->filter > 1)
+ {
+ /* prev_scanline is all zeros for the first scanline */
+ memset(ctx->prev_scanline, 0, scanline_width);
+ }
+
+ if(ctx->ihdr.bit_depth == 16 && ctx->fmt != SPNG_FMT_RAW) u16_row_to_host(ctx->scanline, scanline_width - 1);
+
+ ret = defilter_scanline(ctx->prev_scanline, ctx->scanline, scanline_width, ctx->bytes_per_pixel, ri->filter);
+ if(ret) return ret;
+
+ ri->filter = next_filter;
+
+ return 0;
+}
+
+static int update_row_info(spng_ctx *ctx)
+{
+ int interlacing = ctx->ihdr.interlace_method;
+ struct spng_row_info *ri = &ctx->row_info;
+ const struct spng_subimage *sub = ctx->subimage;
+
+ if(ri->scanline_idx == (sub[ri->pass].height - 1)) /* Last scanline */
+ {
+ if(ri->pass == ctx->last_pass)
+ {
+ ctx->state = SPNG_STATE_EOI;
+
+ return SPNG_EOI;
+ }
+
+ ri->scanline_idx = 0;
+ ri->pass++;
+
+ /* Skip empty passes */
+ while( (!sub[ri->pass].width || !sub[ri->pass].height) && (ri->pass < ctx->last_pass)) ri->pass++;
+ }
+ else
+ {
+ ri->row_num++;
+ ri->scanline_idx++;
+ }
+
+ if(interlacing) ri->row_num = adam7_y_start[ri->pass] + ri->scanline_idx * adam7_y_delta[ri->pass];
+
+ return 0;
+}
+
+int spng_decode_scanline(spng_ctx *ctx, void *out, size_t len)
+{
+ if(ctx == NULL || out == NULL) return 1;
+
+ if(ctx->state >= SPNG_STATE_EOI) return SPNG_EOI;
+
+ struct decode_flags f = ctx->decode_flags;
+
+ struct spng_row_info *ri = &ctx->row_info;
+ const struct spng_subimage *sub = ctx->subimage;
+
+ const struct spng_ihdr *ihdr = &ctx->ihdr;
+ const uint16_t *gamma_lut = ctx->gamma_lut;
+ unsigned char *trns_px = ctx->trns_px;
+ const struct spng_sbit *sb = &ctx->decode_sb;
+ const struct spng_plte_entry *plte = ctx->decode_plte.rgba;
+ struct spng__iter iter = spng__iter_init(ihdr->bit_depth, ctx->scanline);
+
+ const unsigned char *scanline;
+
+ const int pass = ri->pass;
+ const int fmt = ctx->fmt;
+ const size_t scanline_width = sub[pass].scanline_width;
+ const uint32_t width = sub[pass].width;
+ uint32_t k;
+ uint8_t r_8, g_8, b_8, a_8, gray_8;
+ uint16_t r_16, g_16, b_16, a_16, gray_16;
+ r_8=0; g_8=0; b_8=0; a_8=0; gray_8=0;
+ r_16=0; g_16=0; b_16=0; a_16=0; gray_16=0;
+ size_t pixel_size = 4; /* SPNG_FMT_RGBA8 */
+ size_t pixel_offset = 0;
+ unsigned char *pixel;
+ unsigned processing_depth = ihdr->bit_depth;
+
+ if(f.indexed) processing_depth = 8;
+
+ if(fmt == SPNG_FMT_RGBA16) pixel_size = 8;
+ else if(fmt == SPNG_FMT_RGB8) pixel_size = 3;
+
+ if(len < sub[pass].out_width) return SPNG_EBUFSIZ;
+
+ int ret = read_scanline(ctx);
+
+ if(ret) return decode_err(ctx, ret);
+
+ scanline = ctx->scanline;
+
+ for(k=0; k < width; k++)
+ {
+ pixel = (unsigned char*)out + pixel_offset;
+ pixel_offset += pixel_size;
+
+ if(f.same_layout)
+ {
+ if(f.zerocopy) break;
+
+ memcpy(out, scanline, scanline_width - 1);
+ break;
+ }
+
+ if(f.unpack)
+ {
+ unpack_scanline(out, scanline, width, ihdr->bit_depth, fmt);
+ break;
+ }
+
+ if(ihdr->color_type == SPNG_COLOR_TYPE_TRUECOLOR)
+ {
+ if(ihdr->bit_depth == 16)
+ {
+ memcpy(&r_16, scanline + (k * 6), 2);
+ memcpy(&g_16, scanline + (k * 6) + 2, 2);
+ memcpy(&b_16, scanline + (k * 6) + 4, 2);
+
+ a_16 = 65535;
+ }
+ else /* == 8 */
+ {
+ if(fmt == SPNG_FMT_RGBA8)
+ {
+ rgb8_row_to_rgba8(scanline, out, width);
+ break;
+ }
+
+ r_8 = scanline[k * 3];
+ g_8 = scanline[k * 3 + 1];
+ b_8 = scanline[k * 3 + 2];
+
+ a_8 = 255;
+ }
+ }
+ else if(ihdr->color_type == SPNG_COLOR_TYPE_INDEXED)
+ {
+ uint8_t entry = 0;
+
+ if(ihdr->bit_depth == 8)
+ {
+ if(fmt & (SPNG_FMT_RGBA8 | SPNG_FMT_RGB8))
+ {
+ expand_row(out, scanline, &ctx->decode_plte, width, fmt);
+ break;
+ }
+
+ entry = scanline[k];
+ }
+ else /* < 8 */
+ {
+ entry = get_sample(&iter);
+ }
+
+ if(fmt & (SPNG_FMT_RGBA8 | SPNG_FMT_RGB8))
+ {
+ pixel[0] = plte[entry].red;
+ pixel[1] = plte[entry].green;
+ pixel[2] = plte[entry].blue;
+ if(fmt == SPNG_FMT_RGBA8) pixel[3] = plte[entry].alpha;
+
+ continue;
+ }
+ else /* RGBA16 */
+ {
+ r_16 = plte[entry].red;
+ g_16 = plte[entry].green;
+ b_16 = plte[entry].blue;
+ a_16 = plte[entry].alpha;
+
+ r_16 = (r_16 << 8) | r_16;
+ g_16 = (g_16 << 8) | g_16;
+ b_16 = (b_16 << 8) | b_16;
+ a_16 = (a_16 << 8) | a_16;
+
+ memcpy(pixel, &r_16, 2);
+ memcpy(pixel + 2, &g_16, 2);
+ memcpy(pixel + 4, &b_16, 2);
+ memcpy(pixel + 6, &a_16, 2);
+
+ continue;
+ }
+ }
+ else if(ihdr->color_type == SPNG_COLOR_TYPE_TRUECOLOR_ALPHA)
+ {
+ if(ihdr->bit_depth == 16)
+ {
+ memcpy(&r_16, scanline + (k * 8), 2);
+ memcpy(&g_16, scanline + (k * 8) + 2, 2);
+ memcpy(&b_16, scanline + (k * 8) + 4, 2);
+ memcpy(&a_16, scanline + (k * 8) + 6, 2);
+ }
+ else /* == 8 */
+ {
+ r_8 = scanline[k * 4];
+ g_8 = scanline[k * 4 + 1];
+ b_8 = scanline[k * 4 + 2];
+ a_8 = scanline[k * 4 + 3];
+ }
+ }
+ else if(ihdr->color_type == SPNG_COLOR_TYPE_GRAYSCALE)
+ {
+ if(ihdr->bit_depth == 16)
+ {
+ memcpy(&gray_16, scanline + k * 2, 2);
+
+ if(f.apply_trns && ctx->trns.gray == gray_16) a_16 = 0;
+ else a_16 = 65535;
+
+ r_16 = gray_16;
+ g_16 = gray_16;
+ b_16 = gray_16;
+ }
+ else /* <= 8 */
+ {
+ gray_8 = get_sample(&iter);
+
+ if(f.apply_trns && ctx->trns.gray == gray_8) a_8 = 0;
+ else a_8 = 255;
+
+ r_8 = gray_8; g_8 = gray_8; b_8 = gray_8;
+ }
+ }
+ else if(ihdr->color_type == SPNG_COLOR_TYPE_GRAYSCALE_ALPHA)
+ {
+ if(ihdr->bit_depth == 16)
+ {
+ memcpy(&gray_16, scanline + (k * 4), 2);
+ memcpy(&a_16, scanline + (k * 4) + 2, 2);
+
+ r_16 = gray_16;
+ g_16 = gray_16;
+ b_16 = gray_16;
+ }
+ else /* == 8 */
+ {
+ gray_8 = scanline[k * 2];
+ a_8 = scanline[k * 2 + 1];
+
+ r_8 = gray_8;
+ g_8 = gray_8;
+ b_8 = gray_8;
+ }
+ }
+
+
+ if(fmt & (SPNG_FMT_RGBA8 | SPNG_FMT_RGB8))
+ {
+ if(ihdr->bit_depth == 16)
+ {
+ r_8 = r_16 >> 8;
+ g_8 = g_16 >> 8;
+ b_8 = b_16 >> 8;
+ a_8 = a_16 >> 8;
+ }
+
+ pixel[0] = r_8;
+ pixel[1] = g_8;
+ pixel[2] = b_8;
+
+ if(fmt == SPNG_FMT_RGBA8) pixel[3] = a_8;
+ }
+ else if(fmt == SPNG_FMT_RGBA16)
+ {
+ if(ihdr->bit_depth != 16)
+ {
+ r_16 = r_8;
+ g_16 = g_8;
+ b_16 = b_8;
+ a_16 = a_8;
+ }
+
+ memcpy(pixel, &r_16, 2);
+ memcpy(pixel + 2, &g_16, 2);
+ memcpy(pixel + 4, &b_16, 2);
+ memcpy(pixel + 6, &a_16, 2);
+ }
+ }/* for(k=0; k < width; k++) */
+
+ if(f.apply_trns) trns_row(out, scanline, trns_px, ctx->bytes_per_pixel, &ctx->ihdr, width, fmt);
+
+ if(f.do_scaling) scale_row(out, width, fmt, processing_depth, sb);
+
+ if(f.apply_gamma) gamma_correct_row(out, width, fmt, gamma_lut);
+
+ /* The previous scanline is always defiltered */
+ void *t = ctx->prev_scanline;
+ ctx->prev_scanline = ctx->scanline;
+ ctx->scanline = t;
+
+ ret = update_row_info(ctx);
+
+ if(ret == SPNG_EOI)
+ {
+ if(ctx->cur_chunk_bytes_left) /* zlib stream ended before an IDAT chunk boundary */
+ {/* Discard the rest of the chunk */
+ int error = discard_chunk_bytes(ctx, ctx->cur_chunk_bytes_left);
+ if(error) return decode_err(ctx, error);
+ }
+
+ ctx->last_idat = ctx->current_chunk;
+ }
+
+ return ret;
+}
+
+int spng_decode_row(spng_ctx *ctx, void *out, size_t len)
+{
+ if(ctx == NULL || out == NULL) return 1;
+ if(ctx->state >= SPNG_STATE_EOI) return SPNG_EOI;
+ if(len < ctx->image_width) return SPNG_EBUFSIZ;
+
+ const struct spng_ihdr *ihdr = &ctx->ihdr;
+ int ret, pass = ctx->row_info.pass;
+ unsigned char *outptr = out;
+
+ if(!ihdr->interlace_method || pass == 6) return spng_decode_scanline(ctx, out, len);
+
+ ret = spng_decode_scanline(ctx, ctx->row, ctx->image_width);
+ if(ret && ret != SPNG_EOI) return ret;
+
+ uint32_t k;
+ unsigned pixel_size = 4; /* RGBA8 */
+ if(ctx->fmt == SPNG_FMT_RGBA16) pixel_size = 8;
+ else if(ctx->fmt == SPNG_FMT_RGB8) pixel_size = 3;
+ else if(ctx->fmt == SPNG_FMT_G8) pixel_size = 1;
+ else if(ctx->fmt == SPNG_FMT_GA8) pixel_size = 2;
+ else if(ctx->fmt & (SPNG_FMT_PNG | SPNG_FMT_RAW))
+ {
+ if(ihdr->bit_depth < 8)
+ {
+ struct spng__iter iter = spng__iter_init(ihdr->bit_depth, ctx->row);
+ const uint8_t samples_per_byte = 8 / ihdr->bit_depth;
+ uint8_t sample;
+
+ for(k=0; k < ctx->subimage[pass].width; k++)
+ {
+ sample = get_sample(&iter);
+
+ size_t ioffset = adam7_x_start[pass] + k * adam7_x_delta[pass];
+
+ sample = sample << (iter.initial_shift - ioffset * ihdr->bit_depth % 8);
+
+ ioffset /= samples_per_byte;
+
+ outptr[ioffset] |= sample;
+ }
+
+ return 0;
+ }
+ else pixel_size = ctx->bytes_per_pixel;
+ }
+
+ for(k=0; k < ctx->subimage[pass].width; k++)
+ {
+ size_t ioffset = (adam7_x_start[pass] + (size_t) k * adam7_x_delta[pass]) * pixel_size;
+
+ memcpy(outptr + ioffset, ctx->row + k * pixel_size, pixel_size);
+ }
+
+ return 0;
+}
+
+int spng_decode_chunks(spng_ctx *ctx)
+{
+ if(ctx == NULL) return 1;
+ if(ctx->encode_only) return SPNG_ECTXTYPE;
+ if(ctx->state < SPNG_STATE_INPUT) return SPNG_ENOSRC;
+ if(ctx->state == SPNG_STATE_IEND) return 0;
+
+ return read_chunks(ctx, 0);
+}
+
+int spng_decode_image(spng_ctx *ctx, void *out, size_t len, int fmt, int flags)
+{
+ if(ctx == NULL) return 1;
+ if(ctx->encode_only) return SPNG_ECTXTYPE;
+ if(ctx->state >= SPNG_STATE_EOI) return SPNG_EOI;
+
+ const struct spng_ihdr *ihdr = &ctx->ihdr;
+
+ int ret = read_chunks(ctx, 0);
+ if(ret) return decode_err(ctx, ret);
+
+ ret = check_decode_fmt(ihdr, fmt);
+ if(ret) return ret;
+
+ ret = calculate_image_width(ihdr, fmt, &ctx->image_width);
+ if(ret) return decode_err(ctx, ret);
+
+ if(ctx->image_width > SIZE_MAX / ihdr->height) ctx->image_size = 0; /* overflow */
+ else ctx->image_size = ctx->image_width * ihdr->height;
+
+ if( !(flags & SPNG_DECODE_PROGRESSIVE) )
+ {
+ if(out == NULL) return 1;
+ if(!ctx->image_size) return SPNG_EOVERFLOW;
+ if(len < ctx->image_size) return SPNG_EBUFSIZ;
+ }
+
+ uint32_t bytes_read = 0;
+
+ ret = read_idat_bytes(ctx, &bytes_read);
+ if(ret) return decode_err(ctx, ret);
+
+ if(bytes_read > 1)
+ {
+ int valid = read_u16(ctx->data) % 31 ? 0 : 1;
+
+ unsigned flg = ctx->data[1];
+ unsigned flevel = flg >> 6;
+ int compression_level = Z_DEFAULT_COMPRESSION;
+
+ if(flevel == 0) compression_level = 0; /* fastest */
+ else if(flevel == 1) compression_level = 1; /* fast */
+ else if(flevel == 2) compression_level = 6; /* default */
+ else if(flevel == 3) compression_level = 9; /* slowest, max compression */
+
+ if(valid) ctx->image_options.compression_level = compression_level;
+ }
+
+ ret = spng__inflate_init(ctx, ctx->image_options.window_bits);
+ if(ret) return decode_err(ctx, ret);
+
+ ctx->zstream.avail_in = bytes_read;
+ ctx->zstream.next_in = ctx->data;
+
+ size_t scanline_buf_size = ctx->subimage[ctx->widest_pass].scanline_width;
+
+ scanline_buf_size += 32;
+
+ if(scanline_buf_size < 32) return SPNG_EOVERFLOW;
+
+ ctx->scanline_buf = spng__malloc(ctx, scanline_buf_size);
+ ctx->prev_scanline_buf = spng__malloc(ctx, scanline_buf_size);
+
+ ctx->scanline = ctx->scanline_buf;
+ ctx->prev_scanline = ctx->prev_scanline_buf;
+
+ struct decode_flags f = {0};
+
+ ctx->fmt = fmt;
+
+ if(ihdr->color_type == SPNG_COLOR_TYPE_INDEXED) f.indexed = 1;
+
+ unsigned processing_depth = ihdr->bit_depth;
+
+ if(f.indexed) processing_depth = 8;
+
+ if(ihdr->interlace_method)
+ {
+ f.interlaced = 1;
+ ctx->row_buf = spng__malloc(ctx, ctx->image_width);
+ ctx->row = ctx->row_buf;
+
+ if(ctx->row == NULL) return decode_err(ctx, SPNG_EMEM);
+ }
+
+ if(ctx->scanline == NULL || ctx->prev_scanline == NULL)
+ {
+ return decode_err(ctx, SPNG_EMEM);
+ }
+
+ f.do_scaling = 1;
+ if(f.indexed) f.do_scaling = 0;
+
+ unsigned depth_target = 8; /* FMT_RGBA8, G8 */
+ if(fmt == SPNG_FMT_RGBA16) depth_target = 16;
+
+ if(flags & SPNG_DECODE_TRNS && ctx->stored.trns) f.apply_trns = 1;
+ else flags &= ~SPNG_DECODE_TRNS;
+
+ if(ihdr->color_type == SPNG_COLOR_TYPE_GRAYSCALE_ALPHA ||
+ ihdr->color_type == SPNG_COLOR_TYPE_TRUECOLOR_ALPHA) flags &= ~SPNG_DECODE_TRNS;
+
+ if(flags & SPNG_DECODE_GAMMA && ctx->stored.gama) f.apply_gamma = 1;
+ else flags &= ~SPNG_DECODE_GAMMA;
+
+ if(flags & SPNG_DECODE_USE_SBIT && ctx->stored.sbit) f.use_sbit = 1;
+ else flags &= ~SPNG_DECODE_USE_SBIT;
+
+ if(fmt & (SPNG_FMT_RGBA8 | SPNG_FMT_RGBA16))
+ {
+ if(ihdr->color_type == SPNG_COLOR_TYPE_TRUECOLOR_ALPHA &&
+ ihdr->bit_depth == depth_target) f.same_layout = 1;
+ }
+ else if(fmt == SPNG_FMT_RGB8)
+ {
+ if(ihdr->color_type == SPNG_COLOR_TYPE_TRUECOLOR &&
+ ihdr->bit_depth == depth_target) f.same_layout = 1;
+
+ f.apply_trns = 0; /* not applicable */
+ }
+ else if(fmt & (SPNG_FMT_PNG | SPNG_FMT_RAW))
+ {
+ f.same_layout = 1;
+ f.do_scaling = 0;
+ f.apply_gamma = 0; /* for now */
+ f.apply_trns = 0;
+ }
+ else if(fmt == SPNG_FMT_G8 && ihdr->color_type == SPNG_COLOR_TYPE_GRAYSCALE && ihdr->bit_depth <= 8)
+ {
+ if(ihdr->bit_depth == depth_target) f.same_layout = 1;
+ else if(ihdr->bit_depth < 8) f.unpack = 1;
+
+ f.apply_trns = 0;
+ }
+ else if(fmt == SPNG_FMT_GA8 && ihdr->color_type == SPNG_COLOR_TYPE_GRAYSCALE && ihdr->bit_depth <= 8)
+ {
+ if(ihdr->color_type == SPNG_COLOR_TYPE_GRAYSCALE_ALPHA &&
+ ihdr->bit_depth == depth_target) f.same_layout = 1;
+ else if(ihdr->bit_depth <= 8) f.unpack = 1;
+ }
+ else if(fmt == SPNG_FMT_GA16 && ihdr->color_type == SPNG_COLOR_TYPE_GRAYSCALE && ihdr->bit_depth == 16)
+ {
+ if(ihdr->color_type == SPNG_COLOR_TYPE_GRAYSCALE_ALPHA &&
+ ihdr->bit_depth == depth_target) f.same_layout = 1;
+ else if(ihdr->bit_depth == 16) f.unpack = 1;
+ }
+
+ /*if(f.same_layout && !flags && !f.interlaced) f.zerocopy = 1;*/
+
+ uint16_t *gamma_lut = NULL;
+
+ if(f.apply_gamma)
+ {
+ float file_gamma = (float)ctx->gama / 100000.0f;
+ float max;
+
+ unsigned lut_entries;
+
+ if(fmt & (SPNG_FMT_RGBA8 | SPNG_FMT_RGB8))
+ {
+ lut_entries = 256;
+ max = 255.0f;
+
+ gamma_lut = ctx->gamma_lut8;
+ ctx->gamma_lut = ctx->gamma_lut8;
+ }
+ else /* SPNG_FMT_RGBA16 */
+ {
+ lut_entries = 65536;
+ max = 65535.0f;
+
+ ctx->gamma_lut16 = spng__malloc(ctx, lut_entries * sizeof(uint16_t));
+ if(ctx->gamma_lut16 == NULL) return decode_err(ctx, SPNG_EMEM);
+
+ gamma_lut = ctx->gamma_lut16;
+ ctx->gamma_lut = ctx->gamma_lut16;
+ }
+
+ float screen_gamma = 2.2f;
+ float exponent = file_gamma * screen_gamma;
+
+ if(FP_ZERO == fpclassify(exponent)) return decode_err(ctx, SPNG_EGAMA);
+
+ exponent = 1.0f / exponent;
+
+ unsigned i;
+ for(i=0; i < lut_entries; i++)
+ {
+ float c = pow((float)i / max, exponent) * max;
+ if(c > max) c = max;
+
+ gamma_lut[i] = (uint16_t)c;
+ }
+ }
+
+ struct spng_sbit *sb = &ctx->decode_sb;
+
+ sb->red_bits = processing_depth;
+ sb->green_bits = processing_depth;
+ sb->blue_bits = processing_depth;
+ sb->alpha_bits = processing_depth;
+ sb->grayscale_bits = processing_depth;
+
+ if(f.use_sbit)
+ {
+ if(ihdr->color_type == 0)
+ {
+ sb->grayscale_bits = ctx->sbit.grayscale_bits;
+ sb->alpha_bits = ihdr->bit_depth;
+ }
+ else if(ihdr->color_type == 2 || ihdr->color_type == 3)
+ {
+ sb->red_bits = ctx->sbit.red_bits;
+ sb->green_bits = ctx->sbit.green_bits;
+ sb->blue_bits = ctx->sbit.blue_bits;
+ sb->alpha_bits = ihdr->bit_depth;
+ }
+ else if(ihdr->color_type == 4)
+ {
+ sb->grayscale_bits = ctx->sbit.grayscale_bits;
+ sb->alpha_bits = ctx->sbit.alpha_bits;
+ }
+ else /* == 6 */
+ {
+ sb->red_bits = ctx->sbit.red_bits;
+ sb->green_bits = ctx->sbit.green_bits;
+ sb->blue_bits = ctx->sbit.blue_bits;
+ sb->alpha_bits = ctx->sbit.alpha_bits;
+ }
+ }
+
+ if(ihdr->bit_depth == 16 && fmt & (SPNG_FMT_RGBA8 | SPNG_FMT_RGB8))
+ {/* samples are scaled down by 8 bits in the decode loop */
+ sb->red_bits -= 8;
+ sb->green_bits -= 8;
+ sb->blue_bits -= 8;
+ sb->alpha_bits -= 8;
+ sb->grayscale_bits -= 8;
+
+ processing_depth = 8;
+ }
+
+ /* Prevent infinite loops in sample_to_target() */
+ if(!depth_target || depth_target > 16 ||
+ !processing_depth || processing_depth > 16 ||
+ !sb->grayscale_bits || sb->grayscale_bits > processing_depth ||
+ !sb->alpha_bits || sb->alpha_bits > processing_depth ||
+ !sb->red_bits || sb->red_bits > processing_depth ||
+ !sb->green_bits || sb->green_bits > processing_depth ||
+ !sb->blue_bits || sb->blue_bits > processing_depth)
+ {
+ return decode_err(ctx, SPNG_ESBIT);
+ }
+
+ if(sb->red_bits == sb->green_bits &&
+ sb->green_bits == sb->blue_bits &&
+ sb->blue_bits == sb->alpha_bits &&
+ sb->alpha_bits == processing_depth &&
+ processing_depth == depth_target) f.do_scaling = 0;
+
+ struct spng_plte_entry *plte = ctx->decode_plte.rgba;
+
+ /* Pre-process palette entries */
+ if(f.indexed)
+ {
+ uint8_t red, green, blue, alpha;
+
+ uint32_t i;
+ for(i=0; i < 256; i++)
+ {
+ if(f.apply_trns && i < ctx->trns.n_type3_entries)
+ ctx->plte.entries[i].alpha = ctx->trns.type3_alpha[i];
+ else
+ ctx->plte.entries[i].alpha = 255;
+
+ red = sample_to_target(ctx->plte.entries[i].red, 8, sb->red_bits, 8);
+ green = sample_to_target(ctx->plte.entries[i].green, 8, sb->green_bits, 8);
+ blue = sample_to_target(ctx->plte.entries[i].blue, 8, sb->blue_bits, 8);
+ alpha = sample_to_target(ctx->plte.entries[i].alpha, 8, sb->alpha_bits, 8);
+
+#if defined(SPNG_ARM)
+ if(fmt == SPNG_FMT_RGB8 && ihdr->bit_depth == 8)
+ {/* Working with 3 bytes at a time is more of an ARM thing */
+ ctx->decode_plte.rgb[i * 3 + 0] = red;
+ ctx->decode_plte.rgb[i * 3 + 1] = green;
+ ctx->decode_plte.rgb[i * 3 + 2] = blue;
+ continue;
+ }
+#endif
+ plte[i].red = red;
+ plte[i].green = green;
+ plte[i].blue = blue;
+ plte[i].alpha = alpha;
+ }
+
+ f.apply_trns = 0;
+ }
+
+ unsigned char *trns_px = ctx->trns_px;
+
+ if(f.apply_trns)
+ {
+ uint16_t mask = ~0;
+ if(ctx->ihdr.bit_depth < 16) mask = (1 << ctx->ihdr.bit_depth) - 1;
+
+ if(fmt & (SPNG_FMT_RGBA8 | SPNG_FMT_RGBA16))
+ {
+ if(ihdr->color_type == SPNG_COLOR_TYPE_TRUECOLOR)
+ {
+ if(ihdr->bit_depth == 16)
+ {
+ memcpy(trns_px, &ctx->trns.red, 2);
+ memcpy(trns_px + 2, &ctx->trns.green, 2);
+ memcpy(trns_px + 4, &ctx->trns.blue, 2);
+ }
+ else
+ {
+ trns_px[0] = ctx->trns.red & mask;
+ trns_px[1] = ctx->trns.green & mask;
+ trns_px[2] = ctx->trns.blue & mask;
+ }
+ }
+ }
+ else if(ihdr->color_type == SPNG_COLOR_TYPE_GRAYSCALE) // fmt == SPNG_FMT_GA8 &&
+ {
+ if(ihdr->bit_depth == 16)
+ {
+ memcpy(trns_px, &ctx->trns.gray, 2);
+ }
+ else
+ {
+ trns_px[0] = ctx->trns.gray & mask;
+ }
+ }
+ }
+
+ ctx->decode_flags = f;
+
+ ctx->state = SPNG_STATE_DECODE_INIT;
+
+ struct spng_row_info *ri = &ctx->row_info;
+ struct spng_subimage *sub = ctx->subimage;
+
+ while(!sub[ri->pass].width || !sub[ri->pass].height) ri->pass++;
+
+ if(f.interlaced) ri->row_num = adam7_y_start[ri->pass];
+
+ unsigned pixel_size = 4; /* SPNG_FMT_RGBA8 */
+
+ if(fmt == SPNG_FMT_RGBA16) pixel_size = 8;
+ else if(fmt == SPNG_FMT_RGB8) pixel_size = 3;
+ else if(fmt == SPNG_FMT_G8) pixel_size = 1;
+ else if(fmt == SPNG_FMT_GA8) pixel_size = 2;
+
+ int i;
+ for(i=ri->pass; i <= ctx->last_pass; i++)
+ {
+ if(!sub[i].scanline_width) continue;
+
+ if(fmt & (SPNG_FMT_PNG | SPNG_FMT_RAW)) sub[i].out_width = sub[i].scanline_width - 1;
+ else sub[i].out_width = (size_t)sub[i].width * pixel_size;
+
+ if(sub[i].out_width > UINT32_MAX) return decode_err(ctx, SPNG_EOVERFLOW);
+ }
+
+ /* Read the first filter byte, offsetting all reads by 1 byte.
+ The scanlines will be aligned with the start of the array with
+ the next scanline's filter byte at the end,
+ the last scanline will end up being 1 byte "shorter". */
+ ret = read_scanline_bytes(ctx, &ri->filter, 1);
+ if(ret) return decode_err(ctx, ret);
+
+ if(ri->filter > 4) return decode_err(ctx, SPNG_EFILTER);
+
+ if(flags & SPNG_DECODE_PROGRESSIVE)
+ {
+ return 0;
+ }
+
+ do
+ {
+ size_t ioffset = ri->row_num * ctx->image_width;
+
+ ret = spng_decode_row(ctx, (unsigned char*)out + ioffset, ctx->image_width);
+ }while(!ret);
+
+ if(ret != SPNG_EOI) return decode_err(ctx, ret);
+
+ return 0;
+}
+
+int spng_get_row_info(spng_ctx *ctx, struct spng_row_info *row_info)
+{
+ if(ctx == NULL || row_info == NULL || ctx->state < SPNG_STATE_DECODE_INIT) return 1;
+
+ if(ctx->state >= SPNG_STATE_EOI) return SPNG_EOI;
+
+ *row_info = ctx->row_info;
+
+ return 0;
+}
+
+static int write_chunks_before_idat(spng_ctx *ctx)
+{
+ if(ctx == NULL) return SPNG_EINTERNAL;
+ if(!ctx->encode_only) return SPNG_EINTERNAL;
+ if(!ctx->stored.ihdr) return SPNG_EINTERNAL;
+
+ int ret;
+ uint32_t i;
+ size_t length;
+ const struct spng_ihdr *ihdr = &ctx->ihdr;
+ unsigned char *data = ctx->decode_plte.raw;
+
+ ret = write_data(ctx, spng_signature, 8);
+ if(ret) return ret;
+
+ write_u32(data, ihdr->width);
+ write_u32(data + 4, ihdr->height);
+ data[8] = ihdr->bit_depth;
+ data[9] = ihdr->color_type;
+ data[10] = ihdr->compression_method;
+ data[11] = ihdr->filter_method;
+ data[12] = ihdr->interlace_method;
+
+ ret = write_chunk(ctx, type_ihdr, data, 13);
+ if(ret) return ret;
+
+ if(ctx->stored.chrm)
+ {
+ write_u32(data, ctx->chrm_int.white_point_x);
+ write_u32(data + 4, ctx->chrm_int.white_point_y);
+ write_u32(data + 8, ctx->chrm_int.red_x);
+ write_u32(data + 12, ctx->chrm_int.red_y);
+ write_u32(data + 16, ctx->chrm_int.green_x);
+ write_u32(data + 20, ctx->chrm_int.green_y);
+ write_u32(data + 24, ctx->chrm_int.blue_x);
+ write_u32(data + 28, ctx->chrm_int.blue_y);
+
+ ret = write_chunk(ctx, type_chrm, data, 32);
+ if(ret) return ret;
+ }
+
+ if(ctx->stored.gama)
+ {
+ write_u32(data, ctx->gama);
+
+ ret = write_chunk(ctx, type_gama, data, 4);
+ if(ret) return ret;
+ }
+
+ if(ctx->stored.iccp)
+ {
+ uLongf dest_len = compressBound((uLong)ctx->iccp.profile_len);
+
+ Bytef *buf = spng__malloc(ctx, dest_len);
+ if(buf == NULL) return SPNG_EMEM;
+
+ ret = compress2(buf, &dest_len, (void*)ctx->iccp.profile, (uLong)ctx->iccp.profile_len, Z_DEFAULT_COMPRESSION);
+
+ if(ret != Z_OK)
+ {
+ spng__free(ctx, buf);
+ return SPNG_EZLIB;
+ }
+
+ size_t name_len = strlen(ctx->iccp.profile_name);
+
+ length = name_len + 2;
+ length += dest_len;
+
+ if(dest_len > length) return SPNG_EOVERFLOW;
+
+ unsigned char *cdata = NULL;
+
+ ret = write_header(ctx, type_iccp, length, &cdata);
+
+ if(ret)
+ {
+ spng__free(ctx, buf);
+ return ret;
+ }
+
+ memcpy(cdata, ctx->iccp.profile_name, name_len + 1);
+ cdata[name_len + 1] = 0; /* compression method */
+ memcpy(cdata + name_len + 2, buf, dest_len);
+
+ spng__free(ctx, buf);
+
+ ret = finish_chunk(ctx);
+ if(ret) return ret;
+ }
+
+ if(ctx->stored.sbit)
+ {
+ switch(ctx->ihdr.color_type)
+ {
+ case SPNG_COLOR_TYPE_GRAYSCALE:
+ {
+ length = 1;
+
+ data[0] = ctx->sbit.grayscale_bits;
+
+ break;
+ }
+ case SPNG_COLOR_TYPE_TRUECOLOR:
+ case SPNG_COLOR_TYPE_INDEXED:
+ {
+ length = 3;
+
+ data[0] = ctx->sbit.red_bits;
+ data[1] = ctx->sbit.green_bits;
+ data[2] = ctx->sbit.blue_bits;
+
+ break;
+ }
+ case SPNG_COLOR_TYPE_GRAYSCALE_ALPHA:
+ {
+ length = 2;
+
+ data[0] = ctx->sbit.grayscale_bits;
+ data[1] = ctx->sbit.alpha_bits;
+
+ break;
+ }
+ case SPNG_COLOR_TYPE_TRUECOLOR_ALPHA:
+ {
+ length = 4;
+
+ data[0] = ctx->sbit.red_bits;
+ data[1] = ctx->sbit.green_bits;
+ data[2] = ctx->sbit.blue_bits;
+ data[3] = ctx->sbit.alpha_bits;
+
+ break;
+ }
+ default: return SPNG_EINTERNAL;
+ }
+
+ ret = write_chunk(ctx, type_sbit, data, length);
+ if(ret) return ret;
+ }
+
+ if(ctx->stored.srgb)
+ {
+ ret = write_chunk(ctx, type_srgb, &ctx->srgb_rendering_intent, 1);
+ if(ret) return ret;
+ }
+
+ ret = write_unknown_chunks(ctx, SPNG_AFTER_IHDR);
+ if(ret) return ret;
+
+ if(ctx->stored.plte)
+ {
+ for(i=0; i < ctx->plte.n_entries; i++)
+ {
+ data[i * 3 + 0] = ctx->plte.entries[i].red;
+ data[i * 3 + 1] = ctx->plte.entries[i].green;
+ data[i * 3 + 2] = ctx->plte.entries[i].blue;
+ }
+
+ ret = write_chunk(ctx, type_plte, data, ctx->plte.n_entries * 3);
+ if(ret) return ret;
+ }
+
+ if(ctx->stored.bkgd)
+ {
+ switch(ctx->ihdr.color_type)
+ {
+ case SPNG_COLOR_TYPE_GRAYSCALE:
+ case SPNG_COLOR_TYPE_GRAYSCALE_ALPHA:
+ {
+ length = 2;
+
+ write_u16(data, ctx->bkgd.gray);
+
+ break;
+ }
+ case SPNG_COLOR_TYPE_TRUECOLOR:
+ case SPNG_COLOR_TYPE_TRUECOLOR_ALPHA:
+ {
+ length = 6;
+
+ write_u16(data, ctx->bkgd.red);
+ write_u16(data + 2, ctx->bkgd.green);
+ write_u16(data + 4, ctx->bkgd.blue);
+
+ break;
+ }
+ case SPNG_COLOR_TYPE_INDEXED:
+ {
+ length = 1;
+
+ data[0] = ctx->bkgd.plte_index;
+
+ break;
+ }
+ default: return SPNG_EINTERNAL;
+ }
+
+ ret = write_chunk(ctx, type_bkgd, data, length);
+ if(ret) return ret;
+ }
+
+ if(ctx->stored.hist)
+ {
+ length = ctx->plte.n_entries * 2;
+
+ for(i=0; i < ctx->plte.n_entries; i++)
+ {
+ write_u16(data + i * 2, ctx->hist.frequency[i]);
+ }
+
+ ret = write_chunk(ctx, type_hist, data, length);
+ if(ret) return ret;
+ }
+
+ if(ctx->stored.trns)
+ {
+ if(ctx->ihdr.color_type == SPNG_COLOR_TYPE_GRAYSCALE)
+ {
+ write_u16(data, ctx->trns.gray);
+
+ ret = write_chunk(ctx, type_trns, data, 2);
+ }
+ else if(ctx->ihdr.color_type == SPNG_COLOR_TYPE_TRUECOLOR)
+ {
+ write_u16(data, ctx->trns.red);
+ write_u16(data + 2, ctx->trns.green);
+ write_u16(data + 4, ctx->trns.blue);
+
+ ret = write_chunk(ctx, type_trns, data, 6);
+ }
+ else if(ctx->ihdr.color_type == SPNG_COLOR_TYPE_INDEXED)
+ {
+ ret = write_chunk(ctx, type_trns, ctx->trns.type3_alpha, ctx->trns.n_type3_entries);
+ }
+
+ if(ret) return ret;
+ }
+
+ if(ctx->stored.phys)
+ {
+ write_u32(data, ctx->phys.ppu_x);
+ write_u32(data + 4, ctx->phys.ppu_y);
+ data[8] = ctx->phys.unit_specifier;
+
+ ret = write_chunk(ctx, type_phys, data, 9);
+ if(ret) return ret;
+ }
+
+ if(ctx->stored.splt)
+ {
+ const struct spng_splt *splt;
+ unsigned char *cdata = NULL;
+
+ uint32_t k;
+ for(i=0; i < ctx->n_splt; i++)
+ {
+ splt = &ctx->splt_list[i];
+
+ size_t name_len = strlen(splt->name);
+ length = name_len + 1;
+
+ if(splt->sample_depth == 8) length += splt->n_entries * 6 + 1;
+ else if(splt->sample_depth == 16) length += splt->n_entries * 10 + 1;
+
+ ret = write_header(ctx, type_splt, length, &cdata);
+ if(ret) return ret;
+
+ memcpy(cdata, splt->name, name_len + 1);
+ cdata += name_len + 2;
+ cdata[-1] = splt->sample_depth;
+
+ if(splt->sample_depth == 8)
+ {
+ for(k=0; k < splt->n_entries; k++)
+ {
+ cdata[k * 6 + 0] = splt->entries[k].red;
+ cdata[k * 6 + 1] = splt->entries[k].green;
+ cdata[k * 6 + 2] = splt->entries[k].blue;
+ cdata[k * 6 + 3] = splt->entries[k].alpha;
+ write_u16(cdata + k * 6 + 4, splt->entries[k].frequency);
+ }
+ }
+ else if(splt->sample_depth == 16)
+ {
+ for(k=0; k < splt->n_entries; k++)
+ {
+ write_u16(cdata + k * 10 + 0, splt->entries[k].red);
+ write_u16(cdata + k * 10 + 2, splt->entries[k].green);
+ write_u16(cdata + k * 10 + 4, splt->entries[k].blue);
+ write_u16(cdata + k * 10 + 6, splt->entries[k].alpha);
+ write_u16(cdata + k * 10 + 8, splt->entries[k].frequency);
+ }
+ }
+
+ ret = finish_chunk(ctx);
+ if(ret) return ret;
+ }
+ }
+
+ if(ctx->stored.time)
+ {
+ write_u16(data, ctx->time.year);
+ data[2] = ctx->time.month;
+ data[3] = ctx->time.day;
+ data[4] = ctx->time.hour;
+ data[5] = ctx->time.minute;
+ data[6] = ctx->time.second;
+
+ ret = write_chunk(ctx, type_time, data, 7);
+ if(ret) return ret;
+ }
+
+ if(ctx->stored.text)
+ {
+ unsigned char *cdata = NULL;
+ const struct spng_text2 *text;
+ const uint8_t *text_type_array[4] = { 0, type_text, type_ztxt, type_itxt };
+
+ for(i=0; i < ctx->n_text; i++)
+ {
+ text = &ctx->text_list[i];
+
+ const uint8_t *text_chunk_type = text_type_array[text->type];
+ Bytef *compressed_text = NULL;
+ size_t keyword_len = 0;
+ size_t language_tag_len = 0;
+ size_t translated_keyword_len = 0;
+ size_t compressed_length = 0;
+ size_t text_length = 0;
+
+ keyword_len = strlen(text->keyword);
+ text_length = strlen(text->text);
+
+ length = keyword_len + 1;
+
+ if(text->type == SPNG_ZTXT)
+ {
+ length += 1; /* compression method */
+ }
+ else if(text->type == SPNG_ITXT)
+ {
+ if(!text->language_tag || !text->translated_keyword) return SPNG_EINTERNAL;
+
+ language_tag_len = strlen(text->language_tag);
+ translated_keyword_len = strlen(text->translated_keyword);
+
+ length += language_tag_len;
+ if(length < language_tag_len) return SPNG_EOVERFLOW;
+
+ length += translated_keyword_len;
+ if(length < translated_keyword_len) return SPNG_EOVERFLOW;
+
+ length += 4; /* compression flag + method + nul for the two strings */
+ if(length < 4) return SPNG_EOVERFLOW;
+ }
+
+ if(text->compression_flag)
+ {
+ ret = spng__deflate_init(ctx, &ctx->text_options);
+ if(ret) return ret;
+
+ z_stream *zstream = &ctx->zstream;
+ uLongf dest_len = deflateBound(zstream, (uLong)text_length);
+
+ compressed_text = spng__malloc(ctx, dest_len);
+
+ if(compressed_text == NULL) return SPNG_EMEM;
+
+ zstream->next_in = (void*)text->text;
+ zstream->avail_in = (uInt)text_length;
+
+ zstream->next_out = compressed_text;
+ zstream->avail_out = dest_len;
+
+ ret = deflate(zstream, Z_FINISH);
+
+ if(ret != Z_STREAM_END)
+ {
+ spng__free(ctx, compressed_text);
+ return SPNG_EZLIB;
+ }
+
+ compressed_length = zstream->total_out;
+
+ length += compressed_length;
+ if(length < compressed_length) return SPNG_EOVERFLOW;
+ }
+ else
+ {
+ text_length = strlen(text->text);
+
+ length += text_length;
+ if(length < text_length) return SPNG_EOVERFLOW;
+ }
+
+ ret = write_header(ctx, text_chunk_type, length, &cdata);
+ if(ret)
+ {
+ spng__free(ctx, compressed_text);
+ return ret;
+ }
+
+ memcpy(cdata, text->keyword, keyword_len + 1);
+ cdata += keyword_len + 1;
+
+ if(text->type == SPNG_ITXT)
+ {
+ cdata[0] = text->compression_flag;
+ cdata[1] = 0; /* compression method */
+ cdata += 2;
+
+ memcpy(cdata, text->language_tag, language_tag_len + 1);
+ cdata += language_tag_len + 1;
+
+ memcpy(cdata, text->translated_keyword, translated_keyword_len + 1);
+ cdata += translated_keyword_len + 1;
+ }
+ else if(text->type == SPNG_ZTXT)
+ {
+ cdata[0] = 0; /* compression method */
+ cdata++;
+ }
+
+ if(text->compression_flag) memcpy(cdata, compressed_text, compressed_length);
+ else memcpy(cdata, text->text, text_length);
+
+ spng__free(ctx, compressed_text);
+
+ ret = finish_chunk(ctx);
+ if(ret) return ret;
+ }
+ }
+
+ if(ctx->stored.offs)
+ {
+ write_s32(data, ctx->offs.x);
+ write_s32(data + 4, ctx->offs.y);
+ data[8] = ctx->offs.unit_specifier;
+
+ ret = write_chunk(ctx, type_offs, data, 9);
+ if(ret) return ret;
+ }
+
+ if(ctx->stored.exif)
+ {
+ ret = write_chunk(ctx, type_exif, ctx->exif.data, ctx->exif.length);
+ if(ret) return ret;
+ }
+
+ ret = write_unknown_chunks(ctx, SPNG_AFTER_PLTE);
+ if(ret) return ret;
+
+ return 0;
+}
+
+static int write_chunks_after_idat(spng_ctx *ctx)
+{
+ if(ctx == NULL) return SPNG_EINTERNAL;
+
+ int ret = write_unknown_chunks(ctx, SPNG_AFTER_IDAT);
+ if(ret) return ret;
+
+ return write_iend(ctx);
+}
+
+/* Compress and write scanline to IDAT stream */
+static int write_idat_bytes(spng_ctx *ctx, const void *scanline, size_t len, int flush)
+{
+ if(ctx == NULL || scanline == NULL) return SPNG_EINTERNAL;
+ if(len > UINT_MAX) return SPNG_EINTERNAL;
+
+ int ret = 0;
+ unsigned char *data = NULL;
+ z_stream *zstream = &ctx->zstream;
+ uint32_t idat_length = SPNG_WRITE_SIZE;
+
+ zstream->next_in = scanline;
+ zstream->avail_in = (uInt)len;
+
+ do
+ {
+ ret = deflate(zstream, flush);
+
+ if(zstream->avail_out == 0)
+ {
+ ret = finish_chunk(ctx);
+ if(ret) return encode_err(ctx, ret);
+
+ ret = write_header(ctx, type_idat, idat_length, &data);
+ if(ret) return encode_err(ctx, ret);
+
+ zstream->next_out = data;
+ zstream->avail_out = idat_length;
+ }
+
+ }while(zstream->avail_in);
+
+ if(ret != Z_OK) return SPNG_EZLIB;
+
+ return 0;
+}
+
+static int finish_idat(spng_ctx *ctx)
+{
+ int ret = 0;
+ unsigned char *data = NULL;
+ z_stream *zstream = &ctx->zstream;
+ uint32_t idat_length = SPNG_WRITE_SIZE;
+
+ while(ret != Z_STREAM_END)
+ {
+ ret = deflate(zstream, Z_FINISH);
+
+ if(ret)
+ {
+ if(ret == Z_STREAM_END) break;
+
+ if(ret != Z_BUF_ERROR) return SPNG_EZLIB;
+ }
+
+ if(zstream->avail_out == 0)
+ {
+ ret = finish_chunk(ctx);
+ if(ret) return encode_err(ctx, ret);
+
+ ret = write_header(ctx, type_idat, idat_length, &data);
+ if(ret) return encode_err(ctx, ret);
+
+ zstream->next_out = data;
+ zstream->avail_out = idat_length;
+ }
+ }
+
+ uint32_t trimmed_length = idat_length - zstream->avail_out;
+
+ ret = trim_chunk(ctx, trimmed_length);
+ if(ret) return ret;
+
+ return finish_chunk(ctx);
+}
+
+static int encode_scanline(spng_ctx *ctx, const void *scanline, size_t len)
+{
+ if(ctx == NULL || scanline == NULL) return SPNG_EINTERNAL;
+
+ int ret, pass = ctx->row_info.pass;
+ uint8_t filter = 0;
+ struct spng_row_info *ri = &ctx->row_info;
+ const struct spng_subimage *sub = ctx->subimage;
+ struct encode_flags f = ctx->encode_flags;
+ unsigned char *filtered_scanline = ctx->filtered_scanline;
+ size_t scanline_width = sub[pass].scanline_width;
+
+ if(len < scanline_width - 1) return SPNG_EINTERNAL;
+
+ /* encode_row() interlaces directly to ctx->scanline */
+ if(scanline != ctx->scanline) memcpy(ctx->scanline, scanline, scanline_width - 1);
+
+ if(f.to_bigendian) u16_row_to_bigendian(ctx->scanline, scanline_width - 1);
+ const int requires_previous = f.filter_choice & (SPNG_FILTER_CHOICE_UP | SPNG_FILTER_CHOICE_AVG | SPNG_FILTER_CHOICE_PAETH);
+
+ /* XXX: exclude 'requires_previous' filters by default for first scanline? */
+ if(!ri->scanline_idx && requires_previous)
+ {
+ /* prev_scanline is all zeros for the first scanline */
+ memset(ctx->prev_scanline, 0, scanline_width);
+ }
+
+ filter = get_best_filter(ctx->prev_scanline, ctx->scanline, scanline_width, ctx->bytes_per_pixel, f.filter_choice);
+
+ if(!filter) filtered_scanline = ctx->scanline;
+
+ filtered_scanline[-1] = filter;
+
+ if(filter)
+ {
+ ret = filter_scanline(filtered_scanline, ctx->prev_scanline, ctx->scanline, scanline_width, ctx->bytes_per_pixel, filter);
+ if(ret) return encode_err(ctx, ret);
+ }
+
+ ret = write_idat_bytes(ctx, filtered_scanline - 1, scanline_width, Z_NO_FLUSH);
+ if(ret) return encode_err(ctx, ret);
+
+ /* The previous scanline is always unfiltered */
+ void *t = ctx->prev_scanline;
+ ctx->prev_scanline = ctx->scanline;
+ ctx->scanline = t;
+
+ ret = update_row_info(ctx);
+
+ if(ret == SPNG_EOI)
+ {
+ int error = finish_idat(ctx);
+ if(error) encode_err(ctx, error);
+
+ if(f.finalize)
+ {
+ error = spng_encode_chunks(ctx);
+ if(error) return encode_err(ctx, error);
+ }
+ }
+
+ return ret;
+}
+
+static int encode_row(spng_ctx *ctx, const void *row, size_t len)
+{
+ if(ctx == NULL || row == NULL) return SPNG_EINTERNAL;
+
+ const int pass = ctx->row_info.pass;
+
+ if(!ctx->ihdr.interlace_method || pass == 6) return encode_scanline(ctx, row, len);
+
+ uint32_t k;
+ const unsigned pixel_size = ctx->pixel_size;
+ const unsigned bit_depth = ctx->ihdr.bit_depth;
+
+ if(bit_depth < 8)
+ {
+ const unsigned samples_per_byte = 8 / bit_depth;
+ const uint8_t mask = (1 << bit_depth) - 1;
+ const unsigned initial_shift = 8 - bit_depth;
+ unsigned shift_amount = initial_shift;
+
+ unsigned char *scanline = ctx->scanline;
+ const unsigned char *row_uc = row;
+ uint8_t sample;
+
+ memset(scanline, 0, ctx->subimage[pass].scanline_width);
+
+ for(k=0; k < ctx->subimage[pass].width; k++)
+ {
+ size_t ioffset = adam7_x_start[pass] + k * adam7_x_delta[pass];
+
+ sample = row_uc[ioffset / samples_per_byte];
+
+ sample = sample >> (initial_shift - ioffset * bit_depth % 8);
+ sample = sample & mask;
+ sample = sample << shift_amount;
+
+ scanline[0] |= sample;
+
+ shift_amount -= bit_depth;
+
+ if(shift_amount > 7)
+ {
+ shift_amount = initial_shift;
+ scanline++;
+ }
+ }
+
+ return encode_scanline(ctx, ctx->scanline, len);
+ }
+
+ for(k=0; k < ctx->subimage[pass].width; k++)
+ {
+ size_t ioffset = (adam7_x_start[pass] + (size_t) k * adam7_x_delta[pass]) * pixel_size;
+
+ memcpy(ctx->scanline + k * pixel_size, (unsigned char*)row + ioffset, pixel_size);
+ }
+
+ return encode_scanline(ctx, ctx->scanline, len);
+}
+
+int spng_encode_scanline(spng_ctx *ctx, const void *scanline, size_t len)
+{
+ if(ctx == NULL || scanline == NULL) return SPNG_EINVAL;
+ if(ctx->state >= SPNG_STATE_EOI) return SPNG_EOI;
+ if(len < (ctx->subimage[ctx->row_info.pass].scanline_width -1) ) return SPNG_EBUFSIZ;
+
+ return encode_scanline(ctx, scanline, len);
+}
+
+int spng_encode_row(spng_ctx *ctx, const void *row, size_t len)
+{
+ if(ctx == NULL || row == NULL) return SPNG_EINVAL;
+ if(ctx->state >= SPNG_STATE_EOI) return SPNG_EOI;
+ if(len < ctx->image_width) return SPNG_EBUFSIZ;
+
+ return encode_row(ctx, row, len);
+}
+
+int spng_encode_chunks(spng_ctx *ctx)
+{
+ if(ctx == NULL) return 1;
+ if(!ctx->state) return SPNG_EBADSTATE;
+ if(ctx->state < SPNG_STATE_OUTPUT) return SPNG_ENODST;
+ if(!ctx->encode_only) return SPNG_ECTXTYPE;
+
+ int ret = 0;
+
+ if(ctx->state < SPNG_STATE_FIRST_IDAT)
+ {
+ if(!ctx->stored.ihdr) return SPNG_ENOIHDR;
+
+ ret = write_chunks_before_idat(ctx);
+ if(ret) return encode_err(ctx, ret);
+
+ ctx->state = SPNG_STATE_FIRST_IDAT;
+ }
+ else if(ctx->state == SPNG_STATE_FIRST_IDAT)
+ {
+ return 0;
+ }
+ else if(ctx->state == SPNG_STATE_EOI)
+ {
+ ret = write_chunks_after_idat(ctx);
+ if(ret) return encode_err(ctx, ret);
+
+ ctx->state = SPNG_STATE_IEND;
+ }
+ else return SPNG_EOPSTATE;
+
+ return 0;
+}
+
+int spng_encode_image(spng_ctx *ctx, const void *img, size_t len, int fmt, int flags)
+{
+ if(ctx == NULL) return 1;
+ if(!ctx->state) return SPNG_EBADSTATE;
+ if(!ctx->encode_only) return SPNG_ECTXTYPE;
+ if(!ctx->stored.ihdr) return SPNG_ENOIHDR;
+ if( !(fmt == SPNG_FMT_PNG || fmt == SPNG_FMT_RAW) ) return SPNG_EFMT;
+
+ int ret = 0;
+ const struct spng_ihdr *ihdr = &ctx->ihdr;
+ struct encode_flags *encode_flags = &ctx->encode_flags;
+
+ if(ihdr->color_type == SPNG_COLOR_TYPE_INDEXED && !ctx->stored.plte) return SPNG_ENOPLTE;
+
+ ret = calculate_image_width(ihdr, fmt, &ctx->image_width);
+ if(ret) return encode_err(ctx, ret);
+
+ if(ctx->image_width > SIZE_MAX / ihdr->height) ctx->image_size = 0; /* overflow */
+ else ctx->image_size = ctx->image_width * ihdr->height;
+
+ if( !(flags & SPNG_ENCODE_PROGRESSIVE) )
+ {
+ if(img == NULL) return 1;
+ if(!ctx->image_size) return SPNG_EOVERFLOW;
+ if(len != ctx->image_size) return SPNG_EBUFSIZ;
+ }
+
+ ret = spng_encode_chunks(ctx);
+ if(ret) return encode_err(ctx, ret);
+
+ ret = calculate_subimages(ctx);
+ if(ret) return encode_err(ctx, ret);
+
+ if(ihdr->bit_depth < 8) ctx->bytes_per_pixel = 1;
+ else ctx->bytes_per_pixel = num_channels(ihdr) * (ihdr->bit_depth / 8);
+
+ if(spng__optimize(SPNG_FILTER_CHOICE))
+ {
+ /* Filtering would make no difference */
+ if(!ctx->image_options.compression_level)
+ {
+ encode_flags->filter_choice = SPNG_DISABLE_FILTERING;
+ }
+
+ /* Palette indices and low bit-depth images do not benefit from filtering */
+ if(ihdr->color_type == SPNG_COLOR_TYPE_INDEXED || ihdr->bit_depth < 8)
+ {
+ encode_flags->filter_choice = SPNG_DISABLE_FILTERING;
+ }
+ }
+
+ /* This is technically the same as disabling filtering */
+ if(encode_flags->filter_choice == SPNG_FILTER_CHOICE_NONE)
+ {
+ encode_flags->filter_choice = SPNG_DISABLE_FILTERING;
+ }
+
+ if(!encode_flags->filter_choice && spng__optimize(SPNG_IMG_COMPRESSION_STRATEGY))
+ {
+ ctx->image_options.strategy = Z_DEFAULT_STRATEGY;
+ }
+
+ ret = spng__deflate_init(ctx, &ctx->image_options);
+ if(ret) return encode_err(ctx, ret);
+
+ size_t scanline_buf_size = ctx->subimage[ctx->widest_pass].scanline_width;
+
+ scanline_buf_size += 32;
+
+ if(scanline_buf_size < 32) return SPNG_EOVERFLOW;
+
+ ctx->scanline_buf = spng__malloc(ctx, scanline_buf_size);
+ ctx->prev_scanline_buf = spng__malloc(ctx, scanline_buf_size);
+
+ if(ctx->scanline_buf == NULL || ctx->prev_scanline_buf == NULL) return encode_err(ctx, SPNG_EMEM);
+
+ /* Maintain alignment for pixels, filter at [-1] */
+ ctx->scanline = ctx->scanline_buf + 16;
+ ctx->prev_scanline = ctx->prev_scanline_buf + 16;
+
+ if(encode_flags->filter_choice)
+ {
+ ctx->filtered_scanline_buf = spng__malloc(ctx, scanline_buf_size);
+ if(ctx->filtered_scanline_buf == NULL) return encode_err(ctx, SPNG_EMEM);
+
+ ctx->filtered_scanline = ctx->filtered_scanline_buf + 16;
+ }
+
+ struct spng_subimage *sub = ctx->subimage;
+ struct spng_row_info *ri = &ctx->row_info;
+
+ ctx->fmt = fmt;
+
+ z_stream *zstream = &ctx->zstream;
+ zstream->avail_out = SPNG_WRITE_SIZE;
+
+ ret = write_header(ctx, type_idat, zstream->avail_out, &zstream->next_out);
+ if(ret) return encode_err(ctx, ret);
+
+ if(ihdr->interlace_method) encode_flags->interlace = 1;
+
+ if(fmt & (SPNG_FMT_PNG | SPNG_FMT_RAW) ) encode_flags->same_layout = 1;
+
+ if(ihdr->bit_depth == 16 && fmt != SPNG_FMT_RAW) encode_flags->to_bigendian = 1;
+
+ if(flags & SPNG_ENCODE_FINALIZE) encode_flags->finalize = 1;
+
+ while(!sub[ri->pass].width || !sub[ri->pass].height) ri->pass++;
+
+ if(encode_flags->interlace) ri->row_num = adam7_y_start[ri->pass];
+
+ ctx->pixel_size = 4; /* SPNG_FMT_RGBA8 */
+
+ if(fmt == SPNG_FMT_RGBA16) ctx->pixel_size = 8;
+ else if(fmt == SPNG_FMT_RGB8) ctx->pixel_size = 3;
+ else if(fmt == SPNG_FMT_G8) ctx->pixel_size = 1;
+ else if(fmt == SPNG_FMT_GA8) ctx->pixel_size = 2;
+ else if(fmt & (SPNG_FMT_PNG | SPNG_FMT_RAW)) ctx->pixel_size = ctx->bytes_per_pixel;
+
+ ctx->state = SPNG_STATE_ENCODE_INIT;
+
+ if(flags & SPNG_ENCODE_PROGRESSIVE)
+ {
+ encode_flags->progressive = 1;
+
+ return 0;
+ }
+
+ do
+ {
+ size_t ioffset = ri->row_num * ctx->image_width;
+
+ ret = encode_row(ctx, (unsigned char*)img + ioffset, ctx->image_width);
+
+ }while(!ret);
+
+ if(ret != SPNG_EOI) return encode_err(ctx, ret);
+
+ return 0;
+}
+
+spng_ctx *spng_ctx_new(int flags)
+{
+ struct spng_alloc alloc =
+ {
+ .malloc_fn = malloc,
+ .realloc_fn = realloc,
+ .calloc_fn = calloc,
+ .free_fn = free
+ };
+
+ return spng_ctx_new2(&alloc, flags);
+}
+
+spng_ctx *spng_ctx_new2(struct spng_alloc *alloc, int flags)
+{
+ if(alloc == NULL) return NULL;
+ if(flags != (flags & SPNG__CTX_FLAGS_ALL)) return NULL;
+
+ if(alloc->malloc_fn == NULL) return NULL;
+ if(alloc->realloc_fn == NULL) return NULL;
+ if(alloc->calloc_fn == NULL) return NULL;
+ if(alloc->free_fn == NULL) return NULL;
+
+ spng_ctx *ctx = alloc->calloc_fn(1, sizeof(spng_ctx));
+ if(ctx == NULL) return NULL;
+
+ ctx->alloc = *alloc;
+
+ ctx->max_width = spng_u32max;
+ ctx->max_height = spng_u32max;
+
+ ctx->max_chunk_size = spng_u32max;
+ ctx->chunk_cache_limit = SIZE_MAX;
+ ctx->chunk_count_limit = SPNG_MAX_CHUNK_COUNT;
+
+ ctx->state = SPNG_STATE_INIT;
+
+ ctx->crc_action_critical = SPNG_CRC_ERROR;
+ ctx->crc_action_ancillary = SPNG_CRC_DISCARD;
+
+ const struct spng__zlib_options image_defaults =
+ {
+ .compression_level = Z_DEFAULT_COMPRESSION,
+ .window_bits = 15,
+ .mem_level = 8,
+ .strategy = Z_FILTERED,
+ .data_type = 0 /* Z_BINARY */
+ };
+
+ const struct spng__zlib_options text_defaults =
+ {
+ .compression_level = Z_DEFAULT_COMPRESSION,
+ .window_bits = 15,
+ .mem_level = 8,
+ .strategy = Z_DEFAULT_STRATEGY,
+ .data_type = 1 /* Z_TEXT */
+ };
+
+ ctx->image_options = image_defaults;
+ ctx->text_options = text_defaults;
+
+ ctx->optimize_option = ~0;
+ ctx->encode_flags.filter_choice = SPNG_FILTER_CHOICE_ALL;
+
+ ctx->flags = flags;
+
+ if(flags & SPNG_CTX_ENCODER) ctx->encode_only = 1;
+
+ return ctx;
+}
+
+void spng_ctx_free(spng_ctx *ctx)
+{
+ if(ctx == NULL) return;
+
+ if(ctx->streaming && ctx->stream_buf != NULL) spng__free(ctx, ctx->stream_buf);
+
+ if(!ctx->user.exif) spng__free(ctx, ctx->exif.data);
+
+ if(!ctx->user.iccp) spng__free(ctx, ctx->iccp.profile);
+
+ uint32_t i;
+
+ if(ctx->splt_list != NULL && !ctx->user.splt)
+ {
+ for(i=0; i < ctx->n_splt; i++)
+ {
+ spng__free(ctx, ctx->splt_list[i].entries);
+ }
+ spng__free(ctx, ctx->splt_list);
+ }
+
+ if(ctx->text_list != NULL)
+ {
+ for(i=0; i< ctx->n_text; i++)
+ {
+ if(ctx->user.text) break;
+
+ spng__free(ctx, ctx->text_list[i].keyword);
+ if(ctx->text_list[i].compression_flag) spng__free(ctx, ctx->text_list[i].text);
+ }
+ spng__free(ctx, ctx->text_list);
+ }
+
+ if(ctx->chunk_list != NULL && !ctx->user.unknown)
+ {
+ for(i=0; i< ctx->n_chunks; i++)
+ {
+ spng__free(ctx, ctx->chunk_list[i].data);
+ }
+ spng__free(ctx, ctx->chunk_list);
+ }
+
+ if(ctx->deflate) deflateEnd(&ctx->zstream);
+ else inflateEnd(&ctx->zstream);
+
+ if(!ctx->user_owns_out_png) spng__free(ctx, ctx->out_png);
+
+ spng__free(ctx, ctx->gamma_lut16);
+
+ spng__free(ctx, ctx->row_buf);
+ spng__free(ctx, ctx->scanline_buf);
+ spng__free(ctx, ctx->prev_scanline_buf);
+ spng__free(ctx, ctx->filtered_scanline_buf);
+
+ spng_free_fn *free_fn = ctx->alloc.free_fn;
+
+ memset(ctx, 0, sizeof(spng_ctx));
+
+ free_fn(ctx);
+}
+
+static int buffer_read_fn(spng_ctx *ctx, void *user, void *data, size_t n)
+{
+ if(n > ctx->bytes_left) return SPNG_IO_EOF;
+
+ (void)user;
+ (void)data;
+ ctx->data = ctx->data + ctx->last_read_size;
+
+ ctx->last_read_size = n;
+ ctx->bytes_left -= n;
+
+ return 0;
+}
+
+static int file_read_fn(spng_ctx *ctx, void *user, void *data, size_t n)
+{
+ FILE *file = user;
+ (void)ctx;
+
+ if(fread(data, n, 1, file) != 1)
+ {
+ if(feof(file)) return SPNG_IO_EOF;
+ else return SPNG_IO_ERROR;
+ }
+
+ return 0;
+}
+
+static int file_write_fn(spng_ctx *ctx, void *user, void *data, size_t n)
+{
+ FILE *file = user;
+ (void)ctx;
+
+ if(fwrite(data, n, 1, file) != 1) return SPNG_IO_ERROR;
+
+ return 0;
+}
+
+int spng_set_png_buffer(spng_ctx *ctx, const void *buf, size_t size)
+{
+ if(ctx == NULL || buf == NULL) return 1;
+ if(!ctx->state) return SPNG_EBADSTATE;
+ if(ctx->encode_only) return SPNG_ECTXTYPE; /* not supported */
+
+ if(ctx->data != NULL) return SPNG_EBUF_SET;
+
+ ctx->data = buf;
+ ctx->png_base = buf;
+ ctx->data_size = size;
+ ctx->bytes_left = size;
+
+ ctx->read_fn = buffer_read_fn;
+
+ ctx->state = SPNG_STATE_INPUT;
+
+ return 0;
+}
+
+int spng_set_png_stream(spng_ctx *ctx, spng_rw_fn *rw_func, void *user)
+{
+ if(ctx == NULL || rw_func == NULL) return 1;
+ if(!ctx->state) return SPNG_EBADSTATE;
+
+ /* SPNG_STATE_OUTPUT shares the same value */
+ if(ctx->state >= SPNG_STATE_INPUT) return SPNG_EBUF_SET;
+
+ if(ctx->encode_only)
+ {
+ if(ctx->out_png != NULL) return SPNG_EBUF_SET;
+
+ ctx->write_fn = rw_func;
+ ctx->write_ptr = ctx->stream_buf;
+
+ ctx->state = SPNG_STATE_OUTPUT;
+ }
+ else
+ {
+ ctx->stream_buf = spng__malloc(ctx, SPNG_READ_SIZE);
+ if(ctx->stream_buf == NULL) return SPNG_EMEM;
+
+ ctx->read_fn = rw_func;
+ ctx->data = ctx->stream_buf;
+ ctx->data_size = SPNG_READ_SIZE;
+
+ ctx->state = SPNG_STATE_INPUT;
+ }
+
+ ctx->stream_user_ptr = user;
+
+ ctx->streaming = 1;
+
+ return 0;
+}
+
+int spng_set_png_file(spng_ctx *ctx, FILE *file)
+{
+ if(file == NULL) return 1;
+
+ if(ctx->encode_only) return spng_set_png_stream(ctx, file_write_fn, file);
+
+ return spng_set_png_stream(ctx, file_read_fn, file);
+}
+
+void *spng_get_png_buffer(spng_ctx *ctx, size_t *len, int *error)
+{
+ int tmp = 0;
+ error = error ? error : &tmp;
+ *error = 0;
+
+ if(ctx == NULL || !len) *error = SPNG_EINVAL;
+
+ if(*error) return NULL;
+
+ if(!ctx->encode_only) *error = SPNG_ECTXTYPE;
+ else if(!ctx->state) *error = SPNG_EBADSTATE;
+ else if(!ctx->internal_buffer) *error = SPNG_EOPSTATE;
+ else if(ctx->state < SPNG_STATE_EOI) *error = SPNG_EOPSTATE;
+ else if(ctx->state != SPNG_STATE_IEND) *error = SPNG_ENOTFINAL;
+
+ if(*error) return NULL;
+
+ ctx->user_owns_out_png = 1;
+
+ *len = ctx->bytes_encoded;
+
+ return ctx->out_png;
+}
+
+int spng_set_image_limits(spng_ctx *ctx, uint32_t width, uint32_t height)
+{
+ if(ctx == NULL) return 1;
+
+ if(width > spng_u32max || height > spng_u32max) return 1;
+
+ ctx->max_width = width;
+ ctx->max_height = height;
+
+ return 0;
+}
+
+int spng_get_image_limits(spng_ctx *ctx, uint32_t *width, uint32_t *height)
+{
+ if(ctx == NULL || width == NULL || height == NULL) return 1;
+
+ *width = ctx->max_width;
+ *height = ctx->max_height;
+
+ return 0;
+}
+
+int spng_set_chunk_limits(spng_ctx *ctx, size_t chunk_size, size_t cache_limit)
+{
+ if(ctx == NULL || chunk_size > spng_u32max || chunk_size > cache_limit) return 1;
+
+ ctx->max_chunk_size = chunk_size;
+
+ ctx->chunk_cache_limit = cache_limit;
+
+ return 0;
+}
+
+int spng_get_chunk_limits(spng_ctx *ctx, size_t *chunk_size, size_t *cache_limit)
+{
+ if(ctx == NULL || chunk_size == NULL || cache_limit == NULL) return 1;
+
+ *chunk_size = ctx->max_chunk_size;
+
+ *cache_limit = ctx->chunk_cache_limit;
+
+ return 0;
+}
+
+int spng_set_crc_action(spng_ctx *ctx, int critical, int ancillary)
+{
+ if(ctx == NULL) return 1;
+ if(ctx->encode_only) return SPNG_ECTXTYPE;
+
+ if(critical > 2 || critical < 0) return 1;
+ if(ancillary > 2 || ancillary < 0) return 1;
+
+ if(critical == SPNG_CRC_DISCARD) return 1;
+
+ ctx->crc_action_critical = critical;
+ ctx->crc_action_ancillary = ancillary;
+
+ return 0;
+}
+
+int spng_set_option(spng_ctx *ctx, enum spng_option option, int value)
+{
+ if(ctx == NULL) return 1;
+ if(!ctx->state) return SPNG_EBADSTATE;
+
+ switch(option)
+ {
+ case SPNG_KEEP_UNKNOWN_CHUNKS:
+ {
+ ctx->keep_unknown = value ? 1 : 0;
+ break;
+ }
+ case SPNG_IMG_COMPRESSION_LEVEL:
+ {
+ ctx->image_options.compression_level = value;
+ break;
+ }
+ case SPNG_IMG_WINDOW_BITS:
+ {
+ ctx->image_options.window_bits = value;
+ break;
+ }
+ case SPNG_IMG_MEM_LEVEL:
+ {
+ ctx->image_options.mem_level = value;
+ break;
+ }
+ case SPNG_IMG_COMPRESSION_STRATEGY:
+ {
+ ctx->image_options.strategy = value;
+ break;
+ }
+ case SPNG_TEXT_COMPRESSION_LEVEL:
+ {
+ ctx->text_options.compression_level = value;
+ break;
+ }
+ case SPNG_TEXT_WINDOW_BITS:
+ {
+ ctx->text_options.window_bits = value;
+ break;
+ }
+ case SPNG_TEXT_MEM_LEVEL:
+ {
+ ctx->text_options.mem_level = value;
+ break;
+ }
+ case SPNG_TEXT_COMPRESSION_STRATEGY:
+ {
+ ctx->text_options.strategy = value;
+ break;
+ }
+ case SPNG_FILTER_CHOICE:
+ {
+ if(value & ~SPNG_FILTER_CHOICE_ALL) return 1;
+ ctx->encode_flags.filter_choice = value;
+ break;
+ }
+ case SPNG_CHUNK_COUNT_LIMIT:
+ {
+ if(value < 0) return 1;
+ if(value > (int)ctx->chunk_count_total) return 1;
+ ctx->chunk_count_limit = value;
+ break;
+ }
+ case SPNG_ENCODE_TO_BUFFER:
+ {
+ if(value < 0) return 1;
+ if(!ctx->encode_only) return SPNG_ECTXTYPE;
+ if(ctx->state >= SPNG_STATE_OUTPUT) return SPNG_EOPSTATE;
+
+ if(!value) break;
+
+ ctx->internal_buffer = 1;
+ ctx->state = SPNG_STATE_OUTPUT;
+
+ break;
+ }
+ default: return 1;
+ }
+
+ /* Option can no longer be overriden by the library */
+ if(option < 32) ctx->optimize_option &= ~(1 << option);
+
+ return 0;
+}
+
+int spng_get_option(spng_ctx *ctx, enum spng_option option, int *value)
+{
+ if(ctx == NULL || value == NULL) return 1;
+ if(!ctx->state) return SPNG_EBADSTATE;
+
+ switch(option)
+ {
+ case SPNG_KEEP_UNKNOWN_CHUNKS:
+ {
+ *value = ctx->keep_unknown;
+ break;
+ }
+ case SPNG_IMG_COMPRESSION_LEVEL:
+ {
+ *value = ctx->image_options.compression_level;
+ break;
+ }
+ case SPNG_IMG_WINDOW_BITS:
+ {
+ *value = ctx->image_options.window_bits;
+ break;
+ }
+ case SPNG_IMG_MEM_LEVEL:
+ {
+ *value = ctx->image_options.mem_level;
+ break;
+ }
+ case SPNG_IMG_COMPRESSION_STRATEGY:
+ {
+ *value = ctx->image_options.strategy;
+ break;
+ }
+ case SPNG_TEXT_COMPRESSION_LEVEL:
+ {
+ *value = ctx->text_options.compression_level;
+ break;
+ }
+ case SPNG_TEXT_WINDOW_BITS:
+ {
+ *value = ctx->text_options.window_bits;
+ break;
+ }
+ case SPNG_TEXT_MEM_LEVEL:
+ {
+ *value = ctx->text_options.mem_level;
+ break;
+ }
+ case SPNG_TEXT_COMPRESSION_STRATEGY:
+ {
+ *value = ctx->text_options.strategy;
+ break;
+ }
+ case SPNG_FILTER_CHOICE:
+ {
+ *value = ctx->encode_flags.filter_choice;
+ break;
+ }
+ case SPNG_CHUNK_COUNT_LIMIT:
+ {
+ *value = ctx->chunk_count_limit;
+ break;
+ }
+ case SPNG_ENCODE_TO_BUFFER:
+ {
+ if(ctx->internal_buffer) *value = 1;
+ else *value = 0;
+
+ break;
+ }
+ default: return 1;
+ }
+
+ return 0;
+}
+
+int spng_decoded_image_size(spng_ctx *ctx, int fmt, size_t *len)
+{
+ if(ctx == NULL || len == NULL) return 1;
+
+ int ret = read_chunks(ctx, 1);
+ if(ret) return ret;
+
+ ret = check_decode_fmt(&ctx->ihdr, fmt);
+ if(ret) return ret;
+
+ return calculate_image_size(&ctx->ihdr, fmt, len);
+}
+
+int spng_get_ihdr(spng_ctx *ctx, struct spng_ihdr *ihdr)
+{
+ if(ctx == NULL) return 1;
+ int ret = read_chunks(ctx, 1);
+ if(ret) return ret;
+ if(ihdr == NULL) return 1;
+
+ *ihdr = ctx->ihdr;
+
+ return 0;
+}
+
+int spng_get_plte(spng_ctx *ctx, struct spng_plte *plte)
+{
+ SPNG_GET_CHUNK_BOILERPLATE(plte);
+
+ *plte = ctx->plte;
+
+ return 0;
+}
+
+int spng_get_trns(spng_ctx *ctx, struct spng_trns *trns)
+{
+ SPNG_GET_CHUNK_BOILERPLATE(trns);
+
+ *trns = ctx->trns;
+
+ return 0;
+}
+
+int spng_get_chrm(spng_ctx *ctx, struct spng_chrm *chrm)
+{
+ SPNG_GET_CHUNK_BOILERPLATE(chrm);
+
+ chrm->white_point_x = (double)ctx->chrm_int.white_point_x / 100000.0;
+ chrm->white_point_y = (double)ctx->chrm_int.white_point_y / 100000.0;
+ chrm->red_x = (double)ctx->chrm_int.red_x / 100000.0;
+ chrm->red_y = (double)ctx->chrm_int.red_y / 100000.0;
+ chrm->blue_y = (double)ctx->chrm_int.blue_y / 100000.0;
+ chrm->blue_x = (double)ctx->chrm_int.blue_x / 100000.0;
+ chrm->green_x = (double)ctx->chrm_int.green_x / 100000.0;
+ chrm->green_y = (double)ctx->chrm_int.green_y / 100000.0;
+
+ return 0;
+}
+
+int spng_get_chrm_int(spng_ctx *ctx, struct spng_chrm_int *chrm)
+{
+ SPNG_GET_CHUNK_BOILERPLATE(chrm);
+
+ *chrm = ctx->chrm_int;
+
+ return 0;
+}
+
+int spng_get_gama(spng_ctx *ctx, double *gamma)
+{
+ double *gama = gamma;
+ SPNG_GET_CHUNK_BOILERPLATE(gama);
+
+ *gama = (double)ctx->gama / 100000.0;
+
+ return 0;
+}
+
+int spng_get_gama_int(spng_ctx *ctx, uint32_t *gama_int)
+{
+ uint32_t *gama = gama_int;
+ SPNG_GET_CHUNK_BOILERPLATE(gama);
+
+ *gama_int = ctx->gama;
+
+ return 0;
+}
+
+int spng_get_iccp(spng_ctx *ctx, struct spng_iccp *iccp)
+{
+ SPNG_GET_CHUNK_BOILERPLATE(iccp);
+
+ *iccp = ctx->iccp;
+
+ return 0;
+}
+
+int spng_get_sbit(spng_ctx *ctx, struct spng_sbit *sbit)
+{
+ SPNG_GET_CHUNK_BOILERPLATE(sbit);
+
+ *sbit = ctx->sbit;
+
+ return 0;
+}
+
+int spng_get_srgb(spng_ctx *ctx, uint8_t *rendering_intent)
+{
+ uint8_t *srgb = rendering_intent;
+ SPNG_GET_CHUNK_BOILERPLATE(srgb);
+
+ *srgb = ctx->srgb_rendering_intent;
+
+ return 0;
+}
+
+int spng_get_text(spng_ctx *ctx, struct spng_text *text, uint32_t *n_text)
+{
+ if(ctx == NULL) return 1;
+ int ret = read_chunks(ctx, 0);
+ if(ret) return ret;
+ if(!ctx->stored.text) return SPNG_ECHUNKAVAIL;
+ if(n_text == NULL) return 1;
+
+ if(text == NULL)
+ {
+ *n_text = ctx->n_text;
+ return 0;
+ }
+
+ if(*n_text < ctx->n_text) return 1;
+
+ uint32_t i;
+ for(i=0; i< ctx->n_text; i++)
+ {
+ text[i].type = ctx->text_list[i].type;
+ memcpy(&text[i].keyword, ctx->text_list[i].keyword, strlen(ctx->text_list[i].keyword) + 1);
+ text[i].compression_method = 0;
+ text[i].compression_flag = ctx->text_list[i].compression_flag;
+ text[i].language_tag = ctx->text_list[i].language_tag;
+ text[i].translated_keyword = ctx->text_list[i].translated_keyword;
+ text[i].length = ctx->text_list[i].text_length;
+ text[i].text = ctx->text_list[i].text;
+ }
+
+ return ret;
+}
+
+int spng_get_bkgd(spng_ctx *ctx, struct spng_bkgd *bkgd)
+{
+ SPNG_GET_CHUNK_BOILERPLATE(bkgd);
+
+ *bkgd = ctx->bkgd;
+
+ return 0;
+}
+
+int spng_get_hist(spng_ctx *ctx, struct spng_hist *hist)
+{
+ SPNG_GET_CHUNK_BOILERPLATE(hist);
+
+ *hist = ctx->hist;
+
+ return 0;
+}
+
+int spng_get_phys(spng_ctx *ctx, struct spng_phys *phys)
+{
+ SPNG_GET_CHUNK_BOILERPLATE(phys);
+
+ *phys = ctx->phys;
+
+ return 0;
+}
+
+int spng_get_splt(spng_ctx *ctx, struct spng_splt *splt, uint32_t *n_splt)
+{
+ if(ctx == NULL) return 1;
+ int ret = read_chunks(ctx, 0);
+ if(ret) return ret;
+ if(!ctx->stored.splt) return SPNG_ECHUNKAVAIL;
+ if(n_splt == NULL) return 1;
+
+ if(splt == NULL)
+ {
+ *n_splt = ctx->n_splt;
+ return 0;
+ }
+
+ if(*n_splt < ctx->n_splt) return 1;
+
+ memcpy(splt, ctx->splt_list, ctx->n_splt * sizeof(struct spng_splt));
+
+ return 0;
+}
+
+int spng_get_time(spng_ctx *ctx, struct spng_time *time)
+{
+ SPNG_GET_CHUNK_BOILERPLATE(time);
+
+ *time = ctx->time;
+
+ return 0;
+}
+
+int spng_get_unknown_chunks(spng_ctx *ctx, struct spng_unknown_chunk *chunks, uint32_t *n_chunks)
+{
+ if(ctx == NULL) return 1;
+ int ret = read_chunks(ctx, 0);
+ if(ret) return ret;
+ if(!ctx->stored.unknown) return SPNG_ECHUNKAVAIL;
+ if(n_chunks == NULL) return 1;
+
+ if(chunks == NULL)
+ {
+ *n_chunks = ctx->n_chunks;
+ return 0;
+ }
+
+ if(*n_chunks < ctx->n_chunks) return 1;
+
+ memcpy(chunks, ctx->chunk_list, sizeof(struct spng_unknown_chunk));
+
+ return 0;
+}
+
+int spng_get_offs(spng_ctx *ctx, struct spng_offs *offs)
+{
+ SPNG_GET_CHUNK_BOILERPLATE(offs);
+
+ *offs = ctx->offs;
+
+ return 0;
+}
+
+int spng_get_exif(spng_ctx *ctx, struct spng_exif *exif)
+{
+ SPNG_GET_CHUNK_BOILERPLATE(exif);
+
+ *exif = ctx->exif;
+
+ return 0;
+}
+
+int spng_set_ihdr(spng_ctx *ctx, struct spng_ihdr *ihdr)
+{
+ SPNG_SET_CHUNK_BOILERPLATE(ihdr);
+
+ if(ctx->stored.ihdr) return 1;
+
+ ret = check_ihdr(ihdr, ctx->max_width, ctx->max_height);
+ if(ret) return ret;
+
+ ctx->ihdr = *ihdr;
+
+ ctx->stored.ihdr = 1;
+ ctx->user.ihdr = 1;
+
+ return 0;
+}
+
+int spng_set_plte(spng_ctx *ctx, struct spng_plte *plte)
+{
+ SPNG_SET_CHUNK_BOILERPLATE(plte);
+
+ if(!ctx->stored.ihdr) return 1;
+
+ if(check_plte(plte, &ctx->ihdr)) return 1;
+
+ ctx->plte.n_entries = plte->n_entries;
+
+ memcpy(ctx->plte.entries, plte->entries, plte->n_entries * sizeof(struct spng_plte_entry));
+
+ ctx->stored.plte = 1;
+ ctx->user.plte = 1;
+
+ return 0;
+}
+
+int spng_set_trns(spng_ctx *ctx, struct spng_trns *trns)
+{
+ SPNG_SET_CHUNK_BOILERPLATE(trns);
+
+ if(!ctx->stored.ihdr) return SPNG_ENOIHDR;
+
+ if(ctx->ihdr.color_type == SPNG_COLOR_TYPE_GRAYSCALE)
+ {
+ ctx->trns.gray = trns->gray;
+ }
+ else if(ctx->ihdr.color_type == SPNG_COLOR_TYPE_TRUECOLOR)
+ {
+ ctx->trns.red = trns->red;
+ ctx->trns.green = trns->green;
+ ctx->trns.blue = trns->blue;
+ }
+ else if(ctx->ihdr.color_type == SPNG_COLOR_TYPE_INDEXED)
+ {
+ if(!ctx->stored.plte) return SPNG_ETRNS_NO_PLTE;
+ if(trns->n_type3_entries > ctx->plte.n_entries) return 1;
+
+ ctx->trns.n_type3_entries = trns->n_type3_entries;
+ memcpy(ctx->trns.type3_alpha, trns->type3_alpha, trns->n_type3_entries);
+ }
+ else return SPNG_ETRNS_COLOR_TYPE;
+
+ ctx->stored.trns = 1;
+ ctx->user.trns = 1;
+
+ return 0;
+}
+
+int spng_set_chrm(spng_ctx *ctx, struct spng_chrm *chrm)
+{
+ SPNG_SET_CHUNK_BOILERPLATE(chrm);
+
+ struct spng_chrm_int chrm_int;
+
+ chrm_int.white_point_x = (uint32_t)(chrm->white_point_x * 100000.0);
+ chrm_int.white_point_y = (uint32_t)(chrm->white_point_y * 100000.0);
+ chrm_int.red_x = (uint32_t)(chrm->red_x * 100000.0);
+ chrm_int.red_y = (uint32_t)(chrm->red_y * 100000.0);
+ chrm_int.green_x = (uint32_t)(chrm->green_x * 100000.0);
+ chrm_int.green_y = (uint32_t)(chrm->green_y * 100000.0);
+ chrm_int.blue_x = (uint32_t)(chrm->blue_x * 100000.0);
+ chrm_int.blue_y = (uint32_t)(chrm->blue_y * 100000.0);
+
+ if(check_chrm_int(&chrm_int)) return SPNG_ECHRM;
+
+ ctx->chrm_int = chrm_int;
+
+ ctx->stored.chrm = 1;
+ ctx->user.chrm = 1;
+
+ return 0;
+}
+
+int spng_set_chrm_int(spng_ctx *ctx, struct spng_chrm_int *chrm_int)
+{
+ SPNG_SET_CHUNK_BOILERPLATE(chrm_int);
+
+ if(check_chrm_int(chrm_int)) return SPNG_ECHRM;
+
+ ctx->chrm_int = *chrm_int;
+
+ ctx->stored.chrm = 1;
+ ctx->user.chrm = 1;
+
+ return 0;
+}
+
+int spng_set_gama(spng_ctx *ctx, double gamma)
+{
+ SPNG_SET_CHUNK_BOILERPLATE(ctx);
+
+ uint32_t gama = gamma * 100000.0;
+
+ if(!gama) return 1;
+ if(gama > spng_u32max) return 1;
+
+ ctx->gama = gama;
+
+ ctx->stored.gama = 1;
+ ctx->user.gama = 1;
+
+ return 0;
+}
+
+int spng_set_gama_int(spng_ctx *ctx, uint32_t gamma)
+{
+ SPNG_SET_CHUNK_BOILERPLATE(ctx);
+
+ if(!gamma) return 1;
+ if(gamma > spng_u32max) return 1;
+
+ ctx->gama = gamma;
+
+ ctx->stored.gama = 1;
+ ctx->user.gama = 1;
+
+ return 0;
+}
+
+int spng_set_iccp(spng_ctx *ctx, struct spng_iccp *iccp)
+{
+ SPNG_SET_CHUNK_BOILERPLATE(iccp);
+
+ if(check_png_keyword(iccp->profile_name)) return SPNG_EICCP_NAME;
+ if(!iccp->profile_len) return SPNG_ECHUNK_SIZE;
+ if(iccp->profile_len > spng_u32max) return SPNG_ECHUNK_STDLEN;
+
+ if(ctx->iccp.profile && !ctx->user.iccp) spng__free(ctx, ctx->iccp.profile);
+
+ ctx->iccp = *iccp;
+
+ ctx->stored.iccp = 1;
+ ctx->user.iccp = 1;
+
+ return 0;
+}
+
+int spng_set_sbit(spng_ctx *ctx, struct spng_sbit *sbit)
+{
+ SPNG_SET_CHUNK_BOILERPLATE(sbit);
+
+ if(check_sbit(sbit, &ctx->ihdr)) return 1;
+
+ if(!ctx->stored.ihdr) return 1;
+
+ ctx->sbit = *sbit;
+
+ ctx->stored.sbit = 1;
+ ctx->user.sbit = 1;
+
+ return 0;
+}
+
+int spng_set_srgb(spng_ctx *ctx, uint8_t rendering_intent)
+{
+ SPNG_SET_CHUNK_BOILERPLATE(ctx);
+
+ if(rendering_intent > 3) return 1;
+
+ ctx->srgb_rendering_intent = rendering_intent;
+
+ ctx->stored.srgb = 1;
+ ctx->user.srgb = 1;
+
+ return 0;
+}
+
+int spng_set_text(spng_ctx *ctx, struct spng_text *text, uint32_t n_text)
+{
+ if(!n_text) return 1;
+ SPNG_SET_CHUNK_BOILERPLATE(text);
+
+ uint32_t i;
+ for(i=0; i < n_text; i++)
+ {
+ if(check_png_keyword(text[i].keyword)) return SPNG_ETEXT_KEYWORD;
+ if(!text[i].length) return 1;
+ if(text[i].length > UINT_MAX) return 1;
+ if(text[i].text == NULL) return 1;
+
+ if(text[i].type == SPNG_TEXT)
+ {
+ if(ctx->strict && check_png_text(text[i].text, text[i].length)) return 1;
+ }
+ else if(text[i].type == SPNG_ZTXT)
+ {
+ if(ctx->strict && check_png_text(text[i].text, text[i].length)) return 1;
+
+ if(text[i].compression_method != 0) return SPNG_EZTXT_COMPRESSION_METHOD;
+ }
+ else if(text[i].type == SPNG_ITXT)
+ {
+ if(text[i].compression_flag > 1) return SPNG_EITXT_COMPRESSION_FLAG;
+ if(text[i].compression_method != 0) return SPNG_EITXT_COMPRESSION_METHOD;
+ if(text[i].language_tag == NULL) return SPNG_EITXT_LANG_TAG;
+ if(text[i].translated_keyword == NULL) return SPNG_EITXT_TRANSLATED_KEY;
+ }
+ else return 1;
+
+ }
+
+ struct spng_text2 *text_list = spng__calloc(ctx, sizeof(struct spng_text2), n_text);
+
+ if(!text_list) return SPNG_EMEM;
+
+ if(ctx->text_list != NULL)
+ {
+ for(i=0; i < ctx->n_text; i++)
+ {
+ if(ctx->user.text) break;
+
+ spng__free(ctx, ctx->text_list[i].keyword);
+ if(ctx->text_list[i].compression_flag) spng__free(ctx, ctx->text_list[i].text);
+ }
+ spng__free(ctx, ctx->text_list);
+ }
+
+ for(i=0; i < n_text; i++)
+ {
+ text_list[i].type = text[i].type;
+ /* Prevent issues with spng_text.keyword[80] going out of scope */
+ text_list[i].keyword = text_list[i].user_keyword_storage;
+ memcpy(text_list[i].user_keyword_storage, text[i].keyword, strlen(text[i].keyword));
+ text_list[i].text = text[i].text;
+ text_list[i].text_length = text[i].length;
+
+ if(text[i].type == SPNG_ZTXT)
+ {
+ text_list[i].compression_flag = 1;
+ }
+ else if(text[i].type == SPNG_ITXT)
+ {
+ text_list[i].compression_flag = text[i].compression_flag;
+ text_list[i].language_tag = text[i].language_tag;
+ text_list[i].translated_keyword = text[i].translated_keyword;
+ }
+ }
+
+ ctx->text_list = text_list;
+ ctx->n_text = n_text;
+
+ ctx->stored.text = 1;
+ ctx->user.text = 1;
+
+ return 0;
+}
+
+int spng_set_bkgd(spng_ctx *ctx, struct spng_bkgd *bkgd)
+{
+ SPNG_SET_CHUNK_BOILERPLATE(bkgd);
+
+ if(!ctx->stored.ihdr) return 1;
+
+ if(ctx->ihdr.color_type == 0 || ctx->ihdr.color_type == 4)
+ {
+ ctx->bkgd.gray = bkgd->gray;
+ }
+ else if(ctx->ihdr.color_type == 2 || ctx->ihdr.color_type == 6)
+ {
+ ctx->bkgd.red = bkgd->red;
+ ctx->bkgd.green = bkgd->green;
+ ctx->bkgd.blue = bkgd->blue;
+ }
+ else if(ctx->ihdr.color_type == 3)
+ {
+ if(!ctx->stored.plte) return SPNG_EBKGD_NO_PLTE;
+ if(bkgd->plte_index >= ctx->plte.n_entries) return SPNG_EBKGD_PLTE_IDX;
+
+ ctx->bkgd.plte_index = bkgd->plte_index;
+ }
+
+ ctx->stored.bkgd = 1;
+ ctx->user.bkgd = 1;
+
+ return 0;
+}
+
+int spng_set_hist(spng_ctx *ctx, struct spng_hist *hist)
+{
+ SPNG_SET_CHUNK_BOILERPLATE(hist);
+
+ if(!ctx->stored.plte) return SPNG_EHIST_NO_PLTE;
+
+ ctx->hist = *hist;
+
+ ctx->stored.hist = 1;
+ ctx->user.hist = 1;
+
+ return 0;
+}
+
+int spng_set_phys(spng_ctx *ctx, struct spng_phys *phys)
+{
+ SPNG_SET_CHUNK_BOILERPLATE(phys);
+
+ if(check_phys(phys)) return SPNG_EPHYS;
+
+ ctx->phys = *phys;
+
+ ctx->stored.phys = 1;
+ ctx->user.phys = 1;
+
+ return 0;
+}
+
+int spng_set_splt(spng_ctx *ctx, struct spng_splt *splt, uint32_t n_splt)
+{
+ if(!n_splt) return 1;
+ SPNG_SET_CHUNK_BOILERPLATE(splt);
+
+ uint32_t i;
+ for(i=0; i < n_splt; i++)
+ {
+ if(check_png_keyword(splt[i].name)) return SPNG_ESPLT_NAME;
+ if( !(splt[i].sample_depth == 8 || splt[i].sample_depth == 16) ) return SPNG_ESPLT_DEPTH;
+ }
+
+ if(ctx->stored.splt && !ctx->user.splt)
+ {
+ for(i=0; i < ctx->n_splt; i++)
+ {
+ if(ctx->splt_list[i].entries != NULL) spng__free(ctx, ctx->splt_list[i].entries);
+ }
+ spng__free(ctx, ctx->splt_list);
+ }
+
+ ctx->splt_list = splt;
+ ctx->n_splt = n_splt;
+
+ ctx->stored.splt = 1;
+ ctx->user.splt = 1;
+
+ return 0;
+}
+
+int spng_set_time(spng_ctx *ctx, struct spng_time *time)
+{
+ SPNG_SET_CHUNK_BOILERPLATE(time);
+
+ if(check_time(time)) return SPNG_ETIME;
+
+ ctx->time = *time;
+
+ ctx->stored.time = 1;
+ ctx->user.time = 1;
+
+ return 0;
+}
+
+int spng_set_unknown_chunks(spng_ctx *ctx, struct spng_unknown_chunk *chunks, uint32_t n_chunks)
+{
+ if(!n_chunks) return 1;
+ SPNG_SET_CHUNK_BOILERPLATE(chunks);
+
+ uint32_t i;
+ for(i=0; i < n_chunks; i++)
+ {
+ if(chunks[i].length > spng_u32max) return SPNG_ECHUNK_STDLEN;
+ if(chunks[i].length && chunks[i].data == NULL) return 1;
+
+ switch(chunks[i].location)
+ {
+ case SPNG_AFTER_IHDR:
+ case SPNG_AFTER_PLTE:
+ case SPNG_AFTER_IDAT:
+ break;
+ default: return SPNG_ECHUNK_POS;
+ }
+ }
+
+ if(ctx->stored.unknown && !ctx->user.unknown)
+ {
+ for(i=0; i < ctx->n_chunks; i++)
+ {
+ spng__free(ctx, ctx->chunk_list[i].data);
+ }
+ spng__free(ctx, ctx->chunk_list);
+ }
+
+ ctx->chunk_list = chunks;
+ ctx->n_chunks = n_chunks;
+
+ ctx->stored.unknown = 1;
+ ctx->user.unknown = 1;
+
+ return 0;
+}
+
+int spng_set_offs(spng_ctx *ctx, struct spng_offs *offs)
+{
+ SPNG_SET_CHUNK_BOILERPLATE(offs);
+
+ if(check_offs(offs)) return SPNG_EOFFS;
+
+ ctx->offs = *offs;
+
+ ctx->stored.offs = 1;
+ ctx->user.offs = 1;
+
+ return 0;
+}
+
+int spng_set_exif(spng_ctx *ctx, struct spng_exif *exif)
+{
+ SPNG_SET_CHUNK_BOILERPLATE(exif);
+
+ if(check_exif(exif)) return SPNG_EEXIF;
+
+ if(ctx->exif.data != NULL && !ctx->user.exif) spng__free(ctx, ctx->exif.data);
+
+ ctx->exif = *exif;
+
+ ctx->stored.exif = 1;
+ ctx->user.exif = 1;
+
+ return 0;
+}
+
+const char *spng_strerror(int err)
+{
+ switch(err)
+ {
+ case SPNG_IO_EOF: return "end of stream";
+ case SPNG_IO_ERROR: return "stream error";
+ case SPNG_OK: return "success";
+ case SPNG_EINVAL: return "invalid argument";
+ case SPNG_EMEM: return "out of memory";
+ case SPNG_EOVERFLOW: return "arithmetic overflow";
+ case SPNG_ESIGNATURE: return "invalid signature";
+ case SPNG_EWIDTH: return "invalid image width";
+ case SPNG_EHEIGHT: return "invalid image height";
+ case SPNG_EUSER_WIDTH: return "image width exceeds user limit";
+ case SPNG_EUSER_HEIGHT: return "image height exceeds user limit";
+ case SPNG_EBIT_DEPTH: return "invalid bit depth";
+ case SPNG_ECOLOR_TYPE: return "invalid color type";
+ case SPNG_ECOMPRESSION_METHOD: return "invalid compression method";
+ case SPNG_EFILTER_METHOD: return "invalid filter method";
+ case SPNG_EINTERLACE_METHOD: return "invalid interlace method";
+ case SPNG_EIHDR_SIZE: return "invalid IHDR chunk size";
+ case SPNG_ENOIHDR: return "missing IHDR chunk";
+ case SPNG_ECHUNK_POS: return "invalid chunk position";
+ case SPNG_ECHUNK_SIZE: return "invalid chunk length";
+ case SPNG_ECHUNK_CRC: return "invalid chunk checksum";
+ case SPNG_ECHUNK_TYPE: return "invalid chunk type";
+ case SPNG_ECHUNK_UNKNOWN_CRITICAL: return "unknown critical chunk";
+ case SPNG_EDUP_PLTE: return "duplicate PLTE chunk";
+ case SPNG_EDUP_CHRM: return "duplicate cHRM chunk";
+ case SPNG_EDUP_GAMA: return "duplicate gAMA chunk";
+ case SPNG_EDUP_ICCP: return "duplicate iCCP chunk";
+ case SPNG_EDUP_SBIT: return "duplicate sBIT chunk";
+ case SPNG_EDUP_SRGB: return "duplicate sRGB chunk";
+ case SPNG_EDUP_BKGD: return "duplicate bKGD chunk";
+ case SPNG_EDUP_HIST: return "duplicate hIST chunk";
+ case SPNG_EDUP_TRNS: return "duplicate tRNS chunk";
+ case SPNG_EDUP_PHYS: return "duplicate pHYs chunk";
+ case SPNG_EDUP_TIME: return "duplicate tIME chunk";
+ case SPNG_EDUP_OFFS: return "duplicate oFFs chunk";
+ case SPNG_EDUP_EXIF: return "duplicate eXIf chunk";
+ case SPNG_ECHRM: return "invalid cHRM chunk";
+ case SPNG_EPLTE_IDX: return "invalid palette (PLTE) index";
+ case SPNG_ETRNS_COLOR_TYPE: return "tRNS chunk with incompatible color type";
+ case SPNG_ETRNS_NO_PLTE: return "missing palette (PLTE) for tRNS chunk";
+ case SPNG_EGAMA: return "invalid gAMA chunk";
+ case SPNG_EICCP_NAME: return "invalid iCCP profile name";
+ case SPNG_EICCP_COMPRESSION_METHOD: return "invalid iCCP compression method";
+ case SPNG_ESBIT: return "invalid sBIT chunk";
+ case SPNG_ESRGB: return "invalid sRGB chunk";
+ case SPNG_ETEXT: return "invalid tEXt chunk";
+ case SPNG_ETEXT_KEYWORD: return "invalid tEXt keyword";
+ case SPNG_EZTXT: return "invalid zTXt chunk";
+ case SPNG_EZTXT_COMPRESSION_METHOD: return "invalid zTXt compression method";
+ case SPNG_EITXT: return "invalid iTXt chunk";
+ case SPNG_EITXT_COMPRESSION_FLAG: return "invalid iTXt compression flag";
+ case SPNG_EITXT_COMPRESSION_METHOD: return "invalid iTXt compression method";
+ case SPNG_EITXT_LANG_TAG: return "invalid iTXt language tag";
+ case SPNG_EITXT_TRANSLATED_KEY: return "invalid iTXt translated key";
+ case SPNG_EBKGD_NO_PLTE: return "missing palette for bKGD chunk";
+ case SPNG_EBKGD_PLTE_IDX: return "invalid palette index for bKGD chunk";
+ case SPNG_EHIST_NO_PLTE: return "missing palette for hIST chunk";
+ case SPNG_EPHYS: return "invalid pHYs chunk";
+ case SPNG_ESPLT_NAME: return "invalid suggested palette name";
+ case SPNG_ESPLT_DUP_NAME: return "duplicate suggested palette (sPLT) name";
+ case SPNG_ESPLT_DEPTH: return "invalid suggested palette (sPLT) sample depth";
+ case SPNG_ETIME: return "invalid tIME chunk";
+ case SPNG_EOFFS: return "invalid oFFs chunk";
+ case SPNG_EEXIF: return "invalid eXIf chunk";
+ case SPNG_EIDAT_TOO_SHORT: return "IDAT stream too short";
+ case SPNG_EIDAT_STREAM: return "IDAT stream error";
+ case SPNG_EZLIB: return "zlib error";
+ case SPNG_EFILTER: return "invalid scanline filter";
+ case SPNG_EBUFSIZ: return "invalid buffer size";
+ case SPNG_EIO: return "i/o error";
+ case SPNG_EOF: return "end of file";
+ case SPNG_EBUF_SET: return "buffer already set";
+ case SPNG_EBADSTATE: return "non-recoverable state";
+ case SPNG_EFMT: return "invalid format";
+ case SPNG_EFLAGS: return "invalid flags";
+ case SPNG_ECHUNKAVAIL: return "chunk not available";
+ case SPNG_ENCODE_ONLY: return "encode only context";
+ case SPNG_EOI: return "reached end-of-image state";
+ case SPNG_ENOPLTE: return "missing PLTE for indexed image";
+ case SPNG_ECHUNK_LIMITS: return "reached chunk/cache limits";
+ case SPNG_EZLIB_INIT: return "zlib init error";
+ case SPNG_ECHUNK_STDLEN: return "chunk exceeds maximum standard length";
+ case SPNG_EINTERNAL: return "internal error";
+ case SPNG_ECTXTYPE: return "invalid operation for context type";
+ case SPNG_ENOSRC: return "source PNG not set";
+ case SPNG_ENODST: return "PNG output not set";
+ case SPNG_EOPSTATE: return "invalid operation for state";
+ case SPNG_ENOTFINAL: return "PNG not finalized";
+ default: return "unknown error";
+ }
+}
+
+const char *spng_version_string(void)
+{
+ return SPNG_VERSION_STRING;
+}
+
+#if defined(_MSC_VER)
+ #pragma warning(pop)
+#endif
+
+/* The following SIMD optimizations are derived from libpng source code. */
+
+/*
+* PNG Reference Library License version 2
+*
+* Copyright (c) 1995-2019 The PNG Reference Library Authors.
+* Copyright (c) 2018-2019 Cosmin Truta.
+* Copyright (c) 2000-2002, 2004, 2006-2018 Glenn Randers-Pehrson.
+* Copyright (c) 1996-1997 Andreas Dilger.
+* Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc.
+*
+* The software is supplied "as is", without warranty of any kind,
+* express or implied, including, without limitation, the warranties
+* of merchantability, fitness for a particular purpose, title, and
+* non-infringement. In no event shall the Copyright owners, or
+* anyone distributing the software, be liable for any damages or
+* other liability, whether in contract, tort or otherwise, arising
+* from, out of, or in connection with the software, or the use or
+* other dealings in the software, even if advised of the possibility
+* of such damage.
+*
+* Permission is hereby granted to use, copy, modify, and distribute
+* this software, or portions hereof, for any purpose, without fee,
+* subject to the following restrictions:
+*
+* 1. The origin of this software must not be misrepresented; you
+* must not claim that you wrote the original software. If you
+* use this software in a product, an acknowledgment in the product
+* documentation would be appreciated, but is not required.
+*
+* 2. Altered source versions must be plainly marked as such, and must
+* not be misrepresented as being the original software.
+*
+* 3. This Copyright notice may not be removed or altered from any
+* source or altered source distribution.
+*/
+
+#if defined(SPNG_X86)
+
+#ifndef SPNG_SSE
+ #define SPNG_SSE 1
+#endif
+
+#if defined(__GNUC__) && !defined(__clang__)
+ #if SPNG_SSE == 3
+ #pragma GCC target("ssse3")
+ #elif SPNG_SSE == 4
+ #pragma GCC target("sse4.1")
+ #else
+ #pragma GCC target("sse2")
+ #endif
+#endif
+
+/* SSE2 optimised filter functions
+ * Derived from filter_neon_intrinsics.c
+ *
+ * Copyright (c) 2018 Cosmin Truta
+ * Copyright (c) 2016-2017 Glenn Randers-Pehrson
+ * Written by Mike Klein and Matt Sarett
+ * Derived from arm/filter_neon_intrinsics.c
+ *
+ * This code is derived from libpng source code.
+ * For conditions of distribution and use, see the disclaimer
+ * and license above.
+ */
+
+#include
+#include
+#include
+
+/* Functions in this file look at most 3 pixels (a,b,c) to predict the 4th (d).
+ * They're positioned like this:
+ * prev: c b
+ * row: a d
+ * The Sub filter predicts d=a, Avg d=(a+b)/2, and Paeth predicts d to be
+ * whichever of a, b, or c is closest to p=a+b-c.
+ */
+
+static __m128i load4(const void* p)
+{
+ int tmp;
+ memcpy(&tmp, p, sizeof(tmp));
+ return _mm_cvtsi32_si128(tmp);
+}
+
+static void store4(void* p, __m128i v)
+{
+ int tmp = _mm_cvtsi128_si32(v);
+ memcpy(p, &tmp, sizeof(int));
+}
+
+static __m128i load3(const void* p)
+{
+ uint32_t tmp = 0;
+ memcpy(&tmp, p, 3);
+ return _mm_cvtsi32_si128(tmp);
+}
+
+static void store3(void* p, __m128i v)
+{
+ int tmp = _mm_cvtsi128_si32(v);
+ memcpy(p, &tmp, 3);
+}
+
+static void defilter_sub3(size_t rowbytes, unsigned char *row)
+{
+ /* The Sub filter predicts each pixel as the previous pixel, a.
+ * There is no pixel to the left of the first pixel. It's encoded directly.
+ * That works with our main loop if we just say that left pixel was zero.
+ */
+ size_t rb = rowbytes;
+
+ __m128i a, d = _mm_setzero_si128();
+
+ while(rb >= 4)
+ {
+ a = d; d = load4(row);
+ d = _mm_add_epi8(d, a);
+ store3(row, d);
+
+ row += 3;
+ rb -= 3;
+ }
+
+ if(rb > 0)
+ {
+ a = d; d = load3(row);
+ d = _mm_add_epi8(d, a);
+ store3(row, d);
+ }
+}
+
+static void defilter_sub4(size_t rowbytes, unsigned char *row)
+{
+ /* The Sub filter predicts each pixel as the previous pixel, a.
+ * There is no pixel to the left of the first pixel. It's encoded directly.
+ * That works with our main loop if we just say that left pixel was zero.
+ */
+ size_t rb = rowbytes+4;
+
+ __m128i a, d = _mm_setzero_si128();
+
+ while(rb > 4)
+ {
+ a = d; d = load4(row);
+ d = _mm_add_epi8(d, a);
+ store4(row, d);
+
+ row += 4;
+ rb -= 4;
+ }
+}
+
+static void defilter_avg3(size_t rowbytes, unsigned char *row, const unsigned char *prev)
+{
+ /* The Avg filter predicts each pixel as the (truncated) average of a and b.
+ * There's no pixel to the left of the first pixel. Luckily, it's
+ * predicted to be half of the pixel above it. So again, this works
+ * perfectly with our loop if we make sure a starts at zero.
+ */
+
+ size_t rb = rowbytes;
+
+ const __m128i zero = _mm_setzero_si128();
+
+ __m128i b;
+ __m128i a, d = zero;
+
+ while(rb >= 4)
+ {
+ __m128i avg;
+ b = load4(prev);
+ a = d; d = load4(row );
+
+ /* PNG requires a truncating average, so we can't just use _mm_avg_epu8 */
+ avg = _mm_avg_epu8(a,b);
+ /* ...but we can fix it up by subtracting off 1 if it rounded up. */
+ avg = _mm_sub_epi8(avg, _mm_and_si128(_mm_xor_si128(a, b),
+ _mm_set1_epi8(1)));
+ d = _mm_add_epi8(d, avg);
+ store3(row, d);
+
+ prev += 3;
+ row += 3;
+ rb -= 3;
+ }
+
+ if(rb > 0)
+ {
+ __m128i avg;
+ b = load3(prev);
+ a = d; d = load3(row );
+
+ /* PNG requires a truncating average, so we can't just use _mm_avg_epu8 */
+ avg = _mm_avg_epu8(a, b);
+ /* ...but we can fix it up by subtracting off 1 if it rounded up. */
+ avg = _mm_sub_epi8(avg, _mm_and_si128(_mm_xor_si128(a, b),
+ _mm_set1_epi8(1)));
+
+ d = _mm_add_epi8(d, avg);
+ store3(row, d);
+ }
+}
+
+static void defilter_avg4(size_t rowbytes, unsigned char *row, const unsigned char *prev)
+{
+ /* The Avg filter predicts each pixel as the (truncated) average of a and b.
+ * There's no pixel to the left of the first pixel. Luckily, it's
+ * predicted to be half of the pixel above it. So again, this works
+ * perfectly with our loop if we make sure a starts at zero.
+ */
+ size_t rb = rowbytes+4;
+
+ const __m128i zero = _mm_setzero_si128();
+ __m128i b;
+ __m128i a, d = zero;
+
+ while(rb > 4)
+ {
+ __m128i avg;
+ b = load4(prev);
+ a = d; d = load4(row );
+
+ /* PNG requires a truncating average, so we can't just use _mm_avg_epu8 */
+ avg = _mm_avg_epu8(a,b);
+ /* ...but we can fix it up by subtracting off 1 if it rounded up. */
+ avg = _mm_sub_epi8(avg, _mm_and_si128(_mm_xor_si128(a, b),
+ _mm_set1_epi8(1)));
+
+ d = _mm_add_epi8(d, avg);
+ store4(row, d);
+
+ prev += 4;
+ row += 4;
+ rb -= 4;
+ }
+}
+
+/* Returns |x| for 16-bit lanes. */
+#if (SPNG_SSE >= 3) && !defined(_MSC_VER)
+__attribute__((target("ssse3")))
+#endif
+static __m128i abs_i16(__m128i x)
+{
+#if SPNG_SSE >= 3
+ return _mm_abs_epi16(x);
+#else
+ /* Read this all as, return x<0 ? -x : x.
+ * To negate two's complement, you flip all the bits then add 1.
+ */
+ __m128i is_negative = _mm_cmplt_epi16(x, _mm_setzero_si128());
+
+ /* Flip negative lanes. */
+ x = _mm_xor_si128(x, is_negative);
+
+ /* +1 to negative lanes, else +0. */
+ x = _mm_sub_epi16(x, is_negative);
+ return x;
+#endif
+}
+
+/* Bytewise c ? t : e. */
+static __m128i if_then_else(__m128i c, __m128i t, __m128i e)
+{
+#if SPNG_SSE >= 4
+ return _mm_blendv_epi8(e, t, c);
+#else
+ return _mm_or_si128(_mm_and_si128(c, t), _mm_andnot_si128(c, e));
+#endif
+}
+
+static void defilter_paeth3(size_t rowbytes, unsigned char *row, const unsigned char *prev)
+{
+ /* Paeth tries to predict pixel d using the pixel to the left of it, a,
+ * and two pixels from the previous row, b and c:
+ * prev: c b
+ * row: a d
+ * The Paeth function predicts d to be whichever of a, b, or c is nearest to
+ * p=a+b-c.
+ *
+ * The first pixel has no left context, and so uses an Up filter, p = b.
+ * This works naturally with our main loop's p = a+b-c if we force a and c
+ * to zero.
+ * Here we zero b and d, which become c and a respectively at the start of
+ * the loop.
+ */
+ size_t rb = rowbytes;
+ const __m128i zero = _mm_setzero_si128();
+ __m128i c, b = zero,
+ a, d = zero;
+
+ while(rb >= 4)
+ {
+ /* It's easiest to do this math (particularly, deal with pc) with 16-bit
+ * intermediates.
+ */
+ __m128i pa,pb,pc,smallest,nearest;
+ c = b; b = _mm_unpacklo_epi8(load4(prev), zero);
+ a = d; d = _mm_unpacklo_epi8(load4(row ), zero);
+
+ /* (p-a) == (a+b-c - a) == (b-c) */
+
+ pa = _mm_sub_epi16(b, c);
+
+ /* (p-b) == (a+b-c - b) == (a-c) */
+ pb = _mm_sub_epi16(a, c);
+
+ /* (p-c) == (a+b-c - c) == (a+b-c-c) == (b-c)+(a-c) */
+ pc = _mm_add_epi16(pa, pb);
+
+ pa = abs_i16(pa); /* |p-a| */
+ pb = abs_i16(pb); /* |p-b| */
+ pc = abs_i16(pc); /* |p-c| */
+
+ smallest = _mm_min_epi16(pc, _mm_min_epi16(pa, pb));
+
+ /* Paeth breaks ties favoring a over b over c. */
+ nearest = if_then_else(_mm_cmpeq_epi16(smallest, pa), a,
+ if_then_else(_mm_cmpeq_epi16(smallest, pb), b, c));
+
+ /* Note `_epi8`: we need addition to wrap modulo 255. */
+ d = _mm_add_epi8(d, nearest);
+ store3(row, _mm_packus_epi16(d, d));
+
+ prev += 3;
+ row += 3;
+ rb -= 3;
+ }
+
+ if(rb > 0)
+ {
+ /* It's easiest to do this math (particularly, deal with pc) with 16-bit
+ * intermediates.
+ */
+ __m128i pa, pb, pc, smallest, nearest;
+ c = b; b = _mm_unpacklo_epi8(load3(prev), zero);
+ a = d; d = _mm_unpacklo_epi8(load3(row ), zero);
+
+ /* (p-a) == (a+b-c - a) == (b-c) */
+ pa = _mm_sub_epi16(b, c);
+
+ /* (p-b) == (a+b-c - b) == (a-c) */
+ pb = _mm_sub_epi16(a, c);
+
+ /* (p-c) == (a+b-c - c) == (a+b-c-c) == (b-c)+(a-c) */
+ pc = _mm_add_epi16(pa, pb);
+
+ pa = abs_i16(pa); /* |p-a| */
+ pb = abs_i16(pb); /* |p-b| */
+ pc = abs_i16(pc); /* |p-c| */
+
+ smallest = _mm_min_epi16(pc, _mm_min_epi16(pa, pb));
+
+ /* Paeth breaks ties favoring a over b over c. */
+ nearest = if_then_else(_mm_cmpeq_epi16(smallest, pa), a,
+ if_then_else(_mm_cmpeq_epi16(smallest, pb), b, c));
+
+ /* Note `_epi8`: we need addition to wrap modulo 255. */
+ d = _mm_add_epi8(d, nearest);
+ store3(row, _mm_packus_epi16(d, d));
+ }
+}
+
+static void defilter_paeth4(size_t rowbytes, unsigned char *row, const unsigned char *prev)
+{
+ /* Paeth tries to predict pixel d using the pixel to the left of it, a,
+ * and two pixels from the previous row, b and c:
+ * prev: c b
+ * row: a d
+ * The Paeth function predicts d to be whichever of a, b, or c is nearest to
+ * p=a+b-c.
+ *
+ * The first pixel has no left context, and so uses an Up filter, p = b.
+ * This works naturally with our main loop's p = a+b-c if we force a and c
+ * to zero.
+ * Here we zero b and d, which become c and a respectively at the start of
+ * the loop.
+ */
+ size_t rb = rowbytes+4;
+
+ const __m128i zero = _mm_setzero_si128();
+ __m128i pa, pb, pc, smallest, nearest;
+ __m128i c, b = zero,
+ a, d = zero;
+
+ while(rb > 4)
+ {
+ /* It's easiest to do this math (particularly, deal with pc) with 16-bit
+ * intermediates.
+ */
+ c = b; b = _mm_unpacklo_epi8(load4(prev), zero);
+ a = d; d = _mm_unpacklo_epi8(load4(row ), zero);
+
+ /* (p-a) == (a+b-c - a) == (b-c) */
+ pa = _mm_sub_epi16(b, c);
+
+ /* (p-b) == (a+b-c - b) == (a-c) */
+ pb = _mm_sub_epi16(a, c);
+
+ /* (p-c) == (a+b-c - c) == (a+b-c-c) == (b-c)+(a-c) */
+ pc = _mm_add_epi16(pa, pb);
+
+ pa = abs_i16(pa); /* |p-a| */
+ pb = abs_i16(pb); /* |p-b| */
+ pc = abs_i16(pc); /* |p-c| */
+
+ smallest = _mm_min_epi16(pc, _mm_min_epi16(pa, pb));
+
+ /* Paeth breaks ties favoring a over b over c. */
+ nearest = if_then_else(_mm_cmpeq_epi16(smallest, pa), a,
+ if_then_else(_mm_cmpeq_epi16(smallest, pb), b, c));
+
+ /* Note `_epi8`: we need addition to wrap modulo 255. */
+ d = _mm_add_epi8(d, nearest);
+ store4(row, _mm_packus_epi16(d, d));
+
+ prev += 4;
+ row += 4;
+ rb -= 4;
+ }
+}
+
+#endif /* SPNG_X86 */
+
+
+#if defined(SPNG_ARM)
+
+/* NEON optimised filter functions
+ * Derived from filter_neon_intrinsics.c
+ *
+ * Copyright (c) 2018 Cosmin Truta
+ * Copyright (c) 2014,2016 Glenn Randers-Pehrson
+ * Written by James Yu , October 2013.
+ * Based on filter_neon.S, written by Mans Rullgard, 2011.
+ *
+ * This code is derived from libpng source code.
+ * For conditions of distribution and use, see the disclaimer
+ * and license in this file.
+ */
+
+#define png_aligncast(type, value) ((void*)(value))
+#define png_aligncastconst(type, value) ((const void*)(value))
+
+/* libpng row pointers are not necessarily aligned to any particular boundary,
+ * however this code will only work with appropriate alignment. mips/mips_init.c
+ * checks for this (and will not compile unless it is done). This code uses
+ * variants of png_aligncast to avoid compiler warnings.
+ */
+#define png_ptr(type,pointer) png_aligncast(type *,pointer)
+#define png_ptrc(type,pointer) png_aligncastconst(const type *,pointer)
+
+/* The following relies on a variable 'temp_pointer' being declared with type
+ * 'type'. This is written this way just to hide the GCC strict aliasing
+ * warning; note that the code is safe because there never is an alias between
+ * the input and output pointers.
+ */
+#define png_ldr(type,pointer)\
+ (temp_pointer = png_ptr(type,pointer), *temp_pointer)
+
+
+#if defined(_MSC_VER) && !defined(__clang__) && defined(_M_ARM64)
+ #include
+#else
+ #include
+#endif
+
+static void defilter_sub3(size_t rowbytes, unsigned char *row)
+{
+ unsigned char *rp = row;
+ unsigned char *rp_stop = row + rowbytes;
+
+ uint8x16_t vtmp = vld1q_u8(rp);
+ uint8x8x2_t *vrpt = png_ptr(uint8x8x2_t, &vtmp);
+ uint8x8x2_t vrp = *vrpt;
+
+ uint8x8x4_t vdest;
+ vdest.val[3] = vdup_n_u8(0);
+
+ for (; rp < rp_stop;)
+ {
+ uint8x8_t vtmp1, vtmp2;
+ uint32x2_t *temp_pointer;
+
+ vtmp1 = vext_u8(vrp.val[0], vrp.val[1], 3);
+ vdest.val[0] = vadd_u8(vdest.val[3], vrp.val[0]);
+ vtmp2 = vext_u8(vrp.val[0], vrp.val[1], 6);
+ vdest.val[1] = vadd_u8(vdest.val[0], vtmp1);
+
+ vtmp1 = vext_u8(vrp.val[1], vrp.val[1], 1);
+ vdest.val[2] = vadd_u8(vdest.val[1], vtmp2);
+ vdest.val[3] = vadd_u8(vdest.val[2], vtmp1);
+
+ vtmp = vld1q_u8(rp + 12);
+ vrpt = png_ptr(uint8x8x2_t, &vtmp);
+ vrp = *vrpt;
+
+ vst1_lane_u32(png_ptr(uint32_t,rp), png_ldr(uint32x2_t,&vdest.val[0]), 0);
+ rp += 3;
+ vst1_lane_u32(png_ptr(uint32_t,rp), png_ldr(uint32x2_t,&vdest.val[1]), 0);
+ rp += 3;
+ vst1_lane_u32(png_ptr(uint32_t,rp), png_ldr(uint32x2_t,&vdest.val[2]), 0);
+ rp += 3;
+ vst1_lane_u32(png_ptr(uint32_t,rp), png_ldr(uint32x2_t,&vdest.val[3]), 0);
+ rp += 3;
+ }
+}
+
+static void defilter_sub4(size_t rowbytes, unsigned char *row)
+{
+ unsigned char *rp = row;
+ unsigned char *rp_stop = row + rowbytes;
+
+ uint8x8x4_t vdest;
+ vdest.val[3] = vdup_n_u8(0);
+
+ for (; rp < rp_stop; rp += 16)
+ {
+ uint32x2x4_t vtmp = vld4_u32(png_ptr(uint32_t,rp));
+ uint8x8x4_t *vrpt = png_ptr(uint8x8x4_t,&vtmp);
+ uint8x8x4_t vrp = *vrpt;
+ uint32x2x4_t *temp_pointer;
+ uint32x2x4_t vdest_val;
+
+ vdest.val[0] = vadd_u8(vdest.val[3], vrp.val[0]);
+ vdest.val[1] = vadd_u8(vdest.val[0], vrp.val[1]);
+ vdest.val[2] = vadd_u8(vdest.val[1], vrp.val[2]);
+ vdest.val[3] = vadd_u8(vdest.val[2], vrp.val[3]);
+
+ vdest_val = png_ldr(uint32x2x4_t, &vdest);
+ vst4_lane_u32(png_ptr(uint32_t,rp), vdest_val, 0);
+ }
+}
+
+static void defilter_avg3(size_t rowbytes, unsigned char *row, const unsigned char *prev_row)
+{
+ unsigned char *rp = row;
+ const unsigned char *pp = prev_row;
+ unsigned char *rp_stop = row + rowbytes;
+
+ uint8x16_t vtmp;
+ uint8x8x2_t *vrpt;
+ uint8x8x2_t vrp;
+ uint8x8x4_t vdest;
+ vdest.val[3] = vdup_n_u8(0);
+
+ vtmp = vld1q_u8(rp);
+ vrpt = png_ptr(uint8x8x2_t,&vtmp);
+ vrp = *vrpt;
+
+ for (; rp < rp_stop; pp += 12)
+ {
+ uint8x8_t vtmp1, vtmp2, vtmp3;
+
+ uint8x8x2_t *vppt;
+ uint8x8x2_t vpp;
+
+ uint32x2_t *temp_pointer;
+
+ vtmp = vld1q_u8(pp);
+ vppt = png_ptr(uint8x8x2_t,&vtmp);
+ vpp = *vppt;
+
+ vtmp1 = vext_u8(vrp.val[0], vrp.val[1], 3);
+ vdest.val[0] = vhadd_u8(vdest.val[3], vpp.val[0]);
+ vdest.val[0] = vadd_u8(vdest.val[0], vrp.val[0]);
+
+ vtmp2 = vext_u8(vpp.val[0], vpp.val[1], 3);
+ vtmp3 = vext_u8(vrp.val[0], vrp.val[1], 6);
+ vdest.val[1] = vhadd_u8(vdest.val[0], vtmp2);
+ vdest.val[1] = vadd_u8(vdest.val[1], vtmp1);
+
+ vtmp2 = vext_u8(vpp.val[0], vpp.val[1], 6);
+ vtmp1 = vext_u8(vrp.val[1], vrp.val[1], 1);
+
+ vtmp = vld1q_u8(rp + 12);
+ vrpt = png_ptr(uint8x8x2_t,&vtmp);
+ vrp = *vrpt;
+
+ vdest.val[2] = vhadd_u8(vdest.val[1], vtmp2);
+ vdest.val[2] = vadd_u8(vdest.val[2], vtmp3);
+
+ vtmp2 = vext_u8(vpp.val[1], vpp.val[1], 1);
+
+ vdest.val[3] = vhadd_u8(vdest.val[2], vtmp2);
+ vdest.val[3] = vadd_u8(vdest.val[3], vtmp1);
+
+ vst1_lane_u32(png_ptr(uint32_t,rp), png_ldr(uint32x2_t,&vdest.val[0]), 0);
+ rp += 3;
+ vst1_lane_u32(png_ptr(uint32_t,rp), png_ldr(uint32x2_t,&vdest.val[1]), 0);
+ rp += 3;
+ vst1_lane_u32(png_ptr(uint32_t,rp), png_ldr(uint32x2_t,&vdest.val[2]), 0);
+ rp += 3;
+ vst1_lane_u32(png_ptr(uint32_t,rp), png_ldr(uint32x2_t,&vdest.val[3]), 0);
+ rp += 3;
+ }
+}
+
+static void defilter_avg4(size_t rowbytes, unsigned char *row, const unsigned char *prev_row)
+{
+ unsigned char *rp = row;
+ unsigned char *rp_stop = row + rowbytes;
+ const unsigned char *pp = prev_row;
+
+ uint8x8x4_t vdest;
+ vdest.val[3] = vdup_n_u8(0);
+
+ for (; rp < rp_stop; rp += 16, pp += 16)
+ {
+ uint32x2x4_t vtmp;
+ uint8x8x4_t *vrpt, *vppt;
+ uint8x8x4_t vrp, vpp;
+ uint32x2x4_t *temp_pointer;
+ uint32x2x4_t vdest_val;
+
+ vtmp = vld4_u32(png_ptr(uint32_t,rp));
+ vrpt = png_ptr(uint8x8x4_t,&vtmp);
+ vrp = *vrpt;
+ vtmp = vld4_u32(png_ptrc(uint32_t,pp));
+ vppt = png_ptr(uint8x8x4_t,&vtmp);
+ vpp = *vppt;
+
+ vdest.val[0] = vhadd_u8(vdest.val[3], vpp.val[0]);
+ vdest.val[0] = vadd_u8(vdest.val[0], vrp.val[0]);
+ vdest.val[1] = vhadd_u8(vdest.val[0], vpp.val[1]);
+ vdest.val[1] = vadd_u8(vdest.val[1], vrp.val[1]);
+ vdest.val[2] = vhadd_u8(vdest.val[1], vpp.val[2]);
+ vdest.val[2] = vadd_u8(vdest.val[2], vrp.val[2]);
+ vdest.val[3] = vhadd_u8(vdest.val[2], vpp.val[3]);
+ vdest.val[3] = vadd_u8(vdest.val[3], vrp.val[3]);
+
+ vdest_val = png_ldr(uint32x2x4_t, &vdest);
+ vst4_lane_u32(png_ptr(uint32_t,rp), vdest_val, 0);
+ }
+}
+
+static uint8x8_t paeth_arm(uint8x8_t a, uint8x8_t b, uint8x8_t c)
+{
+ uint8x8_t d, e;
+ uint16x8_t p1, pa, pb, pc;
+
+ p1 = vaddl_u8(a, b); /* a + b */
+ pc = vaddl_u8(c, c); /* c * 2 */
+ pa = vabdl_u8(b, c); /* pa */
+ pb = vabdl_u8(a, c); /* pb */
+ pc = vabdq_u16(p1, pc); /* pc */
+
+ p1 = vcleq_u16(pa, pb); /* pa <= pb */
+ pa = vcleq_u16(pa, pc); /* pa <= pc */
+ pb = vcleq_u16(pb, pc); /* pb <= pc */
+
+ p1 = vandq_u16(p1, pa); /* pa <= pb && pa <= pc */
+
+ d = vmovn_u16(pb);
+ e = vmovn_u16(p1);
+
+ d = vbsl_u8(d, b, c);
+ e = vbsl_u8(e, a, d);
+
+ return e;
+}
+
+static void defilter_paeth3(size_t rowbytes, unsigned char *row, const unsigned char *prev_row)
+{
+ unsigned char *rp = row;
+ const unsigned char *pp = prev_row;
+ unsigned char *rp_stop = row + rowbytes;
+
+ uint8x16_t vtmp;
+ uint8x8x2_t *vrpt;
+ uint8x8x2_t vrp;
+ uint8x8_t vlast = vdup_n_u8(0);
+ uint8x8x4_t vdest;
+ vdest.val[3] = vdup_n_u8(0);
+
+ vtmp = vld1q_u8(rp);
+ vrpt = png_ptr(uint8x8x2_t,&vtmp);
+ vrp = *vrpt;
+
+ for (; rp < rp_stop; pp += 12)
+ {
+ uint8x8x2_t *vppt;
+ uint8x8x2_t vpp;
+ uint8x8_t vtmp1, vtmp2, vtmp3;
+ uint32x2_t *temp_pointer;
+
+ vtmp = vld1q_u8(pp);
+ vppt = png_ptr(uint8x8x2_t,&vtmp);
+ vpp = *vppt;
+
+ vdest.val[0] = paeth_arm(vdest.val[3], vpp.val[0], vlast);
+ vdest.val[0] = vadd_u8(vdest.val[0], vrp.val[0]);
+
+ vtmp1 = vext_u8(vrp.val[0], vrp.val[1], 3);
+ vtmp2 = vext_u8(vpp.val[0], vpp.val[1], 3);
+ vdest.val[1] = paeth_arm(vdest.val[0], vtmp2, vpp.val[0]);
+ vdest.val[1] = vadd_u8(vdest.val[1], vtmp1);
+
+ vtmp1 = vext_u8(vrp.val[0], vrp.val[1], 6);
+ vtmp3 = vext_u8(vpp.val[0], vpp.val[1], 6);
+ vdest.val[2] = paeth_arm(vdest.val[1], vtmp3, vtmp2);
+ vdest.val[2] = vadd_u8(vdest.val[2], vtmp1);
+
+ vtmp1 = vext_u8(vrp.val[1], vrp.val[1], 1);
+ vtmp2 = vext_u8(vpp.val[1], vpp.val[1], 1);
+
+ vtmp = vld1q_u8(rp + 12);
+ vrpt = png_ptr(uint8x8x2_t,&vtmp);
+ vrp = *vrpt;
+
+ vdest.val[3] = paeth_arm(vdest.val[2], vtmp2, vtmp3);
+ vdest.val[3] = vadd_u8(vdest.val[3], vtmp1);
+
+ vlast = vtmp2;
+
+ vst1_lane_u32(png_ptr(uint32_t,rp), png_ldr(uint32x2_t,&vdest.val[0]), 0);
+ rp += 3;
+ vst1_lane_u32(png_ptr(uint32_t,rp), png_ldr(uint32x2_t,&vdest.val[1]), 0);
+ rp += 3;
+ vst1_lane_u32(png_ptr(uint32_t,rp), png_ldr(uint32x2_t,&vdest.val[2]), 0);
+ rp += 3;
+ vst1_lane_u32(png_ptr(uint32_t,rp), png_ldr(uint32x2_t,&vdest.val[3]), 0);
+ rp += 3;
+ }
+}
+
+static void defilter_paeth4(size_t rowbytes, unsigned char *row, const unsigned char *prev_row)
+{
+ unsigned char *rp = row;
+ unsigned char *rp_stop = row + rowbytes;
+ const unsigned char *pp = prev_row;
+
+ uint8x8_t vlast = vdup_n_u8(0);
+ uint8x8x4_t vdest;
+ vdest.val[3] = vdup_n_u8(0);
+
+ for (; rp < rp_stop; rp += 16, pp += 16)
+ {
+ uint32x2x4_t vtmp;
+ uint8x8x4_t *vrpt, *vppt;
+ uint8x8x4_t vrp, vpp;
+ uint32x2x4_t *temp_pointer;
+ uint32x2x4_t vdest_val;
+
+ vtmp = vld4_u32(png_ptr(uint32_t,rp));
+ vrpt = png_ptr(uint8x8x4_t,&vtmp);
+ vrp = *vrpt;
+ vtmp = vld4_u32(png_ptrc(uint32_t,pp));
+ vppt = png_ptr(uint8x8x4_t,&vtmp);
+ vpp = *vppt;
+
+ vdest.val[0] = paeth_arm(vdest.val[3], vpp.val[0], vlast);
+ vdest.val[0] = vadd_u8(vdest.val[0], vrp.val[0]);
+ vdest.val[1] = paeth_arm(vdest.val[0], vpp.val[1], vpp.val[0]);
+ vdest.val[1] = vadd_u8(vdest.val[1], vrp.val[1]);
+ vdest.val[2] = paeth_arm(vdest.val[1], vpp.val[2], vpp.val[1]);
+ vdest.val[2] = vadd_u8(vdest.val[2], vrp.val[2]);
+ vdest.val[3] = paeth_arm(vdest.val[2], vpp.val[3], vpp.val[2]);
+ vdest.val[3] = vadd_u8(vdest.val[3], vrp.val[3]);
+
+ vlast = vpp.val[3];
+
+ vdest_val = png_ldr(uint32x2x4_t, &vdest);
+ vst4_lane_u32(png_ptr(uint32_t,rp), vdest_val, 0);
+ }
+}
+
+/* NEON optimised palette expansion functions
+ * Derived from palette_neon_intrinsics.c
+ *
+ * Copyright (c) 2018-2019 Cosmin Truta
+ * Copyright (c) 2017-2018 Arm Holdings. All rights reserved.
+ * Written by Richard Townsend , February 2017.
+ *
+ * This code is derived from libpng source code.
+ * For conditions of distribution and use, see the disclaimer
+ * and license in this file.
+ *
+ * Related: https://developer.arm.com/documentation/101964/latest/Color-palette-expansion
+ *
+ * The functions were refactored to iterate forward.
+ *
+ */
+
+/* Expands a palettized row into RGBA8. */
+static uint32_t expand_palette_rgba8_neon(unsigned char *row, const unsigned char *scanline, const unsigned char *plte, uint32_t width)
+{
+ const uint32_t scanline_stride = 4;
+ const uint32_t row_stride = scanline_stride * 4;
+ const uint32_t count = width / scanline_stride;
+ const uint32_t *palette = (const uint32_t*)plte;
+
+ if(!count) return 0;
+
+ uint32_t i;
+ uint32x4_t cur;
+ for(i=0; i < count; i++, scanline += scanline_stride)
+ {
+ cur = vld1q_dup_u32 (palette + scanline[0]);
+ cur = vld1q_lane_u32(palette + scanline[1], cur, 1);
+ cur = vld1q_lane_u32(palette + scanline[2], cur, 2);
+ cur = vld1q_lane_u32(palette + scanline[3], cur, 3);
+ vst1q_u32((uint32_t*)(row + i * row_stride), cur);
+ }
+
+ return count * scanline_stride;
+}
+
+/* Expands a palettized row into RGB8. */
+static uint32_t expand_palette_rgb8_neon(unsigned char *row, const unsigned char *scanline, const unsigned char *plte, uint32_t width)
+{
+ const uint32_t scanline_stride = 8;
+ const uint32_t row_stride = scanline_stride * 3;
+ const uint32_t count = width / scanline_stride;
+
+ if(!count) return 0;
+
+ uint32_t i;
+ uint8x8x3_t cur;
+ for(i=0; i < count; i++, scanline += scanline_stride)
+ {
+ cur = vld3_dup_u8 (plte + 3 * scanline[0]);
+ cur = vld3_lane_u8(plte + 3 * scanline[1], cur, 1);
+ cur = vld3_lane_u8(plte + 3 * scanline[2], cur, 2);
+ cur = vld3_lane_u8(plte + 3 * scanline[3], cur, 3);
+ cur = vld3_lane_u8(plte + 3 * scanline[4], cur, 4);
+ cur = vld3_lane_u8(plte + 3 * scanline[5], cur, 5);
+ cur = vld3_lane_u8(plte + 3 * scanline[6], cur, 6);
+ cur = vld3_lane_u8(plte + 3 * scanline[7], cur, 7);
+ vst3_u8(row + i * row_stride, cur);
+ }
+
+ return count * scanline_stride;
+}
+
+#endif /* SPNG_ARM */
diff --git a/tools/assets/n64texconv/lib/spng/spng.h b/tools/assets/n64texconv/lib/spng/spng.h
new file mode 100644
index 000000000..8f946337b
--- /dev/null
+++ b/tools/assets/n64texconv/lib/spng/spng.h
@@ -0,0 +1,537 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+#ifndef SPNG_H
+#define SPNG_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if (defined(_WIN32) || defined(__CYGWIN__)) && !defined(SPNG_STATIC)
+ #if defined(SPNG__BUILD)
+ #define SPNG_API __declspec(dllexport)
+ #else
+ #define SPNG_API __declspec(dllimport)
+ #endif
+#else
+ #define SPNG_API
+#endif
+
+#if defined(_MSC_VER)
+ #define SPNG_CDECL __cdecl
+#else
+ #define SPNG_CDECL
+#endif
+
+#include
+#include
+#include
+
+#define SPNG_VERSION_MAJOR 0
+#define SPNG_VERSION_MINOR 7
+#define SPNG_VERSION_PATCH 4
+
+enum spng_errno
+{
+ SPNG_IO_ERROR = -2,
+ SPNG_IO_EOF = -1,
+ SPNG_OK = 0,
+ SPNG_EINVAL,
+ SPNG_EMEM,
+ SPNG_EOVERFLOW,
+ SPNG_ESIGNATURE,
+ SPNG_EWIDTH,
+ SPNG_EHEIGHT,
+ SPNG_EUSER_WIDTH,
+ SPNG_EUSER_HEIGHT,
+ SPNG_EBIT_DEPTH,
+ SPNG_ECOLOR_TYPE,
+ SPNG_ECOMPRESSION_METHOD,
+ SPNG_EFILTER_METHOD,
+ SPNG_EINTERLACE_METHOD,
+ SPNG_EIHDR_SIZE,
+ SPNG_ENOIHDR,
+ SPNG_ECHUNK_POS,
+ SPNG_ECHUNK_SIZE,
+ SPNG_ECHUNK_CRC,
+ SPNG_ECHUNK_TYPE,
+ SPNG_ECHUNK_UNKNOWN_CRITICAL,
+ SPNG_EDUP_PLTE,
+ SPNG_EDUP_CHRM,
+ SPNG_EDUP_GAMA,
+ SPNG_EDUP_ICCP,
+ SPNG_EDUP_SBIT,
+ SPNG_EDUP_SRGB,
+ SPNG_EDUP_BKGD,
+ SPNG_EDUP_HIST,
+ SPNG_EDUP_TRNS,
+ SPNG_EDUP_PHYS,
+ SPNG_EDUP_TIME,
+ SPNG_EDUP_OFFS,
+ SPNG_EDUP_EXIF,
+ SPNG_ECHRM,
+ SPNG_EPLTE_IDX,
+ SPNG_ETRNS_COLOR_TYPE,
+ SPNG_ETRNS_NO_PLTE,
+ SPNG_EGAMA,
+ SPNG_EICCP_NAME,
+ SPNG_EICCP_COMPRESSION_METHOD,
+ SPNG_ESBIT,
+ SPNG_ESRGB,
+ SPNG_ETEXT,
+ SPNG_ETEXT_KEYWORD,
+ SPNG_EZTXT,
+ SPNG_EZTXT_COMPRESSION_METHOD,
+ SPNG_EITXT,
+ SPNG_EITXT_COMPRESSION_FLAG,
+ SPNG_EITXT_COMPRESSION_METHOD,
+ SPNG_EITXT_LANG_TAG,
+ SPNG_EITXT_TRANSLATED_KEY,
+ SPNG_EBKGD_NO_PLTE,
+ SPNG_EBKGD_PLTE_IDX,
+ SPNG_EHIST_NO_PLTE,
+ SPNG_EPHYS,
+ SPNG_ESPLT_NAME,
+ SPNG_ESPLT_DUP_NAME,
+ SPNG_ESPLT_DEPTH,
+ SPNG_ETIME,
+ SPNG_EOFFS,
+ SPNG_EEXIF,
+ SPNG_EIDAT_TOO_SHORT,
+ SPNG_EIDAT_STREAM,
+ SPNG_EZLIB,
+ SPNG_EFILTER,
+ SPNG_EBUFSIZ,
+ SPNG_EIO,
+ SPNG_EOF,
+ SPNG_EBUF_SET,
+ SPNG_EBADSTATE,
+ SPNG_EFMT,
+ SPNG_EFLAGS,
+ SPNG_ECHUNKAVAIL,
+ SPNG_ENCODE_ONLY,
+ SPNG_EOI,
+ SPNG_ENOPLTE,
+ SPNG_ECHUNK_LIMITS,
+ SPNG_EZLIB_INIT,
+ SPNG_ECHUNK_STDLEN,
+ SPNG_EINTERNAL,
+ SPNG_ECTXTYPE,
+ SPNG_ENOSRC,
+ SPNG_ENODST,
+ SPNG_EOPSTATE,
+ SPNG_ENOTFINAL,
+};
+
+enum spng_text_type
+{
+ SPNG_TEXT = 1,
+ SPNG_ZTXT = 2,
+ SPNG_ITXT = 3
+};
+
+enum spng_color_type
+{
+ SPNG_COLOR_TYPE_GRAYSCALE = 0,
+ SPNG_COLOR_TYPE_TRUECOLOR = 2,
+ SPNG_COLOR_TYPE_INDEXED = 3,
+ SPNG_COLOR_TYPE_GRAYSCALE_ALPHA = 4,
+ SPNG_COLOR_TYPE_TRUECOLOR_ALPHA = 6
+};
+
+enum spng_filter
+{
+ SPNG_FILTER_NONE = 0,
+ SPNG_FILTER_SUB = 1,
+ SPNG_FILTER_UP = 2,
+ SPNG_FILTER_AVERAGE = 3,
+ SPNG_FILTER_PAETH = 4
+};
+
+enum spng_filter_choice
+{
+ SPNG_DISABLE_FILTERING = 0,
+ SPNG_FILTER_CHOICE_NONE = 8,
+ SPNG_FILTER_CHOICE_SUB = 16,
+ SPNG_FILTER_CHOICE_UP = 32,
+ SPNG_FILTER_CHOICE_AVG = 64,
+ SPNG_FILTER_CHOICE_PAETH = 128,
+ SPNG_FILTER_CHOICE_ALL = (8|16|32|64|128)
+};
+
+enum spng_interlace_method
+{
+ SPNG_INTERLACE_NONE = 0,
+ SPNG_INTERLACE_ADAM7 = 1
+};
+
+/* Channels are always in byte-order */
+enum spng_format
+{
+ SPNG_FMT_RGBA8 = 1,
+ SPNG_FMT_RGBA16 = 2,
+ SPNG_FMT_RGB8 = 4,
+
+ /* Partially implemented, see documentation */
+ SPNG_FMT_GA8 = 16,
+ SPNG_FMT_GA16 = 32,
+ SPNG_FMT_G8 = 64,
+
+ /* No conversion or scaling */
+ SPNG_FMT_PNG = 256,
+ SPNG_FMT_RAW = 512 /* big-endian (everything else is host-endian) */
+};
+
+enum spng_ctx_flags
+{
+ SPNG_CTX_IGNORE_ADLER32 = 1, /* Ignore checksum in DEFLATE streams */
+ SPNG_CTX_ENCODER = 2 /* Create an encoder context */
+};
+
+enum spng_decode_flags
+{
+ SPNG_DECODE_USE_TRNS = 1, /* Deprecated */
+ SPNG_DECODE_USE_GAMA = 2, /* Deprecated */
+ SPNG_DECODE_USE_SBIT = 8, /* Undocumented */
+
+ SPNG_DECODE_TRNS = 1, /* Apply transparency */
+ SPNG_DECODE_GAMMA = 2, /* Apply gamma correction */
+ SPNG_DECODE_PROGRESSIVE = 256 /* Initialize for progressive reads */
+};
+
+enum spng_crc_action
+{
+ /* Default for critical chunks */
+ SPNG_CRC_ERROR = 0,
+
+ /* Discard chunk, invalid for critical chunks.
+ Since v0.6.2: default for ancillary chunks */
+ SPNG_CRC_DISCARD = 1,
+
+ /* Ignore and don't calculate checksum.
+ Since v0.6.2: also ignores checksums in DEFLATE streams */
+ SPNG_CRC_USE = 2
+};
+
+enum spng_encode_flags
+{
+ SPNG_ENCODE_PROGRESSIVE = 1, /* Initialize for progressive writes */
+ SPNG_ENCODE_FINALIZE = 2, /* Finalize PNG after encoding image */
+};
+
+struct spng_ihdr
+{
+ uint32_t width;
+ uint32_t height;
+ uint8_t bit_depth;
+ uint8_t color_type;
+ uint8_t compression_method;
+ uint8_t filter_method;
+ uint8_t interlace_method;
+};
+
+struct spng_plte_entry
+{
+ uint8_t red;
+ uint8_t green;
+ uint8_t blue;
+
+ uint8_t alpha; /* Reserved for internal use */
+};
+
+struct spng_plte
+{
+ uint32_t n_entries;
+ struct spng_plte_entry entries[256];
+};
+
+struct spng_trns
+{
+ uint16_t gray;
+
+ uint16_t red;
+ uint16_t green;
+ uint16_t blue;
+
+ uint32_t n_type3_entries;
+ uint8_t type3_alpha[256];
+};
+
+struct spng_chrm_int
+{
+ uint32_t white_point_x;
+ uint32_t white_point_y;
+ uint32_t red_x;
+ uint32_t red_y;
+ uint32_t green_x;
+ uint32_t green_y;
+ uint32_t blue_x;
+ uint32_t blue_y;
+};
+
+struct spng_chrm
+{
+ double white_point_x;
+ double white_point_y;
+ double red_x;
+ double red_y;
+ double green_x;
+ double green_y;
+ double blue_x;
+ double blue_y;
+};
+
+struct spng_iccp
+{
+ char profile_name[80];
+ size_t profile_len;
+ char *profile;
+};
+
+struct spng_sbit
+{
+ uint8_t grayscale_bits;
+ uint8_t red_bits;
+ uint8_t green_bits;
+ uint8_t blue_bits;
+ uint8_t alpha_bits;
+};
+
+struct spng_text
+{
+ char keyword[80];
+ int type;
+
+ size_t length;
+ char *text;
+
+ uint8_t compression_flag; /* iTXt only */
+ uint8_t compression_method; /* iTXt, ztXt only */
+ char *language_tag; /* iTXt only */
+ char *translated_keyword; /* iTXt only */
+};
+
+struct spng_bkgd
+{
+ uint16_t gray; /* Only for gray/gray alpha */
+ uint16_t red;
+ uint16_t green;
+ uint16_t blue;
+ uint16_t plte_index; /* Only for indexed color */
+};
+
+struct spng_hist
+{
+ uint16_t frequency[256];
+};
+
+struct spng_phys
+{
+ uint32_t ppu_x, ppu_y;
+ uint8_t unit_specifier;
+};
+
+struct spng_splt_entry
+{
+ uint16_t red;
+ uint16_t green;
+ uint16_t blue;
+ uint16_t alpha;
+ uint16_t frequency;
+};
+
+struct spng_splt
+{
+ char name[80];
+ uint8_t sample_depth;
+ uint32_t n_entries;
+ struct spng_splt_entry *entries;
+};
+
+struct spng_time
+{
+ uint16_t year;
+ uint8_t month;
+ uint8_t day;
+ uint8_t hour;
+ uint8_t minute;
+ uint8_t second;
+};
+
+struct spng_offs
+{
+ int32_t x, y;
+ uint8_t unit_specifier;
+};
+
+struct spng_exif
+{
+ size_t length;
+ char *data;
+};
+
+struct spng_chunk
+{
+ size_t offset;
+ uint32_t length;
+ uint8_t type[4];
+ uint32_t crc;
+};
+
+enum spng_location
+{
+ SPNG_AFTER_IHDR = 1,
+ SPNG_AFTER_PLTE = 2,
+ SPNG_AFTER_IDAT = 8,
+};
+
+struct spng_unknown_chunk
+{
+ uint8_t type[4];
+ size_t length;
+ void *data;
+ enum spng_location location;
+};
+
+enum spng_option
+{
+ SPNG_KEEP_UNKNOWN_CHUNKS = 1,
+
+ SPNG_IMG_COMPRESSION_LEVEL,
+ SPNG_IMG_WINDOW_BITS,
+ SPNG_IMG_MEM_LEVEL,
+ SPNG_IMG_COMPRESSION_STRATEGY,
+
+ SPNG_TEXT_COMPRESSION_LEVEL,
+ SPNG_TEXT_WINDOW_BITS,
+ SPNG_TEXT_MEM_LEVEL,
+ SPNG_TEXT_COMPRESSION_STRATEGY,
+
+ SPNG_FILTER_CHOICE,
+ SPNG_CHUNK_COUNT_LIMIT,
+ SPNG_ENCODE_TO_BUFFER,
+};
+
+typedef void* SPNG_CDECL spng_malloc_fn(size_t size);
+typedef void* SPNG_CDECL spng_realloc_fn(void* ptr, size_t size);
+typedef void* SPNG_CDECL spng_calloc_fn(size_t count, size_t size);
+typedef void SPNG_CDECL spng_free_fn(void* ptr);
+
+struct spng_alloc
+{
+ spng_malloc_fn *malloc_fn;
+ spng_realloc_fn *realloc_fn;
+ spng_calloc_fn *calloc_fn;
+ spng_free_fn *free_fn;
+};
+
+struct spng_row_info
+{
+ uint32_t scanline_idx;
+ uint32_t row_num; /* deinterlaced row index */
+ int pass;
+ uint8_t filter;
+};
+
+typedef struct spng_ctx spng_ctx;
+
+typedef int spng_read_fn(spng_ctx *ctx, void *user, void *dest, size_t length);
+typedef int spng_write_fn(spng_ctx *ctx, void *user, void *src, size_t length);
+
+typedef int spng_rw_fn(spng_ctx *ctx, void *user, void *dst_src, size_t length);
+
+SPNG_API spng_ctx *spng_ctx_new(int flags);
+SPNG_API spng_ctx *spng_ctx_new2(struct spng_alloc *alloc, int flags);
+SPNG_API void spng_ctx_free(spng_ctx *ctx);
+
+SPNG_API int spng_set_png_buffer(spng_ctx *ctx, const void *buf, size_t size);
+SPNG_API int spng_set_png_stream(spng_ctx *ctx, spng_rw_fn *rw_func, void *user);
+SPNG_API int spng_set_png_file(spng_ctx *ctx, FILE *file);
+
+SPNG_API void *spng_get_png_buffer(spng_ctx *ctx, size_t *len, int *error);
+
+SPNG_API int spng_set_image_limits(spng_ctx *ctx, uint32_t width, uint32_t height);
+SPNG_API int spng_get_image_limits(spng_ctx *ctx, uint32_t *width, uint32_t *height);
+
+SPNG_API int spng_set_chunk_limits(spng_ctx *ctx, size_t chunk_size, size_t cache_size);
+SPNG_API int spng_get_chunk_limits(spng_ctx *ctx, size_t *chunk_size, size_t *cache_size);
+
+SPNG_API int spng_set_crc_action(spng_ctx *ctx, int critical, int ancillary);
+
+SPNG_API int spng_set_option(spng_ctx *ctx, enum spng_option option, int value);
+SPNG_API int spng_get_option(spng_ctx *ctx, enum spng_option option, int *value);
+
+SPNG_API int spng_decoded_image_size(spng_ctx *ctx, int fmt, size_t *len);
+
+/* Decode */
+SPNG_API int spng_decode_image(spng_ctx *ctx, void *out, size_t len, int fmt, int flags);
+
+/* Progressive decode */
+SPNG_API int spng_decode_scanline(spng_ctx *ctx, void *out, size_t len);
+SPNG_API int spng_decode_row(spng_ctx *ctx, void *out, size_t len);
+SPNG_API int spng_decode_chunks(spng_ctx *ctx);
+
+/* Encode/decode */
+SPNG_API int spng_get_row_info(spng_ctx *ctx, struct spng_row_info *row_info);
+
+/* Encode */
+SPNG_API int spng_encode_image(spng_ctx *ctx, const void *img, size_t len, int fmt, int flags);
+
+/* Progressive encode */
+SPNG_API int spng_encode_scanline(spng_ctx *ctx, const void *scanline, size_t len);
+SPNG_API int spng_encode_row(spng_ctx *ctx, const void *row, size_t len);
+SPNG_API int spng_encode_chunks(spng_ctx *ctx);
+
+SPNG_API int spng_get_ihdr(spng_ctx *ctx, struct spng_ihdr *ihdr);
+SPNG_API int spng_get_plte(spng_ctx *ctx, struct spng_plte *plte);
+SPNG_API int spng_get_trns(spng_ctx *ctx, struct spng_trns *trns);
+SPNG_API int spng_get_chrm(spng_ctx *ctx, struct spng_chrm *chrm);
+SPNG_API int spng_get_chrm_int(spng_ctx *ctx, struct spng_chrm_int *chrm_int);
+SPNG_API int spng_get_gama(spng_ctx *ctx, double *gamma);
+SPNG_API int spng_get_gama_int(spng_ctx *ctx, uint32_t *gama_int);
+SPNG_API int spng_get_iccp(spng_ctx *ctx, struct spng_iccp *iccp);
+SPNG_API int spng_get_sbit(spng_ctx *ctx, struct spng_sbit *sbit);
+SPNG_API int spng_get_srgb(spng_ctx *ctx, uint8_t *rendering_intent);
+SPNG_API int spng_get_text(spng_ctx *ctx, struct spng_text *text, uint32_t *n_text);
+SPNG_API int spng_get_bkgd(spng_ctx *ctx, struct spng_bkgd *bkgd);
+SPNG_API int spng_get_hist(spng_ctx *ctx, struct spng_hist *hist);
+SPNG_API int spng_get_phys(spng_ctx *ctx, struct spng_phys *phys);
+SPNG_API int spng_get_splt(spng_ctx *ctx, struct spng_splt *splt, uint32_t *n_splt);
+SPNG_API int spng_get_time(spng_ctx *ctx, struct spng_time *time);
+SPNG_API int spng_get_unknown_chunks(spng_ctx *ctx, struct spng_unknown_chunk *chunks, uint32_t *n_chunks);
+
+/* Official extensions */
+SPNG_API int spng_get_offs(spng_ctx *ctx, struct spng_offs *offs);
+SPNG_API int spng_get_exif(spng_ctx *ctx, struct spng_exif *exif);
+
+
+SPNG_API int spng_set_ihdr(spng_ctx *ctx, struct spng_ihdr *ihdr);
+SPNG_API int spng_set_plte(spng_ctx *ctx, struct spng_plte *plte);
+SPNG_API int spng_set_trns(spng_ctx *ctx, struct spng_trns *trns);
+SPNG_API int spng_set_chrm(spng_ctx *ctx, struct spng_chrm *chrm);
+SPNG_API int spng_set_chrm_int(spng_ctx *ctx, struct spng_chrm_int *chrm_int);
+SPNG_API int spng_set_gama(spng_ctx *ctx, double gamma);
+SPNG_API int spng_set_gama_int(spng_ctx *ctx, uint32_t gamma);
+SPNG_API int spng_set_iccp(spng_ctx *ctx, struct spng_iccp *iccp);
+SPNG_API int spng_set_sbit(spng_ctx *ctx, struct spng_sbit *sbit);
+SPNG_API int spng_set_srgb(spng_ctx *ctx, uint8_t rendering_intent);
+SPNG_API int spng_set_text(spng_ctx *ctx, struct spng_text *text, uint32_t n_text);
+SPNG_API int spng_set_bkgd(spng_ctx *ctx, struct spng_bkgd *bkgd);
+SPNG_API int spng_set_hist(spng_ctx *ctx, struct spng_hist *hist);
+SPNG_API int spng_set_phys(spng_ctx *ctx, struct spng_phys *phys);
+SPNG_API int spng_set_splt(spng_ctx *ctx, struct spng_splt *splt, uint32_t n_splt);
+SPNG_API int spng_set_time(spng_ctx *ctx, struct spng_time *time);
+SPNG_API int spng_set_unknown_chunks(spng_ctx *ctx, struct spng_unknown_chunk *chunks, uint32_t n_chunks);
+
+/* Official extensions */
+SPNG_API int spng_set_offs(spng_ctx *ctx, struct spng_offs *offs);
+SPNG_API int spng_set_exif(spng_ctx *ctx, struct spng_exif *exif);
+
+
+SPNG_API const char *spng_strerror(int err);
+SPNG_API const char *spng_version_string(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* SPNG_H */
diff --git a/tools/assets/n64texconv/src/LICENSE b/tools/assets/n64texconv/src/LICENSE
new file mode 100644
index 000000000..3c68e6a95
--- /dev/null
+++ b/tools/assets/n64texconv/src/LICENSE
@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2025 ZeldaRET
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
diff --git a/tools/assets/n64texconv/src/app/main.c b/tools/assets/n64texconv/src/app/main.c
new file mode 100644
index 000000000..9829c512c
--- /dev/null
+++ b/tools/assets/n64texconv/src/app/main.c
@@ -0,0 +1,137 @@
+/* SPDX-FileCopyrightText: Copyright (C) 2025 ZeldaRET */
+/* SPDX-License-Identifier: MIT */
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#define NORETURN __attribute__((noreturn))
+#define ARRLEN(a) (sizeof(a) / sizeof((a)[0]))
+#define strequ(s1, s2) (strcmp((s1), (s2)) == 0)
+
+#include "../libn64texconv/n64texconv.h"
+#include "../libn64texconv/jfif.h"
+
+static bool
+is_regular_file(const char *path)
+{
+ struct stat sb;
+ stat(path, &sb);
+ return S_ISREG(sb.st_mode);
+}
+
+static NORETURN void
+usage(const char *progname)
+{
+ fprintf(stderr,
+ "n64texconv: Convert an input png to N64 data in the desired format.\n"
+ "Usage: %s [pal_out.c]\n"
+ " Valid types: i4 / i8 / ci4 / ci8 / ia4 / ia8 / ia16 / rgba16 / rgba32 / JFIF\n",
+ progname);
+ exit(EXIT_FAILURE);
+}
+
+static const struct fmt_info {
+ const char *name;
+ int fmt;
+ int siz;
+} fmt_map[] = {
+ // clang-format off
+ { "i4", G_IM_FMT_I, G_IM_SIZ_4b, },
+ { "i8", G_IM_FMT_I, G_IM_SIZ_8b, },
+ { "ci4", G_IM_FMT_CI, G_IM_SIZ_4b, },
+ { "ci8", G_IM_FMT_CI, G_IM_SIZ_8b, },
+ { "ia4", G_IM_FMT_IA, G_IM_SIZ_4b, },
+ { "ia8", G_IM_FMT_IA, G_IM_SIZ_8b, },
+ { "ia16", G_IM_FMT_IA, G_IM_SIZ_16b, },
+ { "rgba16", G_IM_FMT_RGBA, G_IM_SIZ_16b, },
+ { "rgba32", G_IM_FMT_RGBA, G_IM_SIZ_32b, },
+ // clang-format on
+};
+
+int
+main(int argc, char **argv)
+{
+ const char *progname = argv[0];
+ const char *fmt;
+ const char *array_fmt;
+ const char *in;
+ const char *out;
+ const char *pal_out;
+
+ if (argc < 5)
+ usage(progname);
+
+ fmt = argv[1];
+ array_fmt = argv[2];
+ in = argv[3];
+ out = argv[4];
+ pal_out = (argc > 5) ? argv[5] : NULL;
+
+ unsigned int byte_width = (strequ(array_fmt, "u32") ? 4 : 8);
+
+ if (!is_regular_file(in)) {
+ fprintf(stderr, "Could not open input file %s\n", in);
+ return EXIT_FAILURE;
+ }
+
+ if (strequ(fmt, "JFIF")) {
+ struct JFIF *jfif = jfif_fromfile(in, JFIF_BUFFER_SIZE);
+ if (jfif == NULL) {
+ fprintf(stderr, "Could not open input file %s\n", in);
+ return EXIT_FAILURE;
+ }
+ if (jfif_to_c_file(out, jfif, JFIF_BUFFER_SIZE)) {
+ fprintf(stderr, "Could not save output C file %s\n", out);
+ return EXIT_FAILURE;
+ }
+ jfif_free(jfif);
+ } else {
+ int rv;
+ const struct fmt_info *fmt_info = NULL;
+ for (size_t i = 0; i < ARRLEN(fmt_map); i++) {
+ if (strequ(fmt, fmt_map[i].name)) {
+ fmt_info = &fmt_map[i];
+ break;
+ }
+ }
+ if (fmt_info == NULL) {
+ fprintf(stderr, "Error: Invalid fmt %s\n", fmt);
+ return EXIT_FAILURE;
+ }
+
+ struct n64_image *img = n64texconv_image_from_png(in, fmt_info->fmt, fmt_info->siz, G_IM_FMT_RGBA);
+ if (img == NULL) {
+ fprintf(stderr, "Could not open input file %s\n", in);
+ return EXIT_FAILURE;
+ }
+
+ if (img->pal != NULL) {
+ if (pal_out == NULL) {
+ fprintf(stderr, "Input file %s is color indexed, a palette output C file must be provided.\n", in);
+ usage(progname);
+ }
+
+ if (rv = n64texconv_palette_to_c_file(pal_out, img->pal, false, byte_width), rv != 0) {
+ fprintf(stderr, "Could not save output C file %s (error %d)\n", pal_out, rv);
+ return EXIT_FAILURE;
+ }
+ }
+
+ if (rv = n64texconv_image_to_c_file(out, img, false, false, byte_width), rv != 0) {
+ fprintf(stderr, "Could not save output C file %s (error %d)\n", out, rv);
+ return EXIT_FAILURE;
+ }
+
+ if (img->pal != NULL)
+ n64texconv_palette_free(img->pal);
+ n64texconv_image_free(img);
+ }
+
+ return EXIT_SUCCESS;
+}
diff --git a/tools/assets/n64texconv/src/libn64texconv/bin2c.c b/tools/assets/n64texconv/src/libn64texconv/bin2c.c
new file mode 100644
index 000000000..c5d9475bb
--- /dev/null
+++ b/tools/assets/n64texconv/src/libn64texconv/bin2c.c
@@ -0,0 +1,130 @@
+/* SPDX-FileCopyrightText: Copyright (C) 2025 ZeldaRET */
+/* SPDX-License-Identifier: MIT */
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include "bin2c.h"
+#include "endian.h"
+
+#define BYTES_PER_ROW 32
+#define LINE_MASK (BYTES_PER_ROW - 1)
+
+int
+bin2c(char **out, size_t *size_out, void *bin, size_t size, size_t pad_to_size, unsigned int byte_width)
+{
+ assert(out != NULL);
+ assert(size_out != NULL);
+ assert(bin != NULL);
+
+ if (byte_width != 1 && byte_width != 2 && byte_width != 4 && byte_width != 8)
+ return -2;
+
+ size_t end_size = (pad_to_size > size) ? pad_to_size : size;
+
+ if ((end_size & (byte_width - 1)) != 0)
+ return -3;
+
+ size_t size_out_ = (1 + 1 + 2 * byte_width + 1 + 1) * ((end_size + byte_width - 1) / byte_width) + 2;
+ char *out_ = malloc(size_out_);
+ if (out_ == NULL)
+ return -1;
+
+ char *pos = out_;
+ bool was_newline = false;
+ for (size_t p = 0; p < size; p += byte_width) {
+ size_t rem = byte_width;
+ if (rem > size - p) // For any remaining unaligned data, rest will be padded with 0
+ rem = size - p;
+
+ // Read input
+ uint64_t d = 0;
+ memcpy(&d, &((uint8_t *)bin)[p], rem);
+
+ // Byteswap + shift
+ d = be64toh(d) >> (64 - 8 * byte_width);
+
+ // Write output
+ was_newline = (((p + byte_width) & LINE_MASK) == 0);
+ char end = was_newline ? '\n' : ' ';
+ pos += sprintf(pos, "0x%0*" PRIX64 ",%c", 2 * byte_width, d, end);
+ }
+
+ for (size_t p = (size + byte_width - 1) & ~(byte_width - 1); p < pad_to_size; p += byte_width) {
+ was_newline = (((p + byte_width) & LINE_MASK) == 0);
+ char end = was_newline ? '\n' : ' ';
+ pos += sprintf(pos, "0x%0*" PRIX64 ",%c", 2 * byte_width, (uint64_t)0, end);
+ }
+
+ if (!was_newline)
+ *pos++ = '\n';
+
+ *pos++ = '\0';
+
+ *out = out_;
+ *size_out = size_out_;
+ return 0;
+}
+
+int
+bin2c_file(const char *out_path, void *bin, size_t size, size_t pad_to_size, unsigned int byte_width)
+{
+ assert(out_path != NULL);
+ assert(bin != NULL);
+
+ if (byte_width != 1 && byte_width != 2 && byte_width != 4 && byte_width != 8)
+ return -2;
+
+ size_t end_size = (pad_to_size > size) ? pad_to_size : size;
+
+ if ((end_size & (byte_width - 1)) != 0)
+ return -3;
+
+ FILE *of = fopen(out_path, "w");
+ if (of == NULL)
+ return -1;
+
+ bool was_newline = false;
+ for (size_t p = 0; p < size; p += byte_width) {
+ size_t rem = byte_width;
+ if (rem > size - p) // For any remaining unaligned data, rest will be padded with 0
+ rem = size - p;
+
+ // Read input
+ uint64_t d = 0;
+ memcpy(&d, &((uint8_t *)bin)[p], rem);
+
+ // Byteswap + shift
+ d = be64toh(d) >> (64 - 8 * byte_width);
+
+ // Write output
+ was_newline = (((p + byte_width) & LINE_MASK) == 0);
+ char end = was_newline ? '\n' : ' ';
+
+ if (fprintf(of, "0x%0*" PRIX64 ",%c", 2 * byte_width, d, end) < 0)
+ goto error_post_open;
+ }
+
+ for (size_t p = (size + byte_width - 1) & ~(byte_width - 1); p < pad_to_size; p += byte_width) {
+ was_newline = (((p + byte_width) & LINE_MASK) == 0);
+ char end = was_newline ? '\n' : ' ';
+ if (fprintf(of, "0x%0*" PRIX64 ",%c", 2 * byte_width, (uint64_t)0, end) < 0)
+ goto error_post_open;
+ }
+
+ if (!was_newline)
+ fputs("\n", of);
+
+ fclose(of);
+ return 0;
+error_post_open:
+ fclose(of);
+ if (remove(out_path) != 0)
+ fprintf(stderr, "error calling remove(\"%s\"): %s", out_path, strerror(errno));
+ return -4;
+}
diff --git a/tools/assets/n64texconv/src/libn64texconv/bin2c.h b/tools/assets/n64texconv/src/libn64texconv/bin2c.h
new file mode 100644
index 000000000..f34a65baf
--- /dev/null
+++ b/tools/assets/n64texconv/src/libn64texconv/bin2c.h
@@ -0,0 +1,14 @@
+/* SPDX-FileCopyrightText: Copyright (C) 2025 ZeldaRET */
+/* SPDX-License-Identifier: MIT */
+#ifndef BIN2C_H
+#define BIN2C_H
+
+#include
+
+int
+bin2c(char **out, size_t *size_out, void *bin, size_t size, size_t pad_to_size, unsigned int byte_width);
+
+int
+bin2c_file(const char *out_path, void *bin, size_t size, size_t pad_to_size, unsigned int byte_width);
+
+#endif
diff --git a/tools/assets/n64texconv/src/libn64texconv/endian.h b/tools/assets/n64texconv/src/libn64texconv/endian.h
new file mode 100644
index 000000000..e457b8664
--- /dev/null
+++ b/tools/assets/n64texconv/src/libn64texconv/endian.h
@@ -0,0 +1,69 @@
+/* SPDX-FileCopyrightText: Copyright (C) 2025 ZeldaRET */
+/* SPDX-License-Identifier: MIT */
+#ifndef ENDIAN_H
+#define ENDIAN_H
+
+#if defined(__linux__) || defined(__CYGWIN__)
+#include
+#elif defined(__APPLE__)
+#include
+
+#define htobe16(x) OSSwapHostToBigInt16(x)
+#define htole16(x) OSSwapHostToLittleInt16(x)
+#define be16toh(x) OSSwapBigToHostInt16(x)
+#define le16toh(x) OSSwapLittleToHostInt16(x)
+
+#define htobe32(x) OSSwapHostToBigInt32(x)
+#define htole32(x) OSSwapHostToLittleInt32(x)
+#define be32toh(x) OSSwapBigToHostInt32(x)
+#define le32toh(x) OSSwapLittleToHostInt32(x)
+
+#define htobe64(x) OSSwapHostToBigInt64(x)
+#define htole64(x) OSSwapHostToLittleInt64(x)
+#define be64toh(x) OSSwapBigToHostInt64(x)
+#define le64toh(x) OSSwapLittleToHostInt64(x)
+#else
+
+#if !defined(__BYTE_ORDER__)
+#error "No endian define provided by compiler"
+#endif
+
+#if (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__)
+
+#define htobe16(x) (x)
+#define htole16(x) __builtin_bswap16(x)
+#define be16toh(x) (x)
+#define le16toh(x) __builtin_bswap16(x)
+
+#define htobe32(x) (x)
+#define htole32(x) __builtin_bswap32(x)
+#define be32toh(x) (x)
+#define le32toh(x) __builtin_bswap32(x)
+
+#define htobe64(x) (x)
+#define htole64(x) __builtin_bswap64(x)
+#define be64toh(x) (x)
+#define le64toh(x) __builtin_bswap64(x)
+
+#else
+
+#define htobe16(x) __builtin_bswap16(x)
+#define htole16(x) (x)
+#define be16toh(x) __builtin_bswap16(x)
+#define le16toh(x) (x)
+
+#define htobe32(x) __builtin_bswap32(x)
+#define htole32(x) (x)
+#define be32toh(x) __builtin_bswap32(x)
+#define le32toh(x) (x)
+
+#define htobe64(x) __builtin_bswap64(x)
+#define htole64(x) (x)
+#define be64toh(x) __builtin_bswap64(x)
+#define le64toh(x) (x)
+
+#endif
+
+#endif
+
+#endif
diff --git a/tools/assets/n64texconv/src/libn64texconv/jfif.c b/tools/assets/n64texconv/src/libn64texconv/jfif.c
new file mode 100644
index 000000000..645614c89
--- /dev/null
+++ b/tools/assets/n64texconv/src/libn64texconv/jfif.c
@@ -0,0 +1,76 @@
+/* SPDX-FileCopyrightText: Copyright (C) 2025 ZeldaRET */
+/* SPDX-License-Identifier: MIT */
+#include
+#include
+#include
+#include
+#include
+
+#include "endian.h"
+#include "bin2c.h"
+#include "jfif.h"
+
+struct JFIF *
+jfif_fromfile(const char *path, size_t max_size)
+{
+ assert(path != NULL);
+ FILE *f = fopen(path, "rb");
+ if (f == NULL)
+ return NULL;
+
+ fseek(f, 0, SEEK_END);
+ size_t data_size = ftell(f);
+ fseek(f, 0, SEEK_SET);
+
+ struct JFIF *jfif = malloc(((sizeof(struct JFIF) + 3) & ~3) + data_size);
+ if (jfif != NULL) {
+ jfif->data = (void *)(jfif + 1);
+ jfif->data_size = data_size;
+
+ if (fread(jfif->data, 1, data_size, f) != data_size) {
+ free(jfif);
+ jfif = NULL;
+ } else {
+ uint8_t *data8 = jfif->data;
+ uint16_t *data16 = jfif->data;
+ uint32_t *data32 = jfif->data;
+
+ if (be32toh(data32[0]) != 0xFFD8FFE0)
+ printf("[Warning] Missing JPEG marker\n");
+ if (data8[6] != 'J' || data8[7] != 'F' || data8[8] != 'I' || data8[9] != 'F')
+ printf("[Warning] Not JFIF\n");
+ if (data8[11] != 0x01 || data8[12] != 0x01)
+ printf("[Warning] Not JFIF version 1.01\n");
+ if (be16toh(data16[10]) != 0xFFDB)
+ printf("[Warning] Data before DQT\n");
+ if (jfif->data_size > max_size)
+ printf("[Warning] JFIF image too large\n");
+ }
+ }
+
+ fclose(f);
+ return jfif;
+}
+
+void
+jfif_free(struct JFIF *jfif)
+{
+ assert(jfif != NULL);
+ free(jfif);
+}
+
+int
+jfif_to_c(char **out, size_t *size_out, struct JFIF *jfif, size_t pad_to_size)
+{
+ assert(out != NULL);
+ assert(size_out != NULL);
+ return bin2c(out, size_out, jfif->data, jfif->data_size, pad_to_size, 8);
+}
+
+int
+jfif_to_c_file(const char *out_path, struct JFIF *jfif, size_t pad_to_size)
+{
+ assert(out_path != NULL);
+ assert(jfif != NULL);
+ return bin2c_file(out_path, jfif->data, jfif->data_size, pad_to_size, 8);
+}
diff --git a/tools/assets/n64texconv/src/libn64texconv/jfif.h b/tools/assets/n64texconv/src/libn64texconv/jfif.h
new file mode 100644
index 000000000..d094d5478
--- /dev/null
+++ b/tools/assets/n64texconv/src/libn64texconv/jfif.h
@@ -0,0 +1,28 @@
+/* SPDX-FileCopyrightText: Copyright (C) 2025 ZeldaRET */
+/* SPDX-License-Identifier: MIT */
+#ifndef JFIF_H
+#define JFIF_H
+
+#include
+#include
+
+struct JFIF {
+ void *data;
+ size_t data_size;
+};
+
+#define JFIF_BUFFER_SIZE (320 * 240 * sizeof(uint16_t))
+
+struct JFIF *
+jfif_fromfile(const char *path, size_t max_size);
+
+void
+jfif_free(struct JFIF *jfif);
+
+int
+jfif_to_c(char **out, size_t *size_out, struct JFIF *jfif, size_t pad_to_size);
+
+int
+jfif_to_c_file(const char *out_path, struct JFIF *jfif, size_t pad_to_size);
+
+#endif
diff --git a/tools/assets/n64texconv/src/libn64texconv/n64texconv.c b/tools/assets/n64texconv/src/libn64texconv/n64texconv.c
new file mode 100644
index 000000000..06caf36f6
--- /dev/null
+++ b/tools/assets/n64texconv/src/libn64texconv/n64texconv.c
@@ -0,0 +1,1302 @@
+/* SPDX-FileCopyrightText: Copyright (C) 2025 ZeldaRET */
+/* SPDX-License-Identifier: MIT */
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include "spng.h"
+#include "libimagequant.h"
+#include "endian.h"
+#include "bin2c.h"
+#include "n64texconv.h"
+
+// ********************************************************************************************************************
+// Helpers
+// ********************************************************************************************************************
+
+#define UNUSED __attribute__((unused))
+
+#define ALIGN8(x) (((x) + 7) & ~7)
+
+#define ABS(x) (((x) < 0) ? -(x) : (x))
+
+static uint8_t
+texel_to_greyscale(uint8_t r, uint8_t g, uint8_t b)
+{
+ // Approximately (0.2126729, 0.7151522, 0.0721750) in 1.8 fixed point
+ // Same as Blender:
+ // https://github.com/blender/blender/blob/594f47ecd2d5367ca936cf6fc6ec8168c2b360d0/intern/cycles/render/shader.cpp#L387
+ return (r * 54 + g * 183 + b * 19 + 128) / 256;
+}
+
+UNUSED static void
+texels_to_greyscale(struct color *out, struct color *in, size_t ntexels, bool alpha)
+{
+ assert(out != NULL);
+ assert(in != NULL);
+
+ for (size_t i = 0; i < ntexels; i++) {
+ struct color color = in[i];
+ uint8_t grey = texel_to_greyscale(color.r, color.g, color.b);
+ uint8_t a = color.a;
+ out[i].r = grey;
+ out[i].g = grey;
+ out[i].b = grey;
+ out[i].a = (alpha) ? a : grey;
+ }
+}
+
+static void
+palette_dim(size_t count, size_t *width, size_t *height)
+{
+ assert(width != NULL);
+ assert(height != NULL);
+
+ size_t best_width = count;
+ size_t best_height = 1;
+ size_t best_diff = count - 1;
+
+ if (count >= 4) {
+ // Find a factorization of count for which the two factors are close to equal, and width >= height.
+ // This makes the output palette image approximately square.
+ for (size_t i = 2; i <= (size_t)sqrtf(count); i++) {
+ size_t div = count / i;
+
+ size_t new_diff = ABS((signed)(div - i));
+ if (div * i == count && new_diff < best_diff) {
+ // (div, i) is a factorization and is closer to a square than before
+ best_width = div;
+ best_height = i;
+ best_diff = new_diff;
+ }
+ }
+ }
+ *width = best_width;
+ *height = best_height;
+}
+
+static void
+n64texconv_quantize(uint8_t *out_indices, struct color *out_pal, size_t *out_pal_count, struct color *texels,
+ size_t width, size_t height, unsigned int max_colors, float dither_level)
+{
+ assert(out_indices != NULL);
+ assert(out_pal != NULL);
+ assert(out_pal_count != NULL);
+ assert(texels != NULL);
+
+ // Set options
+ liq_attr *attr = liq_attr_create();
+ liq_set_max_colors(attr, max_colors);
+
+ // Quantize
+ liq_image *img = liq_image_create_rgba(attr, (void *)texels, width, height, 0.0);
+ liq_result *result;
+ liq_error err = liq_image_quantize(img, attr, &result);
+ assert(err == LIQ_OK);
+
+ // Write output bitmap
+ liq_set_dithering_level(result, dither_level);
+ liq_write_remapped_image(result, img, (void *)out_indices, width * height);
+
+ // Write output palette
+ const liq_palette *pal = liq_get_palette(result);
+ assert(pal->count <= max_colors);
+ *out_pal_count = pal->count;
+ memcpy(out_pal, pal->entries, pal->count * 4);
+
+ // Cleanup
+ liq_result_destroy(result);
+ liq_image_destroy(img);
+ liq_attr_destroy(attr);
+}
+
+/**
+ * out_indices, out_pal, out_pal_count, texels, widths, heights are all arrays of size num_images
+ * texels[i] and out_indices[i] are arrays of size widths[i] * heights[i]
+ */
+UNUSED static int
+n64texconv_quantize_shared(uint8_t **out_indices, struct color *out_pal, size_t *out_pal_count, struct color **texels,
+ size_t *widths, size_t *heights, size_t num_images, unsigned int max_colors,
+ float dither_level)
+{
+ assert(out_indices != NULL);
+ assert(out_pal != NULL);
+ assert(out_pal_count != NULL);
+ assert(texels != NULL);
+ assert(widths != NULL);
+ assert(heights != NULL);
+
+ int rv = 0;
+
+ // Set options
+ liq_attr *attr = liq_attr_create();
+ liq_set_max_colors(attr, max_colors);
+
+ // Create histogram
+ liq_histogram *hist = liq_histogram_create(attr);
+
+ // Add images to histogram
+ liq_image *images[num_images];
+ for (size_t i = 0; i < num_images; i++) {
+ images[i] = liq_image_create_rgba(attr, (void *)texels[i], widths[i], heights[i], 0);
+ liq_histogram_add_image(hist, attr, images[i]);
+ }
+
+ // Simultaneous quantization
+ liq_result *result;
+ liq_error err = liq_histogram_quantize(hist, attr, &result);
+ if (err != LIQ_OK) {
+ rv = -1;
+ goto exit;
+ }
+
+ // Remap images
+ liq_set_dithering_level(result, dither_level);
+ for (size_t i = 0; i < num_images; i++) {
+ liq_write_remapped_image(result, images[i], (void *)out_indices[i], widths[i] * heights[i]);
+ }
+
+ // Write output palette
+ const liq_palette *pal = liq_get_palette(result);
+ assert(pal->count <= max_colors);
+ *out_pal_count = pal->count;
+ memcpy(out_pal, pal->entries, pal->count * 4);
+
+ // Cleanup
+ liq_result_destroy(result);
+exit:
+ for (size_t i = 0; i < num_images; i++) {
+ liq_image_destroy(images[i]);
+ }
+ liq_histogram_destroy(hist);
+ liq_attr_destroy(attr);
+ return rv;
+}
+
+
+
+// ********************************************************************************************************************
+// Format Packing and Unpacking
+// ********************************************************************************************************************
+
+#define UNPACK_FUNC(fmt_name) static int fmt_name##_unpack(struct color *out, void *in, size_t ntexels)
+
+#define UNPACK_CI_FUNC(fmt_name) static int fmt_name##_unpack(uint8_t *out, void *in, size_t ntexels, size_t npal)
+
+#define PACK_FUNC(fmt_name) static int fmt_name##_pack(void *out, struct color *in, size_t ntexels)
+
+#define PACK_CI_FUNC(fmt_name) static int fmt_name##_pack(void *out, uint8_t *in, size_t ntexels, size_t npal)
+
+/* RGBA16 */
+
+UNPACK_FUNC(rgba16)
+{
+ uint16_t *in16 = in;
+
+ for (size_t n = 0; n < ntexels; n++) {
+ uint16_t c = be16toh(in16[n]);
+ uint8_t r = (c >> 11) & 0b11111;
+ uint8_t g = (c >> 6) & 0b11111;
+ uint8_t b = (c >> 1) & 0b11111;
+ uint8_t a = (c >> 0) & 1;
+ out[n].r = (r << 3) | (r >> 2);
+ out[n].g = (g << 3) | (g >> 2);
+ out[n].b = (b << 3) | (b >> 2);
+ out[n].a = 255 * a;
+ }
+ return 0;
+}
+
+PACK_FUNC(rgba16)
+{
+ uint16_t *out16 = out;
+
+ for (size_t n = 0; n < ntexels; n++) {
+ uint8_t r = (in[n].r >> 3) & 0b11111;
+ uint8_t g = (in[n].g >> 3) & 0b11111;
+ uint8_t b = (in[n].b >> 3) & 0b11111;
+ uint8_t a = in[n].a != 0;
+ out16[n] = htobe16((r << 11) | (g << 6) | (b << 1) | a);
+ }
+ return 0;
+}
+
+/* RGBA32 */
+
+UNPACK_FUNC(rgba32)
+{
+ uint32_t *in32 = in;
+
+ for (size_t n = 0; n < ntexels; n++) {
+ uint32_t c = be32toh(in32[n]);
+ out[n].r = (c >> 24) & 0xFF;
+ out[n].g = (c >> 16) & 0xFF;
+ out[n].b = (c >> 8) & 0xFF;
+ out[n].a = (c >> 0) & 0xFF;
+ }
+ return 0;
+}
+
+PACK_FUNC(rgba32)
+{
+ uint32_t *out32 = out;
+
+ for (size_t n = 0; n < ntexels; n++) {
+ out32[n] = htobe32((in[n].r << 24) | (in[n].g << 16) | (in[n].b << 8) | in[n].a);
+ }
+ return 0;
+}
+
+/* CI4 */
+
+UNPACK_CI_FUNC(ci4)
+{
+ uint8_t *in8 = in;
+
+ unsigned sft = 4;
+ for (size_t n = 0; n < ntexels; n++, sft ^= 4) {
+ uint8_t c = (in8[n >> 1] >> sft) & 0xF;
+ if (!(c < npal))
+ return -1; // palette too small for image data
+ out[n] = c;
+ }
+ return 0;
+}
+
+PACK_CI_FUNC(ci4)
+{
+ uint8_t *out8 = out;
+
+ unsigned sft = 4;
+ for (size_t n = 0; n < ntexels; n++, sft ^= 4) {
+ uint8_t c = in[n];
+ if (!(c < npal))
+ return -1; // palette too small for image data
+ if (sft == 4)
+ out8[n >> 1] = 0;
+ out8[n >> 1] |= c << sft;
+ }
+ return 0;
+}
+
+/* CI8 */
+
+UNPACK_CI_FUNC(ci8)
+{
+ uint8_t *in8 = in;
+
+ for (size_t n = 0; n < ntexels; n++) {
+ uint8_t c = in8[n] & 0xFF;
+ if (!(c < npal))
+ return -1; // palette too small for image data
+ out[n] = c;
+ }
+ return 0;
+}
+
+PACK_CI_FUNC(ci8)
+{
+ uint8_t *out8 = out;
+
+ for (size_t n = 0; n < ntexels; n++) {
+ uint8_t c = in[n];
+ if (!(c < npal))
+ return -1; // palette too small for image data
+ out8[n] = c;
+ }
+ return 0;
+}
+
+/* IA4 */
+
+UNPACK_FUNC(ia4)
+{
+ uint8_t *in8 = in;
+
+ unsigned sft = 4;
+ for (size_t n = 0; n < ntexels; n++, sft ^= 4) {
+ uint8_t c = (in8[n >> 1] >> sft) & 0xF;
+ uint8_t i = c & 0b1110;
+ uint8_t a = c & 0b0001;
+ i = (i << 4) | (i << 1) | (i >> 2);
+ a = 255 * a;
+ out[n].r = i;
+ out[n].g = i;
+ out[n].b = i;
+ out[n].a = a;
+ }
+ return 0;
+}
+
+PACK_FUNC(ia4)
+{
+ uint8_t *out8 = out;
+
+ unsigned sft = 4;
+ for (size_t n = 0; n < ntexels; n++, sft ^= 4) {
+ uint8_t g = texel_to_greyscale(in[n].r, in[n].g, in[n].b);
+ uint8_t i = (g >> 5) & 0b111;
+ uint8_t a = in[n].a != 0;
+ if (sft == 4)
+ out8[n >> 1] = 0;
+ out8[n >> 1] |= ((i << 1) | a) << sft;
+ }
+ return 0;
+}
+
+/* IA8 */
+
+UNPACK_FUNC(ia8)
+{
+ uint8_t *in8 = in;
+
+ for (size_t n = 0; n < ntexels; n++) {
+ uint8_t c = in8[n];
+ uint8_t i = (c >> 4) & 0xF;
+ uint8_t a = (c >> 0) & 0xF;
+ i = (i << 4) | i;
+ a = (a << 4) | a;
+ out[n].r = i;
+ out[n].g = i;
+ out[n].b = i;
+ out[n].a = a;
+ }
+ return 0;
+}
+
+PACK_FUNC(ia8)
+{
+ uint8_t *out8 = out;
+
+ for (size_t n = 0; n < ntexels; n++) {
+ uint8_t g = texel_to_greyscale(in[n].r, in[n].g, in[n].b);
+ uint8_t i = (g >> 4) & 0xF;
+ uint8_t a = (in[n].a >> 4) & 0xF;
+ out8[n] = (i << 4) | a;
+ }
+ return 0;
+}
+
+/* IA16 */
+
+UNPACK_FUNC(ia16)
+{
+ uint16_t *in16 = in;
+
+ for (size_t n = 0; n < ntexels; n++) {
+ uint16_t c = be16toh(in16[n]);
+ uint8_t i = (c >> 8) & 0xFF;
+ uint8_t a = (c >> 0) & 0xFF;
+ out[n].r = i;
+ out[n].g = i;
+ out[n].b = i;
+ out[n].a = a;
+ }
+ return 0;
+}
+
+PACK_FUNC(ia16)
+{
+ uint16_t *out16 = out;
+
+ for (size_t n = 0; n < ntexels; n++) {
+ uint8_t i = texel_to_greyscale(in[n].r, in[n].g, in[n].b);
+ uint8_t a = in[n].a;
+ out16[n] = htobe16((i << 8) | a);
+ }
+ return 0;
+}
+
+/* I4 */
+
+UNPACK_FUNC(i4)
+{
+ uint8_t *in8 = in;
+
+ unsigned sft = 4;
+ for (size_t n = 0; n < ntexels; n++, sft ^= 4) {
+ uint8_t i = (in8[n >> 1] >> sft) & 0xF;
+ i = (i << 4) | i;
+ out[n].r = i;
+ out[n].g = i;
+ out[n].b = i;
+ out[n].a = i;
+ }
+ return 0;
+}
+
+PACK_FUNC(i4)
+{
+ uint8_t *out8 = out;
+
+ unsigned sft = 4;
+ for (size_t n = 0; n < ntexels; n++, sft ^= 4) {
+ uint8_t g = texel_to_greyscale(in[n].r, in[n].g, in[n].b);
+ uint8_t i = (g >> 4) & 0xF;
+ if (sft == 4)
+ out8[n >> 1] = 0;
+ out8[n >> 1] |= i << sft;
+ }
+ return 0;
+}
+
+/* I8 */
+
+UNPACK_FUNC(i8)
+{
+ uint8_t *in8 = in;
+
+ for (size_t n = 0; n < ntexels; n++) {
+ uint8_t i = in8[n];
+ out[n].r = i;
+ out[n].g = i;
+ out[n].b = i;
+ out[n].a = i;
+ }
+ return 0;
+}
+
+PACK_FUNC(i8)
+{
+ uint8_t *out8 = out;
+
+ for (size_t n = 0; n < ntexels; n++) {
+ uint8_t i = texel_to_greyscale(in[n].r, in[n].g, in[n].b);
+ out8[n] = i;
+ }
+ return 0;
+}
+
+struct texel_layout {
+ const char *name;
+ union {
+ int (*pack)(void *out, struct color *in, size_t ntexels);
+ int (*pack_ci)(void *out, uint8_t *in, size_t ntexels, size_t npal);
+ };
+ union {
+ int (*unpack)(struct color *out, void *in, size_t ntexels);
+ int (*unpack_ci)(uint8_t *out, void *in, size_t ntexels, size_t npal);
+ };
+};
+
+#define FMT_SIZ(fmt, siz) (((fmt) << 2) | (siz))
+struct texel_layout texel_layouts[32] = {
+ [FMT_SIZ(G_IM_FMT_RGBA, G_IM_SIZ_16b)] = { "rgba16", .pack = rgba16_pack, .unpack = rgba16_unpack, },
+ [FMT_SIZ(G_IM_FMT_RGBA, G_IM_SIZ_32b)] = { "rgba32", .pack = rgba32_pack, .unpack = rgba32_unpack, },
+ [FMT_SIZ(G_IM_FMT_CI, G_IM_SIZ_4b) ] = { "ci4", .pack_ci = ci4_pack, .unpack_ci = ci4_unpack, },
+ [FMT_SIZ(G_IM_FMT_CI, G_IM_SIZ_8b) ] = { "ci8", .pack_ci = ci8_pack, .unpack_ci = ci8_unpack, },
+ [FMT_SIZ(G_IM_FMT_IA, G_IM_SIZ_4b) ] = { "ia4", .pack = ia4_pack, .unpack = ia4_unpack, },
+ [FMT_SIZ(G_IM_FMT_IA, G_IM_SIZ_8b) ] = { "ia8", .pack = ia8_pack, .unpack = ia8_unpack, },
+ [FMT_SIZ(G_IM_FMT_IA, G_IM_SIZ_16b)] = { "ia16", .pack = ia16_pack, .unpack = ia16_unpack, },
+ [FMT_SIZ(G_IM_FMT_I, G_IM_SIZ_4b) ] = { "i4", .pack = i4_pack, .unpack = i4_unpack, },
+ [FMT_SIZ(G_IM_FMT_I, G_IM_SIZ_8b) ] = { "i8", .pack = i8_pack, .unpack = i8_unpack, },
+};
+
+static int
+n64texconv_data_sync(struct color *texels, uint8_t *color_indices, size_t ntexels, int fmt, int siz, size_t pal_count)
+{
+ assert(texels != NULL);
+
+ void *temp = malloc(texel_size_bytes(ntexels, siz));
+ if (temp == NULL)
+ return -1;
+
+ struct texel_layout *layout = &texel_layouts[FMT_SIZ(fmt, siz)];
+ assert(layout != NULL);
+ if (fmt == G_IM_FMT_CI) {
+ assert(color_indices != NULL);
+ layout->pack_ci(temp, color_indices, ntexels, pal_count);
+ layout->unpack_ci(color_indices, temp, ntexels, pal_count);
+ // TODO update texels from color indices too?
+ } else {
+ layout->pack(temp, texels, ntexels);
+ layout->unpack(texels, temp, ntexels);
+ }
+
+ free(temp);
+ return 0;
+}
+
+
+
+// ********************************************************************************************************************
+// Palette
+// ********************************************************************************************************************
+
+static int
+n64texconv_palette_sync(struct n64_palette *pal)
+{
+ assert(pal != NULL);
+ return n64texconv_data_sync(pal->texels, NULL, pal->count, pal->fmt, G_IM_SIZ_16b, 0);
+}
+
+struct n64_palette *
+n64texconv_palette_new(size_t count, int fmt)
+{
+ if (fmt != G_IM_FMT_RGBA && fmt != G_IM_FMT_IA)
+ return NULL;
+
+ struct n64_palette *pal = malloc(sizeof(struct n64_palette) + count * sizeof(struct color));
+ if (pal == NULL)
+ return NULL;
+
+ pal->texels = (struct color *)(pal + 1);
+ pal->fmt = fmt;
+ pal->count = count;
+ return pal;
+}
+
+void
+n64texconv_palette_free(struct n64_palette *pal)
+{
+ assert(pal != NULL);
+ free(pal);
+}
+
+struct n64_palette *
+n64texconv_palette_copy(struct n64_palette *pal)
+{
+ assert(pal != NULL);
+ // Create new palette
+ struct n64_palette *new_pal = n64texconv_palette_new(pal->count, pal->fmt);
+ if (new_pal == NULL)
+ return NULL;
+
+ // Copy texels
+ memcpy(new_pal->texels, pal->texels, new_pal->count * sizeof(struct color));
+ return new_pal;
+}
+
+struct n64_palette *
+n64texconv_palette_reformat(struct n64_palette *pal, int fmt)
+{
+ assert(pal != NULL);
+
+ // If the target format and source format are the same, just copy
+ if (pal->fmt == fmt)
+ return n64texconv_palette_copy(pal);
+
+ // Create new palette
+ struct n64_palette *new_pal = n64texconv_palette_new(pal->count, pal->fmt);
+ if (new_pal == NULL)
+ return NULL;
+
+ n64texconv_palette_sync(new_pal);
+ return new_pal;
+}
+
+struct n64_palette *
+n64texconv_palette_from_png(const char *path, int fmt)
+{
+ assert(path != NULL);
+
+ FILE *png = fopen(path, "rb");
+ if (png == NULL)
+ return NULL;
+
+ spng_ctx *ctx = spng_ctx_new(0);
+ assert(ctx != NULL);
+
+ int rv;
+ rv = spng_set_png_file(ctx, png);
+ assert(rv == 0);
+
+ size_t ntexels;
+ rv = spng_decoded_image_size(ctx, SPNG_FMT_RGBA8, &ntexels);
+ assert(rv == 0);
+
+ struct n64_palette *pal = n64texconv_palette_new(ntexels, fmt);
+ if (pal == NULL)
+ return NULL;
+
+ rv = spng_decode_image(ctx, (void *)pal->texels, ntexels, SPNG_FMT_RGBA8, 0);
+ assert(rv == 0);
+ for (size_t i = 0; i < ntexels; i++) {
+ pal->texels[i].w = htobe32(pal->texels[i].w);
+ }
+
+ spng_ctx_free(ctx);
+ fclose(png);
+
+ rv = n64texconv_palette_sync(pal);
+ assert(rv == 0);
+ return pal;
+}
+
+struct n64_palette *
+n64texconv_palette_from_bin(void *data, size_t count, int fmt)
+{
+ assert(data != NULL);
+
+ // Reserve new palette
+ struct n64_palette *pal = n64texconv_palette_new(count, fmt);
+ if (pal == NULL)
+ return NULL;
+
+ // Unpack data
+ // The format is always valid at this point since the above NULL check
+ // would be hit if an invalid palette format was passed in.
+ texel_layouts[FMT_SIZ(fmt, G_IM_SIZ_16b)].unpack(pal->texels, data, count);
+ return pal;
+}
+
+int
+n64texconv_palette_to_png(const char *outpath, struct n64_palette *pal)
+{
+ assert(outpath != NULL);
+ assert(pal != NULL);
+
+ // Compute arbitrary dimensions for palette
+ size_t width, height;
+ palette_dim(pal->count, &width, &height);
+
+ // Sync data to format
+
+ int rv;
+ rv = n64texconv_palette_sync(pal);
+ assert(rv == 0);
+
+ // Write texels
+
+ struct spng_ctx *ctx = spng_ctx_new(SPNG_CTX_ENCODER);
+ if (ctx == NULL)
+ return -1;
+
+ FILE *png = fopen(outpath, "wb");
+ if (png == NULL)
+ return -2;
+
+ rv = spng_set_png_file(ctx, png);
+ assert(rv == 0);
+ rv = spng_set_image_limits(ctx, width, height);
+ assert(rv == 0);
+ struct spng_ihdr ihdr = {
+ .width = width,
+ .height = height,
+ .bit_depth = 8,
+ .color_type = SPNG_COLOR_TYPE_TRUECOLOR_ALPHA,
+ .compression_method = 0,
+ .filter_method = 0,
+ .interlace_method = 0,
+ };
+ rv = spng_set_ihdr(ctx, &ihdr);
+ assert(rv == 0);
+ rv = spng_encode_image(ctx, pal->texels, pal->count * sizeof(struct color), SPNG_FMT_PNG, SPNG_ENCODE_FINALIZE);
+ assert(rv == 0);
+ spng_ctx_free(ctx);
+
+ fclose(png);
+ return 0;
+}
+
+void *
+n64texconv_palette_to_bin(struct n64_palette *pal, bool pad_to_8b)
+{
+ assert(pal != NULL);
+
+ // Prepare output buffer
+ size_t size_unaligned = texel_size_bytes(pal->count, G_IM_SIZ_16b);
+ size_t size_aligned = ALIGN8(size_unaligned);
+ void *out = malloc(size_aligned);
+ if (out == NULL)
+ return NULL;
+
+ // Pack into output format
+ assert(pal->fmt == G_IM_FMT_RGBA || pal->fmt == G_IM_FMT_IA);
+ texel_layouts[FMT_SIZ(pal->fmt, G_IM_SIZ_16b)].pack(out, pal->texels, pal->count);
+
+ // Pad to 8-byte alignment if requested
+ if (pad_to_8b && size_aligned != size_unaligned)
+ memset((uint8_t *)out + size_unaligned, 0, size_aligned - size_unaligned);
+
+ return out;
+}
+
+int
+n64texconv_palette_to_c(char **out, size_t *size_out, struct n64_palette *pal, bool pad_to_8b, unsigned int byte_width)
+{
+ assert(out != NULL);
+ assert(size_out != NULL);
+ assert(pal != NULL);
+
+ size_t nbytes = texel_size_bytes(pal->count, G_IM_SIZ_16b);
+ void *bin = n64texconv_palette_to_bin(pal, pad_to_8b);
+ if (bin == NULL)
+ return -1;
+ nbytes = pad_to_8b ? ALIGN8(nbytes) : nbytes;
+ int rv = bin2c(out, size_out, bin, nbytes, 0, byte_width);
+ free(bin);
+ return rv;
+}
+
+int
+n64texconv_palette_to_c_file(const char *out_path, struct n64_palette *pal, bool pad_to_8b, unsigned int byte_width)
+{
+ assert(out_path != NULL);
+ assert(pal != NULL);
+
+ size_t nbytes = texel_size_bytes(pal->count, G_IM_SIZ_16b);
+ void *bin = n64texconv_palette_to_bin(pal, pad_to_8b);
+ if (bin == NULL)
+ return -1;
+ nbytes = pad_to_8b ? ALIGN8(nbytes) : nbytes;
+ int rv = bin2c_file(out_path, bin, nbytes, 0, byte_width);
+ free(bin);
+ return rv;
+}
+
+
+
+// ********************************************************************************************************************
+// Image
+// ********************************************************************************************************************
+
+static int
+n64texconv_image_sync(struct n64_image *img)
+{
+ assert(img != NULL);
+ return n64texconv_data_sync(img->texels, img->color_indices, img->width * img->height, img->fmt, img->siz,
+ (img->pal != NULL) ? img->pal->count : 0);
+}
+
+struct n64_image *
+n64texconv_image_new(size_t width, size_t height, int fmt, int siz, struct n64_palette *pal)
+{
+ // TODO if fmt is CI, assert(pal != NULL) ?
+ if (fmt >= FMT_MAX || siz >= SIZ_MAX)
+ return NULL;
+
+ size_t ntexels = width * height;
+ struct n64_image *img = malloc(sizeof(struct n64_image) + ntexels * (sizeof(struct color) + sizeof(uint8_t)));
+ if (img == NULL)
+ return NULL;
+
+ struct color *texels = (void *)((uint8_t *)img + sizeof(struct n64_image));
+ uint8_t *color_indices = (fmt == G_IM_FMT_CI) ? (uint8_t *)(texels + ntexels) : NULL;
+
+ img->width = width;
+ img->height = height;
+ img->fmt = fmt;
+ img->siz = siz;
+ img->pal = pal;
+ img->texels = texels;
+ img->color_indices = color_indices;
+ return img;
+}
+
+void
+n64texconv_image_free(struct n64_image *img)
+{
+ assert(img != NULL);
+ free(img);
+}
+
+struct n64_image *
+n64texconv_image_copy(struct n64_image *img)
+{
+ if (img == NULL)
+ return NULL;
+
+ // Create new image
+ struct n64_image *new_img = n64texconv_image_new(img->width, img->height, img->fmt, img->siz, img->pal);
+ if (new_img == NULL)
+ return NULL;
+
+ // Copy texels/index data
+ size_t ntexels = new_img->width * new_img->height;
+ memcpy(new_img->texels, img->texels, ntexels * sizeof(struct color));
+ if (img->fmt == G_IM_FMT_CI) // == new_img->fmt
+ memcpy(new_img->color_indices, img->color_indices, ntexels * sizeof(uint8_t));
+ return new_img;
+}
+
+/**
+ * Reads in the png image at `path`.
+ *
+ * For all choices of `fmt`, the png data is converted to a common RGBA32 format and stored that way, but may be
+ * subject to various edits described below.
+ *
+ * - If `fmt` is None (default), the best format and texel size are determined from the RGBA32 data, which is then
+ * processed accordingly (described below).
+ *
+ * - If `fmt` is RGBA, the RGBA32 texels are left as-is, with possible reduction if `siz` is 16-bit.
+ *
+ * - If `fmt` is greyscale (I or IA), the RGBA32 texels are converted to greyscale. If the texels were already
+ * greyscale this operation will leave them unaffected.
+ *
+ * - If `fmt` is CI and the png is an indexed png, the palette and indices in the png are saved in addition to the
+ * texels themselves. This is required for a roundtrip conversion of 'bin -> png -> file -> png -> bin' to match.
+ *
+ * - If `fmt` is CI and the png is not indexed, the image is quantized and a palette is generated automatically.
+ */
+struct n64_image *
+n64texconv_image_from_png(const char *path, int fmt, int siz, int pal_fmt)
+{
+ assert(path != NULL);
+
+ FILE *png = fopen(path, "rb");
+ if (png == NULL)
+ return NULL; // Input file not found
+
+ spng_ctx *ctx = spng_ctx_new(0);
+ int rv = spng_set_png_file(ctx, png);
+ assert(rv == 0);
+
+ struct spng_ihdr ihdr;
+ rv = spng_get_ihdr(ctx, &ihdr);
+ assert(rv == 0);
+
+ size_t nbytes;
+ rv = spng_decoded_image_size(ctx, SPNG_FMT_RGBA8, &nbytes);
+ assert(rv == 0);
+
+ uint32_t width = ihdr.width;
+ uint32_t height = ihdr.height;
+
+ struct n64_image *img = n64texconv_image_new(width, height, fmt, siz, NULL);
+ if (img == NULL)
+ goto error_post_open_png;
+
+ struct n64_palette *pal = NULL;
+
+ if (fmt == G_IM_FMT_CI) {
+ assert(siz == G_IM_SIZ_4b || siz == G_IM_SIZ_8b);
+ assert(pal_fmt != FMT_NONE);
+
+ size_t max_colors = (siz == G_IM_SIZ_8b) ? 256 : 16;
+
+ if (ihdr.color_type == SPNG_COLOR_TYPE_INDEXED) {
+ // Input is an indexed png, obtain palette and color indices
+ struct spng_plte plte;
+ rv = spng_get_plte(ctx, &plte);
+ assert(rv == 0); // must have a palette chunk if it's indexed
+
+ // Palette should not have 0 entries
+ if (plte.n_entries == 0)
+ goto error_post_create_img;
+
+ // TODO ZAPD always writes 256-color palettes which breaks this, enable it when we can
+#if 0
+ // Palette must have sufficiently few colors for the target format. If there are too
+ // many, requantize to the maximum amount for the target format.
+ if (plte.n_entries > max_colors)
+ goto requantize;
+#endif
+
+ pal = n64texconv_palette_new(plte.n_entries, pal_fmt);
+ if (pal == NULL)
+ goto error_post_create_img;
+
+ struct spng_trns trns;
+ rv = spng_get_trns(ctx, &trns);
+ if (rv == 0) {
+ // Read palette transparency from here
+ assert(trns.n_type3_entries == plte.n_entries);
+ for (size_t i = 0; i < plte.n_entries; i++) {
+ pal->texels[i].r = plte.entries[i].red;
+ pal->texels[i].g = plte.entries[i].green;
+ pal->texels[i].b = plte.entries[i].blue;
+ pal->texels[i].a = trns.type3_alpha[i];
+ }
+ } else {
+ // Treat as opaque if trns is not present
+ for (size_t i = 0; i < plte.n_entries; i++) {
+ pal->texels[i].r = plte.entries[i].red;
+ pal->texels[i].g = plte.entries[i].green;
+ pal->texels[i].b = plte.entries[i].blue;
+ pal->texels[i].a = 0xFF;
+ }
+ }
+
+ // Fill color indices
+ size_t nidxbytes;
+ rv = spng_decoded_image_size(ctx, SPNG_FMT_RAW, &nidxbytes);
+ assert(rv == 0);
+ assert(nidxbytes * 4 == nbytes);
+ rv = spng_decode_image(ctx, (void *)img->color_indices, nidxbytes, SPNG_FMT_RAW, 0);
+ assert(rv == 0);
+ } else {
+ // Input is not an indexed png, quantize and generate palette
+#if 0
+ requantize: // Input is an indexed png but has too many colors, requantize with new palette
+#endif
+ rv = spng_decode_image(ctx, (void *)img->texels, nbytes, SPNG_FMT_RGBA8, 0);
+ assert(rv == 0);
+
+ pal = n64texconv_palette_new(max_colors, pal_fmt);
+ if (pal == NULL)
+ goto error_post_create_img;
+
+ n64texconv_quantize(img->color_indices, pal->texels, &pal->count, img->texels, width, height, max_colors,
+ 0.5f);
+ }
+
+ // Populate texels from color indices and palette
+ for (size_t i = 0; i < width * height; i++)
+ img->texels[i] = pal->texels[img->color_indices[i]];
+ } else {
+ rv = spng_decode_image(ctx, (void *)img->texels, nbytes, SPNG_FMT_RGBA8, 0);
+ assert(rv == 0);
+ }
+ spng_ctx_free(ctx);
+ fclose(png);
+
+ img->pal = pal;
+
+ n64texconv_image_sync(img);
+ return img;
+
+error_post_create_img:
+ n64texconv_image_free(img);
+error_post_open_png:
+ spng_ctx_free(ctx);
+ fclose(png);
+ return NULL;
+}
+
+struct n64_image *
+n64texconv_image_from_bin(void *data, size_t width, size_t height, int fmt, int siz, struct n64_palette *pal,
+ bool preswapped)
+{
+ assert(data != NULL);
+ assert((fmt == G_IM_FMT_CI && pal != NULL) || (fmt != G_IM_FMT_CI && pal == NULL));
+
+ size_t ntexels = width * height;
+ struct n64_image *img = n64texconv_image_new(width, height, fmt, siz, pal);
+ if (img == NULL)
+ return NULL;
+
+ if (preswapped) {
+ // TODO unswap data
+ }
+
+ struct texel_layout *layout = &texel_layouts[FMT_SIZ(fmt, siz)];
+ assert(layout != NULL);
+
+ if (fmt == G_IM_FMT_CI) {
+ layout->unpack_ci(img->color_indices, data, ntexels, img->pal->count);
+ for (size_t i = 0; i < ntexels; i++)
+ img->texels[i].w = pal->texels[img->color_indices[i]].w;
+ } else {
+ layout->unpack(img->texels, data, ntexels);
+ }
+ return img;
+}
+
+/**
+ * Given an existing image, create a new image with the new format and size.
+ *
+ * This operation is very often a lossy process, do not expect matching round-trips through reformat; depending on the
+ * target format quality is often lost, sometimes severely.
+ *
+ * This process is typically for converting truecolor png to the optimal N64 format if the format was left unspecified
+ * when reading in the png, in a matching context the format should always be explicitly specified so that no
+ * reformatting is done.
+ */
+struct n64_image *
+n64texconv_image_reformat(struct n64_image *img, int fmt, int siz, struct n64_palette *new_pal)
+{
+ assert(img != NULL);
+
+ if (fmt == FMT_NONE || siz == SIZ_NONE) {
+ // TODO determine optimal format for data
+ }
+
+ size_t width = img->width;
+ size_t height = img->height;
+ size_t ntexels = width * height;
+
+ struct n64_image *new_img = n64texconv_image_new(width, height, fmt, siz, NULL);
+ if (new_img == NULL)
+ return NULL;
+
+ bool src_ci = img->fmt == G_IM_FMT_CI;
+ bool dst_ci = fmt == G_IM_FMT_CI;
+ bool siz_changed = siz != img->siz;
+
+ if (dst_ci && (!src_ci || siz_changed)) {
+ // Converting non-CI to CI, or CI->CI of different size
+
+ size_t max_colors = (siz == G_IM_SIZ_8b) ? 256 : 16;
+
+ // Set color indices pointer if coming from non-CI
+ if (new_img->color_indices == NULL)
+ new_img->color_indices = (void *)(new_img->texels + ntexels);
+
+ if (new_pal != NULL) {
+ // Use the provided new palette
+ new_img->pal = new_pal;
+
+ // Make sure the new palette is of an appropriate size for the bit depth
+ if (new_pal->count > max_colors) {
+ n64texconv_image_free(new_img);
+ return NULL;
+ }
+
+ // Map to the palette
+ for (size_t i = 0; i < width * height; i++) {
+ for (size_t j = 0; j < new_pal->count; j++) {
+ if (new_img->texels[i].w == new_pal->texels[j].w) {
+ new_img->color_indices[i] = j;
+ goto got;
+ }
+ }
+ // Failed to find texel in palette
+ n64texconv_image_free(new_img);
+ return NULL;
+ got:;
+ }
+ } else {
+ // Generate a new palette
+ struct n64_palette *pal = n64texconv_palette_new(max_colors, G_IM_FMT_RGBA); // TODO IA palettes
+ if (pal == NULL) {
+ n64texconv_image_free(new_img);
+ return NULL;
+ }
+ new_img->pal = pal;
+
+ // Quantize and fill color indices
+ n64texconv_quantize(new_img->color_indices, pal->texels, &pal->count, new_img->texels, width, height,
+ max_colors, 0.5f);
+ // Replace old texels
+ for (size_t i = 0; i < width * height; i++) {
+ new_img->texels[i] = pal->texels[new_img->color_indices[i]];
+ }
+ }
+ } else {
+ // Copy texels
+ memcpy(new_img->texels, img->texels, ntexels * sizeof(struct color));
+ if (dst_ci)
+ memcpy(new_img->color_indices, img->color_indices, ntexels * sizeof(uint8_t));
+ }
+
+ // Invalidate color indices if non-CI
+ if (!dst_ci)
+ new_img->color_indices = NULL;
+
+ // Sync texels to format
+ n64texconv_image_sync(new_img);
+ //#pragma GCC diagnostic push
+ //#pragma GCC diagnostic ignored "-Wanalyzer-malloc-leak"
+ // Annoyingly the GCC static analyzer considers pal to be leaked here, but it's reachable by the assignment
+ // to new_img...
+ return new_img;
+ //#pragma GCC diagnostic pop
+}
+
+/**
+ * Writes this texture out to a png file. If this texture is CI and was read in from binary or from an indexed png it
+ * will preserve the color indices and palette of the original if it has not since been reformatted in order to
+ * facilitate matching in a roundtrip of 'bin -> png -> file -> png -> bin'.
+ */
+int
+n64texconv_image_to_png(const char *outpath, struct n64_image *img, bool intensity_alpha)
+{
+ assert(outpath != NULL);
+ assert(img != NULL);
+
+ // For intensity images, we don't always want to write alpha (but sometimes we do), intensity images can be either
+ // RGB channel or Alpha channel but often not both. The `intensity_alpha` option determines whether to write PNGs
+ // with or without alpha, both will roundtrip identically.
+ bool has_alpha = (img->fmt != G_IM_FMT_I) || intensity_alpha;
+
+ size_t ntexels = img->width * img->height;
+
+ if (img->fmt == G_IM_FMT_CI) {
+ assert(img->color_indices != NULL); // CI textures must have color indices
+ assert(img->pal != NULL); // Writing CI to png must have a palette supplied
+ n64texconv_palette_sync(img->pal);
+ }
+
+ // Ensure output is visually precise
+ n64texconv_image_sync(img);
+
+ // Write the png, either truecolor or indexed
+
+ FILE *png = fopen(outpath, "wb");
+ if (png == NULL)
+ return -1;
+ struct spng_ctx *ctx = spng_ctx_new(SPNG_CTX_ENCODER);
+ int rv = spng_set_png_file(ctx, png);
+ assert(rv == 0);
+ rv = spng_set_image_limits(ctx, img->width, img->height);
+ assert(rv == 0);
+
+ uint8_t color_type;
+ if (img->fmt == G_IM_FMT_CI) {
+ color_type = SPNG_COLOR_TYPE_INDEXED;
+ } else {
+ color_type = (has_alpha) ? SPNG_COLOR_TYPE_TRUECOLOR_ALPHA : SPNG_COLOR_TYPE_TRUECOLOR;
+ }
+
+ struct spng_ihdr ihdr = {
+ .width = img->width,
+ .height = img->height,
+ .bit_depth = 8,
+ .color_type = color_type,
+ .compression_method = 0,
+ .filter_method = 0,
+ .interlace_method = 0,
+ };
+ rv = spng_set_ihdr(ctx, &ihdr);
+ assert(rv == 0);
+
+ if (img->fmt == G_IM_FMT_CI) {
+ struct n64_palette *pal = img->pal;
+ assert(pal != NULL);
+
+ // Ensure palette is visually precise
+ rv = n64texconv_palette_sync(pal);
+ assert(rv == 0);
+
+ // Write palette
+ struct spng_plte plte = { 0 };
+ plte.n_entries = pal->count;
+ assert(pal->count <= 256);
+ memcpy(plte.entries, pal->texels, pal->count * 4);
+ rv = spng_set_plte(ctx, &plte);
+ assert(rv == 0);
+
+ // Write palette alphas
+ struct spng_trns trns = { 0 };
+ trns.n_type3_entries = pal->count;
+ for (size_t i = 0; i < pal->count; i++) {
+ trns.type3_alpha[i] = pal->texels[i].a;
+ }
+ rv = spng_set_trns(ctx, &trns);
+ assert(rv == 0);
+
+ // Write color indices
+ rv = spng_encode_image(ctx, img->color_indices, ntexels * sizeof(uint8_t), SPNG_FMT_PNG, SPNG_ENCODE_FINALIZE);
+ assert(rv == 0);
+ } else {
+ void *out = img->texels;
+ size_t outsize = ntexels * sizeof(struct color);
+ if (!has_alpha) {
+ uint8_t *rgb = malloc(ntexels * 3);
+ assert(rgb != NULL);
+ size_t j = 0;
+ for (size_t i = 0; i < ntexels; i++) {
+ rgb[j++] = img->texels[i].r;
+ rgb[j++] = img->texels[i].g;
+ rgb[j++] = img->texels[i].b;
+ }
+ out = rgb;
+ outsize = ntexels * 3;
+ }
+ // Write texels
+ rv = spng_encode_image(ctx, out, outsize, SPNG_FMT_PNG, SPNG_ENCODE_FINALIZE);
+ assert(rv == 0);
+ if (!has_alpha)
+ free(out);
+ }
+
+ spng_ctx_free(ctx);
+ fclose(png);
+
+ return 0;
+}
+
+void *
+n64texconv_image_to_bin(struct n64_image *img, bool pad_to_8b, bool preswap)
+{
+ assert(img != NULL);
+
+ size_t ntexels = img->width * img->height;
+ int fmt = img->fmt;
+ int siz = img->siz;
+
+ // Reserve output buffer
+ size_t size_bytes = texel_size_bytes(ntexels, siz);
+ size_t size_bytes_aligned = ALIGN8(size_bytes);
+ void *out = malloc(size_bytes_aligned);
+ if (out == NULL)
+ return NULL;
+
+ // Pack into output format
+ struct texel_layout *layout = &texel_layouts[FMT_SIZ(fmt, siz)];
+ assert(layout != NULL);
+ if (fmt == G_IM_FMT_CI) {
+ assert(img->pal != NULL);
+ layout->pack_ci(out, img->color_indices, ntexels, img->pal->count);
+ } else {
+ assert(img->pal == NULL);
+ layout->pack(out, img->texels, ntexels);
+ }
+
+ // Pad to 8-byte alignment if requested
+ if (pad_to_8b && size_bytes != size_bytes_aligned) {
+ memset((uint8_t *)out + size_bytes, 0, size_bytes_aligned - size_bytes);
+ }
+
+ // Perform dxt=0 word swapping if requested
+ if (preswap) {
+ // TODO implement preswap
+ }
+
+ return out;
+}
+
+int
+n64texconv_image_to_c(char **out, size_t *size_out, struct n64_image *img, bool pad_to_8b, bool preswap,
+ unsigned int byte_width)
+{
+ assert(out != NULL);
+ assert(size_out != NULL);
+ assert(img != NULL);
+
+ size_t nbytes = texel_size_bytes(img->width * img->height, img->siz);
+ void *bin = n64texconv_image_to_bin(img, pad_to_8b, preswap);
+ if (bin == NULL)
+ return -1;
+ nbytes = pad_to_8b ? ALIGN8(nbytes) : nbytes;
+ int rv = bin2c(out, size_out, bin, nbytes, 0, byte_width);
+ free(bin);
+ return rv;
+}
+
+int
+n64texconv_image_to_c_file(const char *out_path, struct n64_image *img, bool pad_to_8b, bool preswap,
+ unsigned int byte_width)
+{
+ assert(out_path != NULL);
+ assert(img != NULL);
+
+ size_t nbytes = texel_size_bytes(img->width * img->height, img->siz);
+ void *bin = n64texconv_image_to_bin(img, pad_to_8b, preswap);
+ if (bin == NULL)
+ return -1;
+ nbytes = pad_to_8b ? ALIGN8(nbytes) : nbytes;
+ int rv = bin2c_file(out_path, bin, nbytes, 0, byte_width);
+ free(bin);
+ return rv;
+}
+
+
+
+// ********************************************************************************************************************
+// Others
+// ********************************************************************************************************************
+
+const char *
+n64texconv_png_extension(struct n64_image *img)
+{
+ assert(img != NULL);
+
+ struct texel_layout *layout = &texel_layouts[FMT_SIZ(img->fmt, img->siz)];
+ assert(layout != NULL);
+ return layout->name;
+}
+
+/* This is just for the python interface */
+void
+n64texconv_free(void *p)
+{
+ assert(p != NULL);
+ free(p);
+}
diff --git a/tools/assets/n64texconv/src/libn64texconv/n64texconv.h b/tools/assets/n64texconv/src/libn64texconv/n64texconv.h
new file mode 100644
index 000000000..1c2dd98fc
--- /dev/null
+++ b/tools/assets/n64texconv/src/libn64texconv/n64texconv.h
@@ -0,0 +1,122 @@
+/* SPDX-FileCopyrightText: Copyright (C) 2025 ZeldaRET */
+/* SPDX-License-Identifier: MIT */
+#ifndef N64TEXCONV_H
+#define N64TEXCONV_H
+
+#include
+#include
+#include
+
+#define FMT_NONE -1
+#define FMT_MAX 5
+#define G_IM_FMT_RGBA 0
+#define G_IM_FMT_YUV 1
+#define G_IM_FMT_CI 2
+#define G_IM_FMT_IA 3
+#define G_IM_FMT_I 4
+
+#define SIZ_NONE -1
+#define SIZ_MAX 4
+#define G_IM_SIZ_4b 0
+#define G_IM_SIZ_8b 1
+#define G_IM_SIZ_16b 2
+#define G_IM_SIZ_32b 3
+
+struct color {
+ union {
+ struct {
+ uint8_t r, g, b, a;
+ };
+ uint32_t w;
+ };
+};
+
+static inline __attribute__((always_inline)) size_t
+texel_size_bytes(size_t ntexels, int siz)
+{
+ return (siz == G_IM_SIZ_4b) ? (ntexels / 2) : (ntexels * ((1 << (unsigned)siz) >> 1));
+}
+
+struct n64_palette {
+ struct color *texels;
+ int fmt;
+ size_t count;
+};
+
+struct n64_palette *
+n64texconv_palette_new(size_t count, int fmt);
+
+void
+n64texconv_palette_free(struct n64_palette *pal);
+
+struct n64_palette *
+n64texconv_palette_copy(struct n64_palette *pal);
+
+struct n64_palette *
+n64texconv_palette_reformat(struct n64_palette *pal, int fmt);
+
+struct n64_palette *
+n64texconv_palette_from_png(const char *path, int fmt);
+
+struct n64_palette *
+n64texconv_palette_from_bin(void *data, size_t count, int fmt);
+
+int
+n64texconv_palette_to_png(const char *outpath, struct n64_palette *pal);
+
+void *
+n64texconv_palette_to_bin(struct n64_palette *pal, bool pad_to_8b);
+
+int
+n64texconv_palette_to_c(char **out, size_t *size_out, struct n64_palette *pal, bool pad_to_8b, unsigned int byte_width);
+
+int
+n64texconv_palette_to_c_file(const char *out_path, struct n64_palette *pal, bool pad_to_8b, unsigned int byte_width);
+
+struct n64_image {
+ size_t width;
+ size_t height;
+ int fmt;
+ int siz;
+ struct n64_palette *pal;
+ struct color *texels;
+ uint8_t *color_indices;
+};
+
+struct n64_image *
+n64texconv_image_new(size_t width, size_t height, int fmt, int siz, struct n64_palette *pal);
+
+void
+n64texconv_image_free(struct n64_image *img);
+
+struct n64_image *
+n64texconv_image_copy(struct n64_image *img);
+
+struct n64_image *
+n64texconv_image_from_png(const char *path, int fmt, int siz, int pal_fmt);
+
+struct n64_image *
+n64texconv_image_from_bin(void *data, size_t width, size_t height, int fmt, int siz, struct n64_palette *pal,
+ bool preswapped);
+
+struct n64_image *
+n64texconv_image_reformat(struct n64_image *img, int fmt, int siz, struct n64_palette *pal);
+
+int
+n64texconv_image_to_png(const char *outpath, struct n64_image *img, bool intensity_alpha);
+
+void *
+n64texconv_image_to_bin(struct n64_image *img, bool pad_to_8b, bool preswap);
+
+int
+n64texconv_image_to_c(char **out, size_t *size_out, struct n64_image *img, bool pad_to_8b, bool preswap,
+ unsigned int byte_width);
+
+int
+n64texconv_image_to_c_file(const char *out_path, struct n64_image *img, bool pad_to_8b, bool preswap,
+ unsigned int byte_width);
+
+const char *
+n64texconv_png_extension(struct n64_image *img);
+
+#endif
diff --git a/tools/bin2c.c b/tools/bin2c.c
new file mode 100644
index 000000000..3faa3be54
--- /dev/null
+++ b/tools/bin2c.c
@@ -0,0 +1,174 @@
+/* SPDX-FileCopyrightText: (C) 2025 ZeldaRET */
+/* SPDX-License-Identifier: MIT */
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include "endian.h"
+
+#define NORETURN __attribute__((noreturn))
+
+static void NORETURN
+verror(const char *fmt, va_list args)
+{
+ fputs("\x1b[91merror\x1b[97m: ", stderr);
+ vfprintf(stderr, fmt, args);
+ fputs("\x1b[0m", stderr);
+ exit(EXIT_FAILURE);
+}
+
+static void NORETURN
+error(const char *fmt, ...)
+{
+ va_list args;
+ va_start(args, fmt);
+ verror(fmt, args);
+ va_end(args);
+}
+
+static void NORETURN
+error_post_open(const char *path_to_rm, FILE *file_to_rm, const char *fmt, ...)
+{
+ // cleanup output file
+ fclose(file_to_rm);
+ if (remove(path_to_rm) != 0)
+ fprintf(stderr, "error calling remove(): %s", strerror(errno));
+
+ // error as normal
+ va_list args;
+ va_start(args, fmt);
+ verror(fmt, args);
+ va_end(args);
+}
+
+static void NORETURN
+usage(const char *progname)
+{
+ fprintf(stderr,
+ "usage: %s -t [-pad] input.bin output.inc.c" "\n"
+ " fmt must be one of { 1, 2, 4, 8 }" "\n"
+ " if pad, align to fmt by filling with 0s, otherwise error if input is not aligned" "\n",
+ progname);
+ exit(EXIT_FAILURE);
+}
+
+#define BYTES_PER_ROW 32
+#define LINE_MASK (BYTES_PER_ROW - 1)
+
+int
+main(int argc, char **argv)
+{
+ const char *progname = argv[0];
+ const char *inpath = NULL;
+ const char *outpath = NULL;
+ const char *fmt_opt = NULL;
+ int fmt = 0;
+ bool pad = false;
+
+ // Collect arguments
+
+ int narg = 0;
+ for (int i = 1; i < argc; i++) {
+ if (argv[i][0] == '-') {
+ if (strcmp(argv[i], "-t") == 0) {
+ if (++i == argc)
+ usage(progname);
+ fmt_opt = argv[i];
+ char *end;
+ fmt = strtol(argv[i], &end, 10);
+ if (end != &argv[i][strlen(argv[i])])
+ error("Invalid base 10 integer %s\n", argv[i]);
+ } else if (strcmp(argv[i], "-pad") == 0) {
+ pad = true;
+ } else {
+ usage(progname);
+ }
+ } else {
+ switch (narg) {
+ case 0:
+ inpath = argv[i];
+ break;
+ case 1:
+ outpath = argv[i];
+ break;
+ default:
+ usage(progname);
+ break;
+ }
+ narg++;
+ }
+ }
+
+ // Check arguments
+
+ if (inpath == NULL || outpath == NULL || fmt_opt == NULL)
+ usage(progname);
+
+ if (fmt != 1 && fmt != 2 && fmt != 4 && fmt != 8)
+ error("Invalid fmt option '%s'. Valid options: [1, 2, 4, 8]\n", fmt_opt);
+
+ // Open the input binary file
+
+ FILE *infile = fopen(inpath, "rb");
+ if (infile == NULL)
+ error("Failed to open input file '%s' for reading: %s\n", inpath, strerror(errno));
+
+ // Get size
+
+ if (fseek(infile, 0, SEEK_END) != 0)
+ error("Could not ascertain input file size, could not seek to end: %s\n", strerror(errno));
+ size_t file_size = ftell(infile);
+ if (fseek(infile, 0, SEEK_SET) != 0)
+ error("Could not ascertain input file size, could not seek to start: %s\n", strerror(errno));
+
+ // Check alignment
+
+ if ((file_size & (fmt - 1)) != 0 && !pad) {
+ // Not aligned to data size and don't pad, error
+ error("Input file '%s' size (%lu) is not aligned to %d bytes\n", inpath, file_size, fmt);
+ }
+
+ // Open the output text file
+
+ FILE *outfile = fopen(outpath, "w");
+ if (outfile == NULL)
+ error("Failed to open output file '%s' for writing: %s\n", outpath, strerror(errno));
+
+ // Write data. If the input binary size was not aligned we either don't get this far or the option
+ // to pad with 0s is set.
+
+ bool was_newline = false;
+ for (size_t p = 0; p < file_size; p += fmt) {
+ size_t rem = fmt;
+ if (rem > file_size - p) // For any remaining unaligned data, rest will be padded with 0
+ rem = file_size - p;
+
+ // Read input
+ uint64_t d = 0;
+ if (fread(&d, 1, rem, infile) != rem)
+ error_post_open(outpath, outfile, "Error reading from input file '%s': %s\n", inpath, strerror(errno));
+
+ // Byteswap + shift
+ d = be64toh(d) >> (64 - 8 * fmt);
+
+ // Write output
+ bool was_newline = (((p + fmt) & LINE_MASK) == 0);
+ char end = was_newline ? '\n' : ' ';
+ if (fprintf(outfile, "0x%0*" PRIX64 ",%c", 2 * fmt, d, end) < 0)
+ error_post_open(outpath, outfile, "Error writing to output file '%s': %s\n", outpath, strerror(errno));
+ }
+ if (!was_newline) {
+ if (fputs("\n", outfile) == EOF)
+ error_post_open(outpath, outfile, "Error writing to output file '%s': %s\n", outpath, strerror(errno));
+ }
+
+ fclose(infile);
+ fclose(outfile);
+ return EXIT_SUCCESS;
+}
diff --git a/tools/endian.h b/tools/endian.h
new file mode 100644
index 000000000..d69e2e667
--- /dev/null
+++ b/tools/endian.h
@@ -0,0 +1,67 @@
+#ifndef ENDIAN_H_
+#define ENDIAN_H_
+
+#if defined(__linux__) || defined(__CYGWIN__)
+#include
+#elif defined(__APPLE__)
+#include
+
+#define htobe16(x) OSSwapHostToBigInt16(x)
+#define htole16(x) OSSwapHostToLittleInt16(x)
+#define be16toh(x) OSSwapBigToHostInt16(x)
+#define le16toh(x) OSSwapLittleToHostInt16(x)
+
+#define htobe32(x) OSSwapHostToBigInt32(x)
+#define htole32(x) OSSwapHostToLittleInt32(x)
+#define be32toh(x) OSSwapBigToHostInt32(x)
+#define le32toh(x) OSSwapLittleToHostInt32(x)
+
+#define htobe64(x) OSSwapHostToBigInt64(x)
+#define htole64(x) OSSwapHostToLittleInt64(x)
+#define be64toh(x) OSSwapBigToHostInt64(x)
+#define le64toh(x) OSSwapLittleToHostInt64(x)
+#else
+
+#if !defined(__BYTE_ORDER__)
+#error "No endian define provided by compiler"
+#endif
+
+#if (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__)
+
+#define htobe16(x) (x)
+#define htole16(x) __builtin_bswap16(x)
+#define be16toh(x) (x)
+#define le16toh(x) __builtin_bswap16(x)
+
+#define htobe32(x) (x)
+#define htole32(x) __builtin_bswap32(x)
+#define be32toh(x) (x)
+#define le32toh(x) __builtin_bswap32(x)
+
+#define htobe64(x) (x)
+#define htole64(x) __builtin_bswap64(x)
+#define be64toh(x) (x)
+#define le64toh(x) __builtin_bswap64(x)
+
+#else
+
+#define htobe16(x) __builtin_bswap16(x)
+#define htole16(x) (x)
+#define be16toh(x) __builtin_bswap16(x)
+#define le16toh(x) (x)
+
+#define htobe32(x) __builtin_bswap32(x)
+#define htole32(x) (x)
+#define be32toh(x) __builtin_bswap32(x)
+#define le32toh(x) (x)
+
+#define htobe64(x) __builtin_bswap64(x)
+#define htole64(x) (x)
+#define be64toh(x) __builtin_bswap64(x)
+#define le64toh(x) (x)
+
+#endif
+
+#endif
+
+#endif
diff --git a/tools/fix_bss.py b/tools/fix_bss.py
index 2a775765a..61cb4985d 100755
--- a/tools/fix_bss.py
+++ b/tools/fix_bss.py
@@ -170,9 +170,9 @@ def get_file_pointers(
# For relocations against a global symbol, subtract the addend so that the pointer
# is for the start of the symbol. This can help deal with things like STACK_TOP
- # (where the pointer is past the end of the symbol) or negative addends. If the
- # relocation is against a section however, it's not useful to subtract the addend,
- # so we keep it as-is and hope for the best.
+ # (where the pointer is past the end of the symbol) or negative addends. We can't
+ # do this for relocations against a section though, since we need the addend to
+ # distinguish between different static variables.
if reloc.name.startswith("."): # section
addend = reloc.addend
else: # symbol
@@ -446,13 +446,13 @@ def determine_base_bss_ordering(
new_symbol = None
new_offset = 0
for symbol in build_bss_symbols:
- if (
- symbol.offset <= build_offset
- and build_offset < symbol.offset + symbol.size
- ):
+ # To handle one-past-the-end pointers, we check <= instead of < for the symbol end.
+ # This won't work if there is another symbol right after this one, since we'll
+ # attribute this pointer to that symbol instead. This could prevent us from solving
+ # BSS ordering, but often the two symbols are adjacent in the baserom too so it works anyway.
+ if symbol.offset <= build_offset <= symbol.offset + symbol.size:
new_symbol = symbol
new_offset = base_offset - (build_offset - symbol.offset)
- break
if new_symbol is None:
if p.addend > 0: