mirror of https://github.com/sm64pc/sm64pc.git
QOL_FIXES all in one giant commit (thanks Aloxado320 for a lot of these)
This commit is contained in:
parent
fc5cb66f07
commit
8f8ed8ad49
141
Makefile
141
Makefile
|
@ -41,8 +41,8 @@ TARGET_BITS ?= 0
|
|||
BETTERCAMERA ?= 0
|
||||
# Disable no drawing distance by default
|
||||
NODRAWINGDISTANCE ?= 0
|
||||
# Disable texture fixes by default (helps with them purists)
|
||||
TEXTURE_FIX ?= 0
|
||||
# Disable QoL fixes by default (helps with them purists)
|
||||
QOL_FIXES ?= 0
|
||||
# Enable extended options menu by default
|
||||
EXT_OPTIONS_MENU ?= 1
|
||||
# Disable text-based save-files by default
|
||||
|
@ -103,7 +103,15 @@ ifeq ($(WINDOWS_BUILD),1)
|
|||
TARGET_BITS = 32
|
||||
NO_BZERO_BCOPY := 1
|
||||
else ifeq ($(CROSS),x86_64-w64-mingw32.static-)
|
||||
TARGET_ARCH = i386pep
|
||||
TARGET_BITS = 64
|
||||
NO_BZERO_BCOPY := 1
|
||||
else ifeq ($(CROSS),mxe-i686-w64-mingw32.static-)
|
||||
TARGET_ARCH = i386pe
|
||||
TARGET_BITS = 32
|
||||
NO_BZERO_BCOPY := 1
|
||||
else ifeq ($(CROSS),mxe-x86_64-w64-mingw32.static-)
|
||||
TARGET_ARCH = i386pep
|
||||
TARGET_BITS = 64
|
||||
NO_BZERO_BCOPY := 1
|
||||
endif
|
||||
|
@ -117,14 +125,11 @@ endif
|
|||
|
||||
ifeq ($(VERSION),jp)
|
||||
VERSION_DEF := VERSION_JP
|
||||
else
|
||||
ifeq ($(VERSION),us)
|
||||
else ifeq ($(VERSION),us)
|
||||
VERSION_DEF := VERSION_US
|
||||
else
|
||||
ifeq ($(VERSION),eu)
|
||||
else ifeq ($(VERSION),eu)
|
||||
VERSION_DEF := VERSION_EU
|
||||
else
|
||||
ifeq ($(VERSION),sh)
|
||||
else ifeq ($(VERSION),sh)
|
||||
$(warning Building SH is experimental and is prone to breaking. Try at your own risk.)
|
||||
VERSION_DEF := VERSION_SH
|
||||
# TODO: GET RID OF THIS!!! We should mandate assets for Shindou like EU but we dont have the addresses extracted yet so we'll just pretend you have everything extracted for now.
|
||||
|
@ -132,9 +137,6 @@ ifeq ($(VERSION),sh)
|
|||
else
|
||||
$(error unknown version "$(VERSION)")
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
|
||||
TARGET := sm64.$(VERSION)
|
||||
VERSION_CFLAGS := -D$(VERSION_DEF) -D_LANGUAGE_C
|
||||
|
@ -155,34 +157,26 @@ ifeq ($(GRUCODE),f3dex) # Fast3DEX
|
|||
GRUCODE_ASFLAGS := --defsym F3DEX_GBI_SHARED=1
|
||||
TARGET := $(TARGET).f3dex
|
||||
COMPARE := 0
|
||||
else
|
||||
ifeq ($(GRUCODE),f3dex2) # Fast3DEX2
|
||||
else ifeq ($(GRUCODE),f3dex2) # Fast3DEX2
|
||||
GRUCODE_DEF := F3DEX_GBI_2
|
||||
GRUCODE_ASFLAGS := --defsym F3DEX_GBI_SHARED=1
|
||||
TARGET := $(TARGET).f3dex2
|
||||
COMPARE := 0
|
||||
else
|
||||
ifeq ($(GRUCODE),f3dex2e) # Fast3DEX2 Extended (PC default)
|
||||
else ifeq ($(GRUCODE),f3dex2e) # Fast3DEX2 Extended (PC default)
|
||||
GRUCODE_DEF := F3DEX_GBI_2E
|
||||
TARGET := $(TARGET).f3dex2e
|
||||
COMPARE := 0
|
||||
else
|
||||
ifeq ($(GRUCODE),f3d_new) # Fast3D 2.0H (Shindou)
|
||||
else ifeq ($(GRUCODE),f3d_new) # Fast3D 2.0H (Shindou)
|
||||
GRUCODE_DEF := F3D_NEW
|
||||
TARGET := $(TARGET).f3d_new
|
||||
COMPARE := 0
|
||||
else
|
||||
ifeq ($(GRUCODE),f3dzex) # Fast3DZEX (2.0J / Animal Forest - Dōbutsu no Mori)
|
||||
else ifeq ($(GRUCODE),f3dzex) # Fast3DZEX (2.0J / Animal Forest - Dōbutsu no Mori)
|
||||
$(warning Fast3DZEX is experimental. Try at your own risk.)
|
||||
GRUCODE_DEF := F3DEX_GBI_2
|
||||
GRUCODE_ASFLAGS := --defsym F3DEX_GBI_SHARED=1
|
||||
TARGET := $(TARGET).f3dzex
|
||||
COMPARE := 0
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
|
||||
GRUCODE_CFLAGS := -D$(GRUCODE_DEF)
|
||||
GRUCODE_ASFLAGS := $(GRUCODE_ASFLAGS) --defsym $(GRUCODE_DEF)=1
|
||||
|
@ -227,8 +221,7 @@ endif
|
|||
# on tools and assets, and we use directory globs further down
|
||||
# in the makefile that we want should cover assets.)
|
||||
|
||||
ifneq ($(MAKECMDGOALS),clean)
|
||||
ifneq ($(MAKECMDGOALS),distclean)
|
||||
ifeq (,$(findstring clean,$(MAKECMDGOALS)))
|
||||
|
||||
# Make sure assets exist
|
||||
NOEXTRACT ?= 0
|
||||
|
@ -245,7 +238,6 @@ ifeq ($(DUMMY),FAIL)
|
|||
$(error Failed to build tools)
|
||||
endif
|
||||
|
||||
endif
|
||||
endif
|
||||
|
||||
################ Target Executable and Sources ###############
|
||||
|
@ -262,18 +254,13 @@ endif
|
|||
LIBULTRA := $(BUILD_DIR)/libultra.a
|
||||
|
||||
ifeq ($(TARGET_WEB),1)
|
||||
EXE := $(BUILD_DIR)/$(TARGET).html
|
||||
else
|
||||
ifeq ($(WINDOWS_BUILD),1)
|
||||
EXE := $(BUILD_DIR)/$(TARGET).exe
|
||||
|
||||
else # Linux builds/binary namer
|
||||
ifeq ($(TARGET_RPI),1)
|
||||
EXE := $(BUILD_DIR)/$(TARGET).arm
|
||||
else
|
||||
EXE := $(BUILD_DIR)/$(TARGET)
|
||||
endif
|
||||
endif
|
||||
EXE := $(BUILD_DIR)/$(TARGET).html
|
||||
else ifeq ($(WINDOWS_BUILD),1)
|
||||
EXE := $(BUILD_DIR)/$(TARGET).exe
|
||||
else ifeq ($(TARGET_RPI),1) # Linux builds/binary namer
|
||||
EXE := $(BUILD_DIR)/$(TARGET).arm
|
||||
else
|
||||
EXE := $(BUILD_DIR)/$(TARGET)
|
||||
endif
|
||||
|
||||
ELF := $(BUILD_DIR)/$(TARGET).elf
|
||||
|
@ -322,31 +309,29 @@ ifeq ($(TARGET_RPI),1)
|
|||
machine = $(shell sh -c 'uname -m 2>/dev/null || echo unknown')
|
||||
# Raspberry Pi B+, Zero, etc
|
||||
ifneq (,$(findstring armv6l,$(machine)))
|
||||
OPT_FLAGS := -march=armv6zk+fp -mfpu=vfp -Ofast
|
||||
endif
|
||||
OPT_FLAGS := -march=armv6zk+fp -mfpu=vfp -Ofast
|
||||
endif
|
||||
|
||||
# Raspberry Pi 2 and 3 in ARM 32bit mode
|
||||
ifneq (,$(findstring armv7l,$(machine)))
|
||||
model = $(shell sh -c 'cat /sys/firmware/devicetree/base/model 2>/dev/null || echo unknown')
|
||||
|
||||
ifneq (,$(findstring 3,$(model)))
|
||||
OPT_FLAGS := -march=armv8-a+crc -mtune=cortex-a53 -mfpu=neon-fp-armv8 -O3
|
||||
else
|
||||
OPT_FLAGS := -march=armv7-a -mtune=cortex-a7 -mfpu=neon-vfpv4 -O3
|
||||
endif
|
||||
endif
|
||||
ifneq (,$(findstring armv7l,$(machine)))
|
||||
model = $(shell sh -c 'cat /sys/firmware/devicetree/base/model 2>/dev/null || echo unknown')
|
||||
ifneq (,$(findstring 3,$(model)))
|
||||
OPT_FLAGS := -march=armv8-a+crc -mtune=cortex-a53 -mfpu=neon-fp-armv8 -O3
|
||||
else
|
||||
OPT_FLAGS := -march=armv7-a -mtune=cortex-a7 -mfpu=neon-vfpv4 -O3
|
||||
endif
|
||||
endif
|
||||
|
||||
# RPi3 or RPi4, in ARM64 (aarch64) mode. NEEDS TESTING 32BIT.
|
||||
# DO NOT pass -mfpu stuff here, thats for 32bit ARM only and will fail for 64bit ARM.
|
||||
ifneq (,$(findstring aarch64,$(machine)))
|
||||
model = $(shell sh -c 'cat /sys/firmware/devicetree/base/model 2>/dev/null || echo unknown')
|
||||
ifneq (,$(findstring 3,$(model)))
|
||||
OPT_FLAGS := -march=armv8-a+crc -mtune=cortex-a53 -O3
|
||||
else ifneq (,$(findstring 4,$(model)))
|
||||
OPT_FLAGS := -march=armv8-a+crc+simd -mtune=cortex-a72 -O3
|
||||
endif
|
||||
|
||||
endif
|
||||
ifneq (,$(findstring aarch64,$(machine)))
|
||||
model = $(shell sh -c 'cat /sys/firmware/devicetree/base/model 2>/dev/null || echo unknown')
|
||||
ifneq (,$(findstring 3,$(model)))
|
||||
OPT_FLAGS := -march=armv8-a+crc -mtune=cortex-a53 -O3
|
||||
else ifneq (,$(findstring 4,$(model)))
|
||||
OPT_FLAGS := -march=armv8-a+crc+simd -mtune=cortex-a72 -O3
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
|
||||
# File dependencies and variables for specific files
|
||||
|
@ -457,6 +442,10 @@ else ifeq ($(WINDOWS_BUILD),1)
|
|||
LD := $(CC)
|
||||
else ifeq ($(CROSS),x86_64-w64-mingw32.static-)
|
||||
LD := $(CC)
|
||||
else ifeq ($(CROSS),mxe-i686-w64-mingw32.static-)
|
||||
LD := $(CC)
|
||||
else ifeq ($(CROSS),mxe-x86_64-w64-mingw32.static-)
|
||||
LD := $(CC)
|
||||
else
|
||||
LD := $(CXX)
|
||||
endif
|
||||
|
@ -484,7 +473,7 @@ SDLCONFIG := $(CROSS)sdl2-config
|
|||
BACKEND_CFLAGS := -DRAPI_$(RENDER_API)=1 -DWAPI_$(WINDOW_API)=1 -DAAPI_$(AUDIO_API)=1
|
||||
# can have multiple controller APIs
|
||||
BACKEND_CFLAGS += $(foreach capi,$(CONTROLLER_API),-DCAPI_$(capi)=1)
|
||||
BACKEND_LDFLAG0S :=
|
||||
BACKEND_LDFLAGS :=
|
||||
|
||||
SDL1_USED := 0
|
||||
SDL2_USED := 0
|
||||
|
@ -541,16 +530,15 @@ ifneq ($(SDL1_USED)$(SDL2_USED),00)
|
|||
endif
|
||||
|
||||
ifeq ($(WINDOWS_BUILD),1)
|
||||
CC_CHECK := $(CC) -fsyntax-only -fsigned-char $(BACKEND_CFLAGS) $(INCLUDE_CFLAGS) -Wall -Wextra -Wno-format-security $(VERSION_CFLAGS) $(GRUCODE_CFLAGS)
|
||||
CC_CHECK := $(CC) -fsyntax-only -fsigned-char $(BACKEND_CFLAGS) $(INCLUDE_CFLAGS) -Wall -Wextra $(VERSION_CFLAGS) $(GRUCODE_CFLAGS)
|
||||
CFLAGS := $(OPT_FLAGS) $(INCLUDE_CFLAGS) $(BACKEND_CFLAGS) $(VERSION_CFLAGS) $(GRUCODE_CFLAGS) -fno-strict-aliasing -fwrapv
|
||||
|
||||
else ifeq ($(TARGET_WEB),1)
|
||||
CC_CHECK := $(CC) -fsyntax-only -fsigned-char $(BACKEND_CFLAGS) $(INCLUDE_CFLAGS) -Wall -Wextra -Wno-format-security $(VERSION_CFLAGS) $(GRUCODE_CFLAGS) -s USE_SDL=2
|
||||
CC_CHECK := $(CC) -fsyntax-only -fsigned-char $(BACKEND_CFLAGS) $(INCLUDE_CFLAGS) -Wall -Wextra $(VERSION_CFLAGS) $(GRUCODE_CFLAGS) -s USE_SDL=2
|
||||
CFLAGS := $(OPT_FLAGS) $(INCLUDE_CFLAGS) $(BACKEND_CFLAGS) $(VERSION_CFLAGS) $(GRUCODE_CFLAGS) -fno-strict-aliasing -fwrapv -s USE_SDL=2
|
||||
|
||||
# Linux / Other builds below
|
||||
else
|
||||
CC_CHECK := $(CC) -fsyntax-only -fsigned-char $(BACKEND_CFLAGS) $(INCLUDE_CFLAGS) -Wall -Wextra -Wno-format-security $(VERSION_CFLAGS) $(GRUCODE_CFLAGS)
|
||||
else # Linux / Other builds below
|
||||
CC_CHECK := $(CC) -fsyntax-only -fsigned-char $(BACKEND_CFLAGS) $(INCLUDE_CFLAGS) -Wall -Wextra $(VERSION_CFLAGS) $(GRUCODE_CFLAGS)
|
||||
CFLAGS := $(OPT_FLAGS) $(INCLUDE_CFLAGS) $(BACKEND_CFLAGS) $(VERSION_CFLAGS) $(GRUCODE_CFLAGS) -fno-strict-aliasing -fwrapv
|
||||
|
||||
endif
|
||||
|
@ -581,10 +569,10 @@ ifeq ($(DISCORDRPC),1)
|
|||
CFLAGS += -DDISCORDRPC
|
||||
endif
|
||||
|
||||
# Check for texture fix option
|
||||
ifeq ($(TEXTURE_FIX),1)
|
||||
CC_CHECK += -DTEXTURE_FIX
|
||||
CFLAGS += -DTEXTURE_FIX
|
||||
# Check for QoL fix option
|
||||
ifeq ($(QOL_FIXES),1)
|
||||
CC_CHECK += -DQOL_FIXES
|
||||
CFLAGS += -DQOL_FIXES
|
||||
endif
|
||||
|
||||
# Check for extended options menu option
|
||||
|
@ -642,7 +630,7 @@ else ifeq ($(OSX_BUILD),1)
|
|||
|
||||
else
|
||||
LDFLAGS := $(BITS) -march=$(TARGET_ARCH) -lm $(BACKEND_LDFLAGS) -lpthread -ldl
|
||||
ifeq ($(NO_PIE), 1)
|
||||
ifeq ($(NO_PIE),1)
|
||||
LDFLAGS += -no-pie
|
||||
endif
|
||||
|
||||
|
@ -724,7 +712,7 @@ clean:
|
|||
$(RM) -r $(BUILD_DIR_BASE)
|
||||
|
||||
cleantools:
|
||||
$(MAKE) -s -C tools clean
|
||||
$(MAKE) -C tools clean
|
||||
|
||||
distclean:
|
||||
$(RM) -r $(BUILD_DIR_BASE)
|
||||
|
@ -770,8 +758,7 @@ $(BUILD_DIR)/levels/menu/leveldata.o: $(BUILD_DIR)/text/us/define_courses.inc.c
|
|||
$(BUILD_DIR)/levels/menu/leveldata.o: $(BUILD_DIR)/text/de/define_courses.inc.c
|
||||
$(BUILD_DIR)/levels/menu/leveldata.o: $(BUILD_DIR)/text/fr/define_courses.inc.c
|
||||
|
||||
else
|
||||
ifeq ($(VERSION),sh)
|
||||
else ifeq ($(VERSION),sh)
|
||||
TEXT_DIRS := text/jp
|
||||
$(BUILD_DIR)/bin/segment2.o: $(BUILD_DIR)/text/jp/define_text.inc.c
|
||||
|
||||
|
@ -781,13 +768,12 @@ TEXT_DIRS := text/$(VERSION)
|
|||
# non-EU encoded text inserted into segment 0x02
|
||||
$(BUILD_DIR)/bin/segment2.o: $(BUILD_DIR)/text/$(VERSION)/define_text.inc.c
|
||||
endif
|
||||
endif
|
||||
|
||||
$(BUILD_DIR)/text/%/define_courses.inc.c: text/define_courses.inc.c text/%/courses.h
|
||||
$(CPP) $(VERSION_CFLAGS) $< -o - -I text/$*/ | $(TEXTCONV) charmap.txt - $@
|
||||
|
||||
$(BUILD_DIR)/text/%/define_text.inc.c: text/define_text.inc.c text/%/courses.h text/%/dialogs.h
|
||||
$(CPP) $(VERSION_CFLAGS) $< -o - -I text/$*/ | $(TEXTCONV) charmap.txt - $@
|
||||
$(CPP) $(VERSION_CFLAGS) -Wno-trigraphs $< -o - -I text/$*/ | $(TEXTCONV) charmap.txt - $@
|
||||
|
||||
RSP_DIRS := $(BUILD_DIR)/rsp
|
||||
ALL_DIRS := $(BUILD_DIR) $(addprefix $(BUILD_DIR)/,$(SRC_DIRS) $(ASM_DIRS) $(GODDARD_SRC_DIRS) $(ULTRA_SRC_DIRS) $(ULTRA_ASM_DIRS) $(ULTRA_BIN_DIRS) $(BIN_DIRS) $(TEXTURE_DIRS) $(TEXT_DIRS) $(SOUND_SAMPLE_DIRS) $(addprefix levels/,$(LEVEL_DIRS)) include) $(MIO0_DIR) $(addprefix $(MIO0_DIR)/,$(VERSION)) $(SOUND_BIN_DIR) $(SOUND_BIN_DIR)/sequences/$(VERSION) $(RSP_DIRS)
|
||||
|
@ -918,8 +904,13 @@ $(BUILD_DIR)/include/level_headers.h: levels/level_headers.h.in
|
|||
$(BUILD_DIR)/assets/mario_anim_data.c: $(wildcard assets/anims/*.inc.c)
|
||||
$(PYTHON) tools/mario_anims_converter.py > $@
|
||||
|
||||
ifneq ($(QOL_FIXES),1)
|
||||
$(BUILD_DIR)/assets/demo_data.c: assets/demo_data.json $(wildcard assets/demos/*.bin)
|
||||
$(PYTHON) tools/demo_data_converter.py assets/demo_data.json $(VERSION_CFLAGS) > $@
|
||||
else
|
||||
$(BUILD_DIR)/assets/demo_data.c: assets/qol_demo_data.json $(wildcard assets/demos/*.bin)
|
||||
$(PYTHON) tools/demo_data_converter.py assets/qol_demo_data.json $(VERSION_CFLAGS) > $@
|
||||
endif
|
||||
|
||||
# Source code
|
||||
$(BUILD_DIR)/levels/%/leveldata.o: OPT_FLAGS := -g
|
||||
|
@ -996,7 +987,7 @@ $(BUILD_DIR)/%.o: %.s
|
|||
$(EXE): $(O_FILES) $(MIO0_FILES:.mio0=.o) $(SOUND_OBJ_FILES) $(ULTRA_O_FILES) $(GODDARD_O_FILES) $(BUILD_DIR)/$(RPC_LIBS)
|
||||
$(LD) -L $(BUILD_DIR) -o $@ $(O_FILES) $(SOUND_OBJ_FILES) $(ULTRA_O_FILES) $(GODDARD_O_FILES) $(LDFLAGS)
|
||||
|
||||
.PHONY: all clean distclean default diff test load libultra res
|
||||
.PHONY: all clean distclean cleantools default diff test load libultra res
|
||||
.PRECIOUS: $(BUILD_DIR)/bin/%.elf $(SOUND_BIN_DIR)/%.ctl $(SOUND_BIN_DIR)/%.tbl $(SOUND_SAMPLE_TABLES) $(SOUND_BIN_DIR)/%.s $(BUILD_DIR)/%
|
||||
.DELETE_ON_ERROR:
|
||||
|
||||
|
|
|
@ -12,6 +12,8 @@ const GeoLayout boo_geo[] = {
|
|||
GEO_CLOSE_NODE(),
|
||||
GEO_CLOSE_NODE(),
|
||||
GEO_CLOSE_NODE(),
|
||||
#ifndef QOL_FIXES
|
||||
GEO_CLOSE_NODE(), //! more close than open nodes
|
||||
#endif
|
||||
GEO_END(),
|
||||
};
|
||||
|
|
|
@ -12,6 +12,8 @@ const GeoLayout boo_castle_geo[] = {
|
|||
GEO_CLOSE_NODE(),
|
||||
GEO_CLOSE_NODE(),
|
||||
GEO_CLOSE_NODE(),
|
||||
#ifndef QOL_FIXES
|
||||
GEO_CLOSE_NODE(), //! more close than open nodes
|
||||
#endif
|
||||
GEO_END(),
|
||||
};
|
||||
|
|
|
@ -24,6 +24,8 @@ const GeoLayout bookend_part_geo[] = {
|
|||
GEO_CLOSE_NODE(),
|
||||
GEO_CLOSE_NODE(),
|
||||
GEO_CLOSE_NODE(),
|
||||
#ifndef QOL_FIXES
|
||||
GEO_CLOSE_NODE(), //! more close than open nodes
|
||||
#endif
|
||||
GEO_END(),
|
||||
};
|
||||
|
|
|
@ -26,6 +26,8 @@ const GeoLayout bowser_key_cutscene_geo[] = {
|
|||
GEO_CLOSE_NODE(),
|
||||
GEO_CLOSE_NODE(),
|
||||
GEO_CLOSE_NODE(),
|
||||
#ifndef QOL_FIXES
|
||||
GEO_CLOSE_NODE(), //! more close than open nodes
|
||||
#endif
|
||||
GEO_END(),
|
||||
};
|
||||
|
|
|
@ -10,9 +10,9 @@ static const Vtx burn_smoke_seg4_vertex_040217C0[] = {
|
|||
|
||||
// //! Wrong texture format. Called as rgba16, which makes the burn smoke appear
|
||||
// as a transparent black burn smoke. Probably meant to show up as white-ish
|
||||
// burn smoke, but mistakened for being intended as black smoke.
|
||||
// burn smoke, but mistaken for being intended as black smoke.
|
||||
// Due to debate in the Koopa shorts PR surrounding the fix to a similar bug,
|
||||
// said fix is on a compile-time variable. Use TEXTURE_FIX=1 at compile time
|
||||
// said fix is on a compile-time variable. Use QOL_FIXES=1 at compile time
|
||||
// to fix this.
|
||||
// 0x04021800
|
||||
ALIGNED8 static const u8 burn_smoke_seg4_texture_04021800[] = {
|
||||
|
@ -47,7 +47,7 @@ const Gfx burn_smoke_seg4_dl_04022048[] = {
|
|||
// 0x04022070 - 0x040220C8
|
||||
const Gfx burn_smoke_seg4_dl_04022070[] = {
|
||||
gsSPDisplayList(burn_smoke_seg4_dl_04022000),
|
||||
#ifdef TEXTURE_FIX
|
||||
#ifdef QOL_FIXES
|
||||
gsDPLoadTextureBlock(burn_smoke_seg4_texture_04021800, G_IM_FMT_IA, G_IM_SIZ_16b, 32, 32, 0, G_TX_CLAMP, G_TX_CLAMP, 5, 5, G_TX_NOLOD, G_TX_NOLOD),
|
||||
#else
|
||||
gsDPLoadTextureBlock(burn_smoke_seg4_texture_04021800, G_IM_FMT_RGBA, G_IM_SIZ_16b, 32, 32, 0, G_TX_CLAMP, G_TX_CLAMP, 5, 5, G_TX_NOLOD, G_TX_NOLOD),
|
||||
|
|
|
@ -17,6 +17,8 @@ const GeoLayout chain_chomp_geo[] = {
|
|||
GEO_CLOSE_NODE(),
|
||||
GEO_CLOSE_NODE(),
|
||||
GEO_CLOSE_NODE(),
|
||||
#ifndef QOL_FIXES
|
||||
GEO_CLOSE_NODE(), //! more close than open nodes
|
||||
#endif
|
||||
GEO_END(),
|
||||
};
|
||||
|
|
|
@ -24,6 +24,8 @@ const GeoLayout haunted_chair_geo[] = {
|
|||
GEO_CLOSE_NODE(),
|
||||
GEO_CLOSE_NODE(),
|
||||
GEO_CLOSE_NODE(),
|
||||
#ifndef QOL_FIXES
|
||||
GEO_CLOSE_NODE(), //! more close than open nodes
|
||||
#endif
|
||||
GEO_END(),
|
||||
};
|
||||
|
|
|
@ -21,7 +21,9 @@ const GeoLayout castle_door_geo[] = {
|
|||
GEO_CLOSE_NODE(),
|
||||
GEO_CLOSE_NODE(),
|
||||
GEO_CLOSE_NODE(),
|
||||
#ifndef QOL_FIXES
|
||||
GEO_CLOSE_NODE(), //! more close than open nodes
|
||||
#endif
|
||||
GEO_END(),
|
||||
};
|
||||
|
||||
|
@ -48,7 +50,9 @@ const GeoLayout cabin_door_geo[] = {
|
|||
GEO_CLOSE_NODE(),
|
||||
GEO_CLOSE_NODE(),
|
||||
GEO_CLOSE_NODE(),
|
||||
#ifndef QOL_FIXES
|
||||
GEO_CLOSE_NODE(), //! more close than open nodes
|
||||
#endif
|
||||
GEO_END(),
|
||||
};
|
||||
|
||||
|
@ -75,7 +79,9 @@ const GeoLayout wooden_door_geo[] = {
|
|||
GEO_CLOSE_NODE(),
|
||||
GEO_CLOSE_NODE(),
|
||||
GEO_CLOSE_NODE(),
|
||||
#ifndef QOL_FIXES
|
||||
GEO_CLOSE_NODE(), //! more close than open nodes
|
||||
#endif
|
||||
GEO_END(),
|
||||
};
|
||||
|
||||
|
@ -102,7 +108,9 @@ const GeoLayout wooden_door2_geo[] = {
|
|||
GEO_CLOSE_NODE(),
|
||||
GEO_CLOSE_NODE(),
|
||||
GEO_CLOSE_NODE(),
|
||||
#ifndef QOL_FIXES
|
||||
GEO_CLOSE_NODE(), //! more close than open nodes
|
||||
#endif
|
||||
GEO_END(),
|
||||
};
|
||||
|
||||
|
@ -129,7 +137,9 @@ const GeoLayout metal_door_geo[] = {
|
|||
GEO_CLOSE_NODE(),
|
||||
GEO_CLOSE_NODE(),
|
||||
GEO_CLOSE_NODE(),
|
||||
#ifndef QOL_FIXES
|
||||
GEO_CLOSE_NODE(), //! more close than open nodes
|
||||
#endif
|
||||
GEO_END(),
|
||||
};
|
||||
|
||||
|
@ -156,7 +166,9 @@ const GeoLayout hazy_maze_door_geo[] = {
|
|||
GEO_CLOSE_NODE(),
|
||||
GEO_CLOSE_NODE(),
|
||||
GEO_CLOSE_NODE(),
|
||||
#ifndef QOL_FIXES
|
||||
GEO_CLOSE_NODE(), //! more close than open nodes
|
||||
#endif
|
||||
GEO_END(),
|
||||
};
|
||||
|
||||
|
@ -183,7 +195,9 @@ const GeoLayout haunted_door_geo[] = {
|
|||
GEO_CLOSE_NODE(),
|
||||
GEO_CLOSE_NODE(),
|
||||
GEO_CLOSE_NODE(),
|
||||
#ifndef QOL_FIXES
|
||||
GEO_CLOSE_NODE(), //! more close than open nodes
|
||||
#endif
|
||||
GEO_END(),
|
||||
};
|
||||
|
||||
|
@ -216,7 +230,9 @@ const GeoLayout castle_door_0_star_geo[] = {
|
|||
GEO_CLOSE_NODE(),
|
||||
GEO_CLOSE_NODE(),
|
||||
GEO_CLOSE_NODE(),
|
||||
#ifndef QOL_FIXES
|
||||
GEO_CLOSE_NODE(), //! more close than open nodes
|
||||
#endif
|
||||
GEO_END(),
|
||||
};
|
||||
|
||||
|
@ -249,7 +265,9 @@ const GeoLayout castle_door_1_star_geo[] = {
|
|||
GEO_CLOSE_NODE(),
|
||||
GEO_CLOSE_NODE(),
|
||||
GEO_CLOSE_NODE(),
|
||||
#ifndef QOL_FIXES
|
||||
GEO_CLOSE_NODE(), //! more close than open nodes
|
||||
#endif
|
||||
GEO_END(),
|
||||
};
|
||||
|
||||
|
@ -282,7 +300,9 @@ const GeoLayout castle_door_3_stars_geo[] = {
|
|||
GEO_CLOSE_NODE(),
|
||||
GEO_CLOSE_NODE(),
|
||||
GEO_CLOSE_NODE(),
|
||||
#ifndef QOL_FIXES
|
||||
GEO_CLOSE_NODE(), //! more close than open nodes
|
||||
#endif
|
||||
GEO_END(),
|
||||
};
|
||||
|
||||
|
@ -315,6 +335,8 @@ const GeoLayout key_door_geo[] = {
|
|||
GEO_CLOSE_NODE(),
|
||||
GEO_CLOSE_NODE(),
|
||||
GEO_CLOSE_NODE(),
|
||||
#ifndef QOL_FIXES
|
||||
GEO_CLOSE_NODE(), //! more close than open nodes
|
||||
#endif
|
||||
GEO_END(),
|
||||
};
|
||||
|
|
|
@ -49,6 +49,8 @@ const GeoLayout dorrie_geo[] = {
|
|||
GEO_CLOSE_NODE(),
|
||||
GEO_CLOSE_NODE(),
|
||||
GEO_CLOSE_NODE(),
|
||||
#ifndef QOL_FIXES
|
||||
GEO_CLOSE_NODE(), //! more close than open nodes
|
||||
#endif
|
||||
GEO_END(),
|
||||
};
|
||||
|
|
|
@ -25,7 +25,12 @@ extern const Gfx king_bobomb_seg5_dl_0500B118[];
|
|||
extern const Gfx king_bobomb_seg5_dl_0500B150[];
|
||||
extern const Gfx king_bobomb_seg5_dl_0500B188[];
|
||||
extern const Gfx king_bobomb_seg5_dl_0500B278[];
|
||||
#ifdef QOL_FIXES
|
||||
extern const Gfx king_bobomb_dl_eyes[];
|
||||
extern const Gfx king_bobomb_dl_eyes_blink[];
|
||||
#else
|
||||
extern const Gfx king_bobomb_seg5_dl_0500B2D0[];
|
||||
#endif
|
||||
extern const Gfx king_bobomb_seg5_dl_0500B3C8[];
|
||||
extern const Gfx king_bobomb_seg5_dl_0500B418[];
|
||||
extern const Gfx king_bobomb_seg5_dl_0500B5F0[];
|
||||
|
|
|
@ -57,6 +57,8 @@ const GeoLayout hoot_geo[] = {
|
|||
GEO_CLOSE_NODE(),
|
||||
GEO_CLOSE_NODE(),
|
||||
GEO_CLOSE_NODE(),
|
||||
#ifndef QOL_FIXES
|
||||
GEO_CLOSE_NODE(), //! more close than open nodes
|
||||
#endif
|
||||
GEO_END(),
|
||||
};
|
||||
|
|
|
@ -35,7 +35,15 @@ const GeoLayout king_bobomb_geo[] = {
|
|||
GEO_CLOSE_NODE(),
|
||||
GEO_CLOSE_NODE(),
|
||||
GEO_CLOSE_NODE(),
|
||||
#ifdef QOL_FIXES
|
||||
GEO_SWITCH_CASE(2, geo_switch_anim_state),
|
||||
GEO_OPEN_NODE(),
|
||||
GEO_ANIMATED_PART(LAYER_ALPHA, 0, 0, 0, king_bobomb_dl_eyes),
|
||||
GEO_ANIMATED_PART(LAYER_ALPHA, 0, 0, 0, king_bobomb_dl_eyes_blink),
|
||||
GEO_CLOSE_NODE(),
|
||||
#else
|
||||
GEO_ANIMATED_PART(LAYER_ALPHA, 0, 0, 0, king_bobomb_seg5_dl_0500B2D0),
|
||||
#endif
|
||||
GEO_ANIMATED_PART(LAYER_OPAQUE, 0, 0, 0, king_bobomb_seg5_dl_0500B418),
|
||||
GEO_ANIMATED_PART(LAYER_OPAQUE, 0, 0, 0, king_bobomb_seg5_dl_0500B6C0),
|
||||
GEO_ANIMATED_PART(LAYER_OPAQUE, 0, 243, 0, NULL),
|
||||
|
@ -115,6 +123,8 @@ const GeoLayout king_bobomb_geo[] = {
|
|||
GEO_CLOSE_NODE(),
|
||||
GEO_CLOSE_NODE(),
|
||||
GEO_CLOSE_NODE(),
|
||||
#ifndef QOL_FIXES
|
||||
GEO_CLOSE_NODE(), //! more close than open nodes
|
||||
#endif
|
||||
GEO_END(),
|
||||
};
|
||||
|
|
|
@ -527,6 +527,50 @@ static const Vtx king_bobomb_seg5_vertex_0500B218[] = {
|
|||
{{{ 124, -158, 493}, 0, { 990, 0}, {0x00, 0xe8, 0x7c, 0xff}}},
|
||||
};
|
||||
|
||||
#ifdef QOL_FIXES
|
||||
const Gfx king_bobomb_dl_eyes_start_block[] = {
|
||||
gsDPPipeSync(),
|
||||
gsDPSetCombineMode(G_CC_DECALRGBA, G_CC_DECALRGBA),
|
||||
gsSPClearGeometryMode(G_LIGHTING),
|
||||
gsDPSetTile(G_IM_FMT_RGBA, G_IM_SIZ_16b, 0, 0, G_TX_LOADTILE, 0, G_TX_WRAP | G_TX_NOMIRROR, G_TX_NOMASK, G_TX_NOLOD, G_TX_WRAP | G_TX_NOMIRROR, G_TX_NOMASK, G_TX_NOLOD),
|
||||
gsSPTexture(0xFFFF, 0xFFFF, 0, G_TX_RENDERTILE, G_ON),
|
||||
gsDPTileSync(),
|
||||
gsDPSetTile(G_IM_FMT_RGBA, G_IM_SIZ_16b, 8, 0, G_TX_RENDERTILE, 0, G_TX_WRAP | G_TX_NOMIRROR, 5, G_TX_NOLOD, G_TX_WRAP | G_TX_NOMIRROR, 5, G_TX_NOLOD),
|
||||
gsDPSetTileSize(0, 0, 0, (32 - 1) << G_TEXTURE_IMAGE_FRAC, (32 - 1) << G_TEXTURE_IMAGE_FRAC),
|
||||
gsSPEndDisplayList(),
|
||||
};
|
||||
|
||||
const Gfx king_bobomb_dl_eyes_end_block[] = {
|
||||
gsSPLight(&king_bobomb_seg5_lights_0500B200.l, 1),
|
||||
gsSPLight(&king_bobomb_seg5_lights_0500B200.a, 2),
|
||||
gsSPVertex(king_bobomb_seg5_vertex_0500B218, 6, 0),
|
||||
gsSP2Triangles( 0, 1, 2, 0x0, 3, 2, 4, 0x0),
|
||||
gsSP2Triangles( 2, 3, 0, 0x0, 4, 5, 3, 0x0),
|
||||
gsSPTexture(0xFFFF, 0xFFFF, 0, G_TX_RENDERTILE, G_OFF),
|
||||
gsDPPipeSync(),
|
||||
gsDPSetCombineMode(G_CC_SHADE, G_CC_SHADE),
|
||||
gsSPSetGeometryMode(G_LIGHTING),
|
||||
gsSPEndDisplayList(),
|
||||
};
|
||||
|
||||
const Gfx king_bobomb_dl_eyes[] = {
|
||||
gsSPDisplayList(king_bobomb_dl_eyes_start_block),
|
||||
gsDPSetTextureImage(G_IM_FMT_RGBA, G_IM_SIZ_16b, 1, king_bobomb_seg5_texture_05004878),
|
||||
gsDPLoadSync(),
|
||||
gsDPLoadBlock(G_TX_LOADTILE, 0, 0, 32 * 32 - 1, CALC_DXT(32, G_IM_SIZ_16b_BYTES)),
|
||||
gsSPDisplayList(king_bobomb_dl_eyes_end_block),
|
||||
gsSPEndDisplayList(),
|
||||
};
|
||||
|
||||
const Gfx king_bobomb_dl_eyes_blink[] = {
|
||||
gsSPDisplayList(king_bobomb_dl_eyes_start_block),
|
||||
gsDPSetTextureImage(G_IM_FMT_RGBA, G_IM_SIZ_16b, 1, king_bobomb_seg5_texture_05005078),
|
||||
gsDPLoadSync(),
|
||||
gsDPLoadBlock(G_TX_LOADTILE, 0, 0, 32 * 32 - 1, CALC_DXT(32, G_IM_SIZ_16b_BYTES)),
|
||||
gsSPDisplayList(king_bobomb_dl_eyes_end_block),
|
||||
gsSPEndDisplayList(),
|
||||
};
|
||||
#else
|
||||
// 0x0500B278 - 0x0500B2D0
|
||||
const Gfx king_bobomb_seg5_dl_0500B278[] = {
|
||||
gsDPSetTextureImage(G_IM_FMT_RGBA, G_IM_SIZ_16b, 1, king_bobomb_seg5_texture_05004878),
|
||||
|
@ -555,6 +599,7 @@ const Gfx king_bobomb_seg5_dl_0500B2D0[] = {
|
|||
gsDPSetCombineMode(G_CC_SHADE, G_CC_SHADE),
|
||||
gsSPEndDisplayList(),
|
||||
};
|
||||
#endif
|
||||
|
||||
// 0x0500B330
|
||||
static const Lights1 king_bobomb_seg5_lights_0500B330 = gdSPDefLights1(
|
||||
|
|
|
@ -50,7 +50,11 @@ const GeoLayout klepto_geo[] = {
|
|||
GEO_SCALE(0x00, 16384),
|
||||
GEO_OPEN_NODE(),
|
||||
GEO_ASM(0, geo_offset_klepto_held_object),
|
||||
#ifdef QOL_FIXES
|
||||
GEO_TRANSLATE_ROTATE_WITH_DL(LAYER_TRANSPARENT, 0, 100, 0, 180, 270, 0, transparent_star_seg3_dl_0302C620),
|
||||
#else
|
||||
GEO_TRANSLATE_ROTATE_WITH_DL(LAYER_OPAQUE, 0, 100, 0, 180, 270, 0, transparent_star_seg3_dl_0302C620),
|
||||
#endif
|
||||
GEO_CLOSE_NODE(),
|
||||
GEO_CLOSE_NODE(),
|
||||
GEO_CLOSE_NODE(),
|
||||
|
|
|
@ -55,7 +55,7 @@ static const Lights1 koopa_seg6_lights_06002630 = gdSPDefLights1(
|
|||
// the rest of its body. This is evident because once the mistake is corrected
|
||||
// it turns back to being white like the other polygons.
|
||||
// Due to debate in the PR surrounding the fix to this, said fix is on
|
||||
// a compile-time variable. Use TEXTURE_FIX=1 at compile time to fix this.
|
||||
// a compile-time variable. Use QOL_FIXES=1 at compile time to fix this.
|
||||
// 0x06002648
|
||||
ALIGNED8 static const u8 koopa_seg6_texture_06002648[] = {
|
||||
#include "actors/koopa/koopa_shell_front.rgba16.inc.c"
|
||||
|
@ -2079,7 +2079,7 @@ const Gfx koopa_seg6_dl_0600C498[] = {
|
|||
gsSPVertex(koopa_seg6_vertex_0600B560, 9, 0),
|
||||
gsSP2Triangles( 0, 1, 2, 0x0, 3, 4, 5, 0x0),
|
||||
gsSP1Triangle( 6, 7, 8, 0x0),
|
||||
#ifdef TEXTURE_FIX
|
||||
#ifdef QOL_FIXES
|
||||
gsSPLight(&koopa_seg6_lights_06002630.l, 1),
|
||||
gsSPLight(&koopa_seg6_lights_06002630.a, 2),
|
||||
#else
|
||||
|
|
|
@ -16,6 +16,8 @@ const GeoLayout mad_piano_geo[] = {
|
|||
GEO_CLOSE_NODE(),
|
||||
GEO_CLOSE_NODE(),
|
||||
GEO_CLOSE_NODE(),
|
||||
#ifndef QOL_FIXES
|
||||
GEO_CLOSE_NODE(), //! more close than open nodes
|
||||
#endif
|
||||
GEO_END(),
|
||||
};
|
||||
|
|
|
@ -49,7 +49,9 @@ const GeoLayout mips_geo[] = {
|
|||
GEO_CLOSE_NODE(),
|
||||
GEO_CLOSE_NODE(),
|
||||
GEO_CLOSE_NODE(),
|
||||
#ifndef QOL_FIXES
|
||||
GEO_CLOSE_NODE(), //! more close than open nodes
|
||||
#endif
|
||||
GEO_END(),
|
||||
};
|
||||
|
||||
|
|
|
@ -52,7 +52,9 @@ const GeoLayout moneybag_geo[] = {
|
|||
GEO_CLOSE_NODE(),
|
||||
GEO_CLOSE_NODE(),
|
||||
GEO_CLOSE_NODE(),
|
||||
#ifndef QOL_FIXES
|
||||
GEO_CLOSE_NODE(), //! more close than open nodes
|
||||
#endif
|
||||
GEO_END(),
|
||||
};
|
||||
|
||||
|
|
|
@ -22,6 +22,8 @@ const GeoLayout snufit_geo[] = {
|
|||
GEO_CLOSE_NODE(),
|
||||
GEO_CLOSE_NODE(),
|
||||
GEO_CLOSE_NODE(),
|
||||
#ifndef QOL_FIXES
|
||||
GEO_CLOSE_NODE(), //! more close than open nodes
|
||||
#endif
|
||||
GEO_END(),
|
||||
};
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
* in the "demofiles" array.
|
||||
* "ifdef" is an optional array property which can be used to specify
|
||||
* requirement of SM64 version.
|
||||
* "extraSize" is an optional property which will be added the size of the
|
||||
* "extraSize" is an optional property which will be added to the size of the
|
||||
* demofile.
|
||||
*
|
||||
* The "demofiles" array declares the inclusion order of the demofiles.
|
||||
|
|
|
@ -0,0 +1,46 @@
|
|||
/*
|
||||
* This file defines the demo data. It's parsed by tools/demo_data_converter.py.
|
||||
*
|
||||
* The "table" array declares the order of the demos and will be generated
|
||||
* as pairs of (offset, size).
|
||||
* Each item has a "demofile" property, which must reference a demofile
|
||||
* in the "demofiles" array.
|
||||
* "ifdef" is an optional array property which can be used to specify
|
||||
* requirement of SM64 version.
|
||||
* "extraSize" is an optional property which will be added to the size of the
|
||||
* demofile.
|
||||
*
|
||||
* The "demofiles" array declares the inclusion order of the demofiles.
|
||||
* A file with the ".bin" extension with the "name" property as basename
|
||||
* should exist in the assets/demos/ directory.
|
||||
* "ifdef" is an optional array property which can be used to specify
|
||||
* requirement of SM64 version.
|
||||
*/
|
||||
|
||||
{
|
||||
"table": [
|
||||
{"demofile":"bitdw", "ifdef":["VERSION_US"]},
|
||||
{"demofile":"wf"},
|
||||
{"demofile":"ccm"},
|
||||
{"demofile":"bbh"},
|
||||
{"demofile":"jrb"},
|
||||
{"demofile":"hmc"},
|
||||
{"demofile":"pss"},
|
||||
{"demofile":"unused"}
|
||||
],
|
||||
"demofiles": [
|
||||
{"name":"bbh"},
|
||||
{"name":"ccm"},
|
||||
{"name":"hmc"},
|
||||
{"name":"jrb"},
|
||||
{"name":"wf"},
|
||||
{"name":"pss"},
|
||||
|
||||
/* Might be an unused demo, but it doesn't define a header,
|
||||
so it can't be normally called. Speculation: "blooper" take for CCM.
|
||||
Mario runs into the sign and aligns himself as if it were a mistake. */
|
||||
{"name":"unused"},
|
||||
|
||||
{"name":"bitdw", "ifdef":["VERSION_US"]}
|
||||
]
|
||||
}
|
|
@ -9,20 +9,39 @@
|
|||
*/
|
||||
|
||||
// Bug Fixes
|
||||
// --| US Version Nintendo Bug Fixes
|
||||
// --| Post-JP Version Nintendo Bug Fixes
|
||||
/// Fixes bug where obtaining over 999 coins sets the number of lives to 999 (or -25)
|
||||
#define BUGFIX_MAX_LIVES (0 || VERSION_US || VERSION_EU || VERSION_SH)
|
||||
#define BUGFIX_MAX_LIVES (0 || VERSION_US || VERSION_EU || VERSION_SH || QOL_FIXES)
|
||||
/// Fixes bug where the Boss music won't fade out after defeating King Bob-omb
|
||||
#define BUGFIX_KING_BOB_OMB_FADE_MUSIC (0 || VERSION_US || VERSION_EU)
|
||||
#define BUGFIX_KING_BOB_OMB_FADE_MUSIC (0 || VERSION_US || VERSION_EU || VERSION_SH || QOL_FIXES)
|
||||
/// Fixes bug in Bob-Omb Battlefield where entering a warp stops the Koopa race music
|
||||
#define BUGFIX_KOOPA_RACE_MUSIC (0 || VERSION_US || VERSION_EU || VERSION_SH)
|
||||
#define BUGFIX_KOOPA_RACE_MUSIC (0 || VERSION_US || VERSION_EU || VERSION_SH || QOL_FIXES)
|
||||
/// Fixes bug where Piranha Plants do not reset their action state when the
|
||||
/// player exits their activation radius.
|
||||
#define BUGFIX_PIRANHA_PLANT_STATE_RESET (0 || VERSION_US || VERSION_EU || VERSION_SH)
|
||||
#define BUGFIX_PIRANHA_PLANT_STATE_RESET (0 || VERSION_US || VERSION_EU || VERSION_SH || QOL_FIXES)
|
||||
/// Fixes bug where sleeping Piranha Plants damage players that bump into them
|
||||
#define BUGFIX_PIRANHA_PLANT_SLEEP_DAMAGE (0 || VERSION_US || VERSION_SH)
|
||||
#define BUGFIX_PIRANHA_PLANT_SLEEP_DAMAGE (0 || VERSION_US || VERSION_SH || QOL_FIXES)
|
||||
/// Fixes bug where it shows a star when you grab a key in bowser battle stages
|
||||
#define BUGFIX_STAR_BOWSER_KEY (0 || VERSION_US || VERSION_EU)
|
||||
#define BUGFIX_STAR_BOWSER_KEY (0 || VERSION_US || VERSION_EU || VERSION_SH || QOL_FIXES)
|
||||
/// Fixes bug in KTQ win dialog which makes it sound like a penguin instead of a Koopa
|
||||
#define BUGFIX_DIALOG_SOUND_KTQ_WIN (0 || VERSION_US || VERSION_EU || VERSION_SH || QOL_FIXES)
|
||||
/// Fixes bug that causes Wiggler to read a garbage health value when it gets loaded
|
||||
#define BUGFIX_WIGGLER_HEALTH (0 || VERSION_EU || AVOID_UB || QOL_FIXES)
|
||||
/// Fixes bug that can cause spawning displacement (e.g. after exiting a level)
|
||||
#define BUGFIX_SPAWNING_DISPLACEMENT (0 || VERSION_US || VERSION_EU || VERSION_SH || QOL_FIXES)
|
||||
// --| Shindou Version Nintendo Bug Fixes
|
||||
/// Fixes bug where bully could still be interacted with while he dies
|
||||
#define BUGFIX_BULLY_NO_INTERACT_DEATH (0 || VERSION_SH || QOL_FIXES)
|
||||
/// Fixes bug where standing on a controllable platform in HMC be invisible while it blinks
|
||||
#define BUGFIX_HMC_VISIBLE_CONTROL_PLATFORM (0 || VERSION_SH || QOL_FIXES)
|
||||
/// Fixes bug where the angle speed isn't preserved while in a pole
|
||||
#define BUGFIX_PRESERVE_VEL_POLE (0 || VERSION_SH || QOL_FIXES)
|
||||
/// Fixes bug where backwards long jumps have uncapped speed
|
||||
#define BUGFIX_BLJ (0 || VERSION_SH || QOL_FIXES)
|
||||
// --| Misc QoL Fixes (these aren't really covered by QOL_FIXES)
|
||||
/// Reenables the unused play state
|
||||
#define USE_UNUSED_PLAY_STATE (0 || USE_UNUSED_PLAY_STATE)
|
||||
|
||||
|
||||
// Screen Size Defines
|
||||
#define SCREEN_WIDTH 320
|
||||
|
|
|
@ -593,6 +593,9 @@
|
|||
#define /*0x100*/ oKingBobombUnk100 OBJECT_FIELD_S32(0x1E)
|
||||
#define /*0x104*/ oKingBobombUnk104 OBJECT_FIELD_S32(0x1F)
|
||||
#define /*0x108*/ oKingBobombUnk108 OBJECT_FIELD_S32(0x20)
|
||||
#ifdef QOL_FIXES
|
||||
#define /*0x108*/ oKingBobombBlinkTimer OBJECT_FIELD_S32(0x21)
|
||||
#endif
|
||||
|
||||
/* Klepto */
|
||||
#define /*0x0F4*/ oKleptoDistanceToTarget OBJECT_FIELD_F32(0x1B)
|
||||
|
|
|
@ -291,7 +291,11 @@ struct MarioState
|
|||
/*0x0C*/ u32 action;
|
||||
/*0x10*/ u32 prevAction;
|
||||
/*0x14*/ u32 terrainSoundAddend;
|
||||
#ifndef QOL_FIXES
|
||||
/*0x18*/ u16 actionState;
|
||||
#else
|
||||
/*0x18*/ u32 actionState;
|
||||
#endif
|
||||
/*0x1A*/ u16 actionTimer;
|
||||
/*0x1C*/ u32 actionArg;
|
||||
/*0x20*/ f32 intendedMag;
|
||||
|
|
|
@ -28,7 +28,11 @@ const MacroObject bits_seg7_macro_objs[] = {
|
|||
MACRO_OBJECT(/*preset*/ macro_hidden_1up_trigger, /*yaw*/ 0, /*pos*/ -7200, 2080, -890),
|
||||
MACRO_OBJECT(/*preset*/ macro_hidden_1up_trigger, /*yaw*/ 0, /*pos*/ -6600, 2080, -1550),
|
||||
MACRO_OBJECT_WITH_BEH_PARAM(/*preset*/ macro_hidden_1up, /*yaw*/ 0, /*pos*/ -6640, 2280, -890, /*behParam*/ 3),
|
||||
#ifdef QOL_FIXES
|
||||
MACRO_OBJECT(/*preset*/ macro_goomba_triplet_spawner, /*yaw*/ 45, /*pos*/ -5476, 3839, -930),
|
||||
#else
|
||||
MACRO_OBJECT(/*preset*/ macro_goomba_triplet_spawner, /*yaw*/ 0, /*pos*/ -5239, 3839, -999),
|
||||
#endif
|
||||
MACRO_OBJECT(/*preset*/ macro_bobomb, /*yaw*/ 0, /*pos*/ -1559, 3800, -1079),
|
||||
MACRO_OBJECT(/*preset*/ macro_bobomb, /*yaw*/ 0, /*pos*/ -1079, 3800, -1039),
|
||||
MACRO_OBJECT(/*preset*/ macro_coin_line_horizontal, /*yaw*/ 0, /*pos*/ 1879, 4639, -1559),
|
||||
|
|
|
@ -22,6 +22,8 @@ const GeoLayout castle_grounds_geo_000660[] = {
|
|||
GEO_CLOSE_NODE(),
|
||||
GEO_CLOSE_NODE(),
|
||||
GEO_CLOSE_NODE(),
|
||||
#ifndef QOL_FIXES
|
||||
GEO_CLOSE_NODE(), //! more close than open nodes
|
||||
#endif
|
||||
GEO_END(),
|
||||
};
|
||||
|
|
|
@ -27,7 +27,12 @@ const Trajectory ccm_seg7_trajectory_penguin_race[] = {
|
|||
TRAJECTORY_POS(24, /*pos*/ 1333, 761, -1733),
|
||||
TRAJECTORY_POS(25, /*pos*/ 2488, 562, -2944),
|
||||
TRAJECTORY_POS(26, /*pos*/ 2977, 361, -4988),
|
||||
#ifndef QOL_FIXES
|
||||
//! missing ID
|
||||
#else
|
||||
// TODO: Find suitable coordinates for this
|
||||
//TRAJECTORY_POS(27, /*pos*/ 0, 0, 0),
|
||||
#endif
|
||||
TRAJECTORY_POS(28, /*pos*/ 3754, 329, -5689),
|
||||
TRAJECTORY_POS(29, /*pos*/ 5805, 86, -5980),
|
||||
TRAJECTORY_POS(30, /*pos*/ 6566, -449, -4133),
|
||||
|
|
|
@ -88,7 +88,7 @@ const LevelScript level_main_menu_entry_2[] = {
|
|||
/*37*/ TRANSITION(/*transType*/ WARP_TRANSITION_FADE_INTO_COLOR, /*time*/ 16, /*color*/ 0xFF, 0xFF, 0xFF),
|
||||
/*39*/ SLEEP(/*frames*/ 16),
|
||||
/*40*/ CLEAR_LEVEL(),
|
||||
/*41*/ SLEEP_BEFORE_EXIT(/*frames*/ 1),
|
||||
/*41*/ SLEEP_BEFORE_EXIT(/*frames*/ 5),
|
||||
// L1:
|
||||
/*42*/ EXIT(),
|
||||
};
|
||||
|
|
|
@ -3,7 +3,11 @@ const MacroObject sl_seg7_area_1_macro_objs[] = {
|
|||
MACRO_OBJECT_WITH_BEH_PARAM(/*preset*/ macro_wooden_signpost, /*yaw*/ 90, /*pos*/ 4086, 1024, 400, /*behParam*/ DIALOG_086),
|
||||
MACRO_OBJECT(/*preset*/ macro_yellow_coin_2, /*yaw*/ 0, /*pos*/ 1285, 2210, 385),
|
||||
MACRO_OBJECT(/*preset*/ macro_yellow_coin_2, /*yaw*/ 0, /*pos*/ 1728, 2560, -671),
|
||||
#ifdef QOL_FIXES
|
||||
MACRO_OBJECT(/*preset*/ macro_yellow_coin_2, /*yaw*/ 0, /*pos*/ 1371, 3072, -500),
|
||||
#else
|
||||
MACRO_OBJECT(/*preset*/ macro_yellow_coin_2, /*yaw*/ 0, /*pos*/ 1371, 2188, -500),
|
||||
#endif
|
||||
MACRO_OBJECT(/*preset*/ macro_yellow_coin_2, /*yaw*/ 0, /*pos*/ 1814, 3174, 114),
|
||||
MACRO_OBJECT(/*preset*/ macro_yellow_coin_2, /*yaw*/ 0, /*pos*/ 28, 3328, 1885),
|
||||
MACRO_OBJECT(/*preset*/ macro_yellow_coin_2, /*yaw*/ 0, /*pos*/ -228, 3482, 1742),
|
||||
|
|
|
@ -24,6 +24,9 @@ static const LevelScript script_func_local_1[] = {
|
|||
};
|
||||
|
||||
static const LevelScript script_func_local_2[] = {
|
||||
#ifdef QOL_FIXES
|
||||
OBJECT(/*model*/ MODEL_SL_CRACKED_ICE, /*pos*/ 4377, 1843, 4361, /*angle*/ 0, 0, 0, /*behParam*/ 0x00000000, /*beh*/ bhvUnusedPoundablePlatform),
|
||||
#endif
|
||||
OBJECT(/*model*/ MODEL_NONE, /*pos*/ 977, 1024, 2075, /*angle*/ 0, 0, 0, /*behParam*/ 0x00000000, /*beh*/ bhvSnowMoundSpawn),
|
||||
RETURN(),
|
||||
};
|
||||
|
|
|
@ -16,7 +16,11 @@ const MacroObject thi_seg7_area_1_macro_objs[] = {
|
|||
MACRO_OBJECT(/*preset*/ macro_huge_goomba, /*yaw*/ 0, /*pos*/ 4600, -1544, 3455),
|
||||
MACRO_OBJECT(/*preset*/ macro_huge_goomba, /*yaw*/ 0, /*pos*/ 3444, -522, 3011),
|
||||
MACRO_OBJECT(/*preset*/ macro_huge_goomba, /*yaw*/ 0, /*pos*/ -3622, -511, 3100),
|
||||
#ifdef QOL_FIXES
|
||||
MACRO_OBJECT(/*preset*/ macro_coin_line_horizontal, /*yaw*/ 0, /*pos*/ -4911, -165, -1433),
|
||||
#else
|
||||
MACRO_OBJECT(/*preset*/ macro_coin_line_horizontal, /*yaw*/ 0, /*pos*/ -4911, -395, -1433),
|
||||
#endif
|
||||
MACRO_OBJECT(/*preset*/ macro_coin_line_horizontal, /*yaw*/ 90, /*pos*/ 199, 2233, 433),
|
||||
MACRO_OBJECT(/*preset*/ macro_huge_goomba, /*yaw*/ 0, /*pos*/ -3177, 1255, -2366),
|
||||
MACRO_OBJECT(/*preset*/ macro_chuckya, /*yaw*/ 0, /*pos*/ -1800, 2233, -322),
|
||||
|
|
|
@ -38,9 +38,15 @@ const MacroObject thi_seg7_area_2_macro_objs[] = {
|
|||
MACRO_OBJECT(/*preset*/ macro_tiny_goomba, /*yaw*/ 0, /*pos*/ 1822, -460, -1511),
|
||||
MACRO_OBJECT(/*preset*/ macro_tiny_goomba, /*yaw*/ 0, /*pos*/ 2148, -460, -918),
|
||||
MACRO_OBJECT(/*preset*/ macro_yellow_coin_2, /*yaw*/ 0, /*pos*/ -133, -491, -1481),
|
||||
#ifdef QOL_FIXES
|
||||
MACRO_OBJECT(/*preset*/ macro_yellow_coin_2, /*yaw*/ 0, /*pos*/ -1466, 26, -814),
|
||||
MACRO_OBJECT(/*preset*/ macro_yellow_coin_2, /*yaw*/ 0, /*pos*/ -1466, -16, -518),
|
||||
MACRO_OBJECT(/*preset*/ macro_yellow_coin_2, /*yaw*/ 0, /*pos*/ -1466, -149, -162),
|
||||
#else
|
||||
MACRO_OBJECT(/*preset*/ macro_yellow_coin_2, /*yaw*/ 0, /*pos*/ -1466, -70, -814),
|
||||
MACRO_OBJECT(/*preset*/ macro_yellow_coin_2, /*yaw*/ 0, /*pos*/ -1466, -107, -518),
|
||||
MACRO_OBJECT(/*preset*/ macro_yellow_coin_2, /*yaw*/ 0, /*pos*/ -1466, -151, -162),
|
||||
#endif
|
||||
MACRO_OBJECT(/*preset*/ macro_yellow_coin_2, /*yaw*/ 0, /*pos*/ 133, -491, -1496),
|
||||
MACRO_OBJECT(/*preset*/ macro_box_1up, /*yaw*/ 0, /*pos*/ -1866, -400, 311),
|
||||
MACRO_OBJECT(/*preset*/ macro_yellow_coin_2, /*yaw*/ 0, /*pos*/ -380, -480, 370),
|
||||
|
|
|
@ -7,6 +7,12 @@ const GeoLayout ttm_geo_000920[] = {
|
|||
GEO_DISPLAY_LIST(LAYER_OPAQUE, ttm_seg7_dl_0700DF78),
|
||||
GEO_OPEN_NODE(),
|
||||
GEO_CLOSE_NODE(),
|
||||
#ifndef QOL_FIXES
|
||||
//! Too many open nodes. Unfortunately not exploitable
|
||||
GEO_END(),
|
||||
#else
|
||||
GEO_CLOSE_NODE(),
|
||||
GEO_CLOSE_NODE(),
|
||||
GEO_END(),
|
||||
#endif
|
||||
};
|
||||
|
|
|
@ -35,7 +35,6 @@ static const LevelScript script_func_local_2[] = {
|
|||
static const LevelScript script_func_local_3[] = {
|
||||
OBJECT(/*model*/ MODEL_NONE, /*pos*/ 4600, 250, -4500, /*angle*/ 0, 0, 0, /*behParam*/ 0x00000000, /*beh*/ bhvHiddenRedCoinStar),
|
||||
RETURN(),
|
||||
};
|
||||
|
||||
const LevelScript level_vcutm_entry[] = {
|
||||
INIT_LEVEL(),
|
||||
|
@ -49,8 +48,11 @@ const LevelScript level_vcutm_entry[] = {
|
|||
MARIO(/*model*/ MODEL_MARIO, /*behParam*/ 0x00000001, /*beh*/ bhvMario),
|
||||
JUMP_LINK(script_func_global_1),
|
||||
JUMP_LINK(script_func_global_9),
|
||||
LOAD_MODEL_FROM_GEO(MODEL_VCUTM_SEESAW_PLATFORM, vcutm_geo_0001F0),
|
||||
LOAD_MODEL_FROM_GEO(MODEL_VCUTM_WARP_PIPE, warp_pipe_geo),
|
||||
LOAD_MODEL_FROM_GEO(MODEL_VCUTM_SEESAW_PLATFORM, vcutm_geo_0001F0),
|
||||
#ifdef QOL_FIXES
|
||||
LOAD_MODEL_FROM_GEO(MODEL_VCUTM_CHECKERBOARD_PLATFORM_SPAWNER, NULL),
|
||||
#endif
|
||||
LOAD_MODEL_FROM_GEO(MODEL_VCUTM_WARP_PIPE, warp_pipe_geo),
|
||||
|
||||
AREA(/*index*/ 1, vcutm_geo_000208),
|
||||
OBJECT(/*model*/ MODEL_NONE, /*pos*/ -6143, 6734, -6143, /*angle*/ 0, 0, 0, /*behParam*/ 0x000A0000, /*beh*/ bhvAirborneWarp),
|
||||
|
|
|
@ -227,7 +227,7 @@ s32 sGameLoopTicked = 0;
|
|||
#define YOSHI 10
|
||||
#define _ 0xFF
|
||||
|
||||
#ifdef VERSION_JP
|
||||
#if BUGFIX_DIALOG_SOUND_KTQ_WIN
|
||||
#define DIFF KOOPA
|
||||
#else
|
||||
#define DIFF TUXIE
|
||||
|
|
|
@ -558,8 +558,13 @@ void func_eu_802e27e4_unused(f32 arg0, f32 arg1, u16 *arg2) {
|
|||
|
||||
for (i = 2; i < 8; i++) {
|
||||
//! @bug they probably meant to store the value to tmp[i] and tmp[8 + i]
|
||||
#ifndef QOL_FIXES
|
||||
arg2[i] = arg1 * tmp[i - 2] + arg0 * tmp[i - 1];
|
||||
arg2[8 + i] = arg1 * tmp[6 + i] + arg0 * tmp[7 + i];
|
||||
#else
|
||||
tmp[i] = arg1 * tmp[i - 2] + arg0 * tmp[i - 1];
|
||||
tmp[8 + i] = arg1 * tmp[6 + i] + arg0 * tmp[7 + i];
|
||||
#endif
|
||||
}
|
||||
|
||||
for (i = 0; i < 16; i++) {
|
||||
|
|
|
@ -485,7 +485,7 @@ void patch_audio_bank(struct AudioBank *mem, u8 *offset, u32 numInstruments, u32
|
|||
drum = PATCH(patched, mem);
|
||||
mem->drums[i] = drum;
|
||||
if (drum->loaded == 0) {
|
||||
#ifndef VERSION_EU
|
||||
#if !defined(VERSION_EU) || !defined(QOL_FIXES)
|
||||
//! copt replaces drum with 'patched' for these two lines
|
||||
PATCH_SOUND(&(*(struct Drum *)patched).sound, mem, offset);
|
||||
patched = (*(struct Drum *)patched).envelope;
|
||||
|
@ -789,7 +789,11 @@ void preload_sequence(u32 seqId, u8 preloadMask) {
|
|||
|
||||
if (preloadMask & PRELOAD_SEQUENCE) {
|
||||
// @bug should be IS_SEQ_LOAD_COMPLETE
|
||||
#ifndef QOL_FIXES
|
||||
if (IS_BANK_LOAD_COMPLETE(seqId) == TRUE) {
|
||||
#else
|
||||
if (IS_SEQ_LOAD_COMPLETE(seqId) == TRUE) {
|
||||
#endif
|
||||
sequenceData = get_bank_or_seq(&gSeqLoadedPool, 2, seqId);
|
||||
} else {
|
||||
sequenceData = NULL;
|
||||
|
|
|
@ -272,13 +272,16 @@ void seq_channel_layer_process_script(struct SequenceChannelLayer *layer) {
|
|||
case 0xc4: // layer_somethingon
|
||||
case 0xc5: // layer_somethingoff
|
||||
//! copt needs a ternary:
|
||||
//layer->continuousNotes = (cmd == 0xc4) ? TRUE : FALSE;
|
||||
#ifdef QOL_FIXES
|
||||
temp8 = layer->continuousNotes = (cmd == 0xc4) ? TRUE : FALSE;
|
||||
#else
|
||||
if (cmd == 0xc4) {
|
||||
temp8 = TRUE;
|
||||
} else {
|
||||
temp8 = FALSE;
|
||||
}
|
||||
layer->continuousNotes = temp8;
|
||||
#endif
|
||||
seq_channel_layer_note_decay(layer);
|
||||
break;
|
||||
|
||||
|
@ -428,12 +431,15 @@ l1090:
|
|||
|
||||
if (layer->portamento.mode != 0) {
|
||||
//! copt needs a ternary:
|
||||
//usedSemitone = (layer->portamentoTargetNote < SEMITONE) ? SEMITONE : layer->portamentoTargetNote;
|
||||
#ifdef QOL_FIXES
|
||||
USED_SEMITONE = (layer->portamentoTargetNote < SEMITONE) ? SEMITONE : layer->portamentoTargetNote;
|
||||
#else
|
||||
if (layer->portamentoTargetNote < SEMITONE) {
|
||||
USED_SEMITONE = SEMITONE;
|
||||
} else {
|
||||
USED_SEMITONE = layer->portamentoTargetNote;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (instrument != NULL) {
|
||||
sound = (u8) USED_SEMITONE < instrument->normalRangeLo ? &instrument->lowNotesSound
|
||||
|
|
|
@ -22,7 +22,9 @@ void *vec3f_copy(Vec3f dest, Vec3f src) {
|
|||
dest[0] = src[0];
|
||||
dest[1] = src[1];
|
||||
dest[2] = src[2];
|
||||
#ifndef QOL_FIXES
|
||||
return &dest; //! warning: function returns address of local variable
|
||||
#endif
|
||||
}
|
||||
|
||||
/// Set vector 'dest' to (x, y, z)
|
||||
|
@ -30,7 +32,9 @@ void *vec3f_set(Vec3f dest, f32 x, f32 y, f32 z) {
|
|||
dest[0] = x;
|
||||
dest[1] = y;
|
||||
dest[2] = z;
|
||||
#ifndef QOL_FIXES
|
||||
return &dest; //! warning: function returns address of local variable
|
||||
#endif
|
||||
}
|
||||
|
||||
/// Add vector 'a' to 'dest'
|
||||
|
@ -38,7 +42,9 @@ void *vec3f_add(Vec3f dest, Vec3f a) {
|
|||
dest[0] += a[0];
|
||||
dest[1] += a[1];
|
||||
dest[2] += a[2];
|
||||
#ifndef QOL_FIXES
|
||||
return &dest; //! warning: function returns address of local variable
|
||||
#endif
|
||||
}
|
||||
|
||||
/// Make 'dest' the sum of vectors a and b.
|
||||
|
@ -46,7 +52,9 @@ void *vec3f_sum(Vec3f dest, Vec3f a, Vec3f b) {
|
|||
dest[0] = a[0] + b[0];
|
||||
dest[1] = a[1] + b[1];
|
||||
dest[2] = a[2] + b[2];
|
||||
#ifndef QOL_FIXES
|
||||
return &dest; //! warning: function returns address of local variable
|
||||
#endif
|
||||
}
|
||||
|
||||
/// Multiply vector 'dest' by a
|
||||
|
@ -55,7 +63,9 @@ void *vec3f_mul(Vec3f dest, f32 a)
|
|||
dest[0] *= a;
|
||||
dest[1] *= a;
|
||||
dest[2] *= a;
|
||||
#ifndef QOL_FIXES
|
||||
return &dest; //! warning: function returns address of local variable
|
||||
#endif
|
||||
}
|
||||
|
||||
/// Copy vector src to dest
|
||||
|
@ -63,7 +73,9 @@ void *vec3s_copy(Vec3s dest, Vec3s src) {
|
|||
dest[0] = src[0];
|
||||
dest[1] = src[1];
|
||||
dest[2] = src[2];
|
||||
#ifndef QOL_FIXES
|
||||
return &dest; //! warning: function returns address of local variable
|
||||
#endif
|
||||
}
|
||||
|
||||
/// Set vector 'dest' to (x, y, z)
|
||||
|
@ -71,7 +83,9 @@ void *vec3s_set(Vec3s dest, s16 x, s16 y, s16 z) {
|
|||
dest[0] = x;
|
||||
dest[1] = y;
|
||||
dest[2] = z;
|
||||
#ifndef QOL_FIXES
|
||||
return &dest; //! warning: function returns address of local variable
|
||||
#endif
|
||||
}
|
||||
|
||||
/// Add vector a to 'dest'
|
||||
|
@ -79,7 +93,9 @@ void *vec3s_add(Vec3s dest, Vec3s a) {
|
|||
dest[0] += a[0];
|
||||
dest[1] += a[1];
|
||||
dest[2] += a[2];
|
||||
#ifndef QOL_FIXES
|
||||
return &dest; //! warning: function returns address of local variable
|
||||
#endif
|
||||
}
|
||||
|
||||
/// Make 'dest' the sum of vectors a and b.
|
||||
|
@ -87,7 +103,9 @@ void *vec3s_sum(Vec3s dest, Vec3s a, Vec3s b) {
|
|||
dest[0] = a[0] + b[0];
|
||||
dest[1] = a[1] + b[1];
|
||||
dest[2] = a[2] + b[2];
|
||||
#ifndef QOL_FIXES
|
||||
return &dest; //! warning: function returns address of local variable
|
||||
#endif
|
||||
}
|
||||
|
||||
/// Make 'dest' the difference of vectors a and b.
|
||||
|
@ -95,7 +113,9 @@ void *vec3f_dif(Vec3f dest, Vec3f a, Vec3f b) {
|
|||
dest[0] = a[0] - b[0];
|
||||
dest[1] = a[1] - b[1];
|
||||
dest[2] = a[2] - b[2];
|
||||
#ifndef QOL_FIXES
|
||||
return &dest; //! warning: function returns address of local variable
|
||||
#endif
|
||||
}
|
||||
|
||||
/// Convert short vector a to float vector 'dest'
|
||||
|
@ -103,7 +123,9 @@ void *vec3s_to_vec3f(Vec3f dest, Vec3s a) {
|
|||
dest[0] = a[0];
|
||||
dest[1] = a[1];
|
||||
dest[2] = a[2];
|
||||
#ifndef QOL_FIXES
|
||||
return &dest; //! warning: function returns address of local variable
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -115,7 +137,9 @@ void *vec3f_to_vec3s(Vec3s dest, Vec3f a) {
|
|||
dest[0] = a[0] + ((a[0] > 0) ? 0.5f : -0.5f);
|
||||
dest[1] = a[1] + ((a[1] > 0) ? 0.5f : -0.5f);
|
||||
dest[2] = a[2] + ((a[2] > 0) ? 0.5f : -0.5f);
|
||||
#ifndef QOL_FIXES
|
||||
return &dest; //! warning: function returns address of local variable
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -127,7 +151,9 @@ void *find_vector_perpendicular_to_plane(Vec3f dest, Vec3f a, Vec3f b, Vec3f c)
|
|||
dest[0] = (b[1] - a[1]) * (c[2] - b[2]) - (c[1] - b[1]) * (b[2] - a[2]);
|
||||
dest[1] = (b[2] - a[2]) * (c[0] - b[0]) - (c[2] - b[2]) * (b[0] - a[0]);
|
||||
dest[2] = (b[0] - a[0]) * (c[1] - b[1]) - (c[0] - b[0]) * (b[1] - a[1]);
|
||||
#ifndef QOL_FIXES
|
||||
return &dest; //! warning: function returns address of local variable
|
||||
#endif
|
||||
}
|
||||
|
||||
/// Make vector 'dest' the cross product of vectors a and b.
|
||||
|
@ -135,18 +161,31 @@ void *vec3f_cross(Vec3f dest, Vec3f a, Vec3f b) {
|
|||
dest[0] = a[1] * b[2] - b[1] * a[2];
|
||||
dest[1] = a[2] * b[0] - b[2] * a[0];
|
||||
dest[2] = a[0] * b[1] - b[0] * a[1];
|
||||
#ifndef QOL_FIXES
|
||||
return &dest; //! warning: function returns address of local variable
|
||||
#endif
|
||||
}
|
||||
|
||||
/// Scale vector 'dest' so it has length 1
|
||||
void *vec3f_normalize(Vec3f dest) {
|
||||
#ifndef QOL_FIXES
|
||||
//! Possible division by zero
|
||||
f32 invsqrt = 1.0f / sqrtf(dest[0] * dest[0] + dest[1] * dest[1] + dest[2] * dest[2]);
|
||||
#else
|
||||
f32 invsqrt = 0.0f;
|
||||
if (sqrtf(dest[0] * dest[0] + dest[1] * dest[1] + dest[2] * dest[2]) != 0) {
|
||||
invsqrt = 1.0f / sqrtf(dest[0] * dest[0] + dest[1] * dest[1] + dest[2] * dest[2]);
|
||||
} else {
|
||||
invsqrt = 1.0f * 0.0f;
|
||||
}
|
||||
#endif
|
||||
|
||||
dest[0] *= invsqrt;
|
||||
dest[1] *= invsqrt;
|
||||
dest[2] *= invsqrt;
|
||||
#ifndef QOL_FIXES
|
||||
return &dest; //! warning: function returns address of local variable
|
||||
#endif
|
||||
}
|
||||
|
||||
/// Get length of vector 'a'
|
||||
|
@ -730,6 +769,49 @@ f32 approach_f32(f32 current, f32 target, f32 inc, f32 dec) {
|
|||
return current;
|
||||
}
|
||||
|
||||
#ifdef QOL_FIXES
|
||||
/**
|
||||
* Return the value 'current' after it tries to approach target, going up at
|
||||
* most 'inc' and going down at most 'dec'.
|
||||
*/
|
||||
s64 approach_s64(s64 current, s64 target, s64 inc, s64 dec) {
|
||||
//! If target is close to the max or min s64, then it's possible to overflow
|
||||
// past it without stopping.
|
||||
|
||||
if (current < target) {
|
||||
current += inc;
|
||||
if (current > target) {
|
||||
current = target;
|
||||
}
|
||||
} else {
|
||||
current -= dec;
|
||||
if (current < target) {
|
||||
current = target;
|
||||
}
|
||||
}
|
||||
return current;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the value 'current' after it tries to approach target, going up at
|
||||
* most 'inc' and going down at most 'dec'.
|
||||
*/
|
||||
f64 approach_f64(f64 current, f64 target, f64 inc, f64 dec) {
|
||||
if (current < target) {
|
||||
current += inc;
|
||||
if (current > target) {
|
||||
current = target;
|
||||
}
|
||||
} else {
|
||||
current -= dec;
|
||||
if (current < target) {
|
||||
current = target;
|
||||
}
|
||||
}
|
||||
return current;
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Helper function for atan2s. Does a look up of the arctangent of y/x assuming
|
||||
* the resulting angle is in range [0, 0x2000] (1/8 of a circle).
|
||||
|
|
|
@ -74,6 +74,10 @@ void vec3f_get_dist_and_angle(Vec3f from, Vec3f to, f32 *dist, s16 *pitch, s16 *
|
|||
void vec3f_set_dist_and_angle(Vec3f from, Vec3f to, f32 dist, s16 pitch, s16 yaw);
|
||||
s32 approach_s32(s32 current, s32 target, s32 inc, s32 dec);
|
||||
f32 approach_f32(f32 current, f32 target, f32 inc, f32 dec);
|
||||
#ifdef QOL_FIXES
|
||||
s32 approach_s64(s32 current, s32 target, s32 inc, s32 dec);
|
||||
f32 approach_f64(f32 current, f32 target, f32 inc, f32 dec);
|
||||
#endif
|
||||
s16 atan2s(f32 y, f32 x);
|
||||
f32 atan2f(f32 a, f32 b);
|
||||
void spline_get_weights(Vec4f result, f32 t, UNUSED s32 c);
|
||||
|
|
|
@ -313,7 +313,7 @@ f32 find_ceil(f32 posX, f32 posY, f32 posZ, struct Surface **pceil) {
|
|||
s16 x, y, z;
|
||||
|
||||
//! (Parallel Universes) Because position is casted to an s16, reaching higher
|
||||
// float locations can return ceilings despite them not existing there.
|
||||
// float locations can return ceilings despite them not existing there.
|
||||
//(Dynamic ceilings will unload due to the range.)
|
||||
x = (s16) posX;
|
||||
y = (s16) posY;
|
||||
|
@ -519,7 +519,7 @@ f32 find_floor(f32 xPos, f32 yPos, f32 zPos, struct Surface **pfloor) {
|
|||
f32 dynamicHeight = -11000.0f;
|
||||
|
||||
//! (Parallel Universes) Because position is casted to an s16, reaching higher
|
||||
// float locations can return floors despite them not existing there.
|
||||
// float locations can return floors despite them not existing there.
|
||||
//(Dynamic floors will unload due to the range.)
|
||||
s16 x = (s16) xPos;
|
||||
s16 y = (s16) yPos;
|
||||
|
@ -552,7 +552,7 @@ f32 find_floor(f32 xPos, f32 yPos, f32 zPos, struct Surface **pfloor) {
|
|||
if (!gFindFloorIncludeSurfaceIntangible) {
|
||||
//! (BBH Crash) Most NULL checking is done by checking the height of the floor returned
|
||||
// instead of checking directly for a NULL floor. If this check returns a NULL floor
|
||||
// (happens when there is no floor under the SURFACE_INTANGIBLE floor) but returns the height
|
||||
// (happens when there is no floor under the SURFACE_INTANGIBLE floor), it returns the height
|
||||
// of the SURFACE_INTANGIBLE floor instead of the typical -11000 returned for a NULL floor.
|
||||
if (floor != NULL && floor->type == SURFACE_INTANGIBLE) {
|
||||
floor = find_floor_from_list(surfaceList, x, (s32)(height - 200.0f), z, &height);
|
||||
|
|
|
@ -21,7 +21,9 @@ void bhv_beta_chest_bottom_init(void) {
|
|||
// cancelled by setting the yaw to 0, right before this beta
|
||||
// object was discarded?
|
||||
o->oMoveAngleYaw = random_u16();
|
||||
#ifndef QOL_FIXES
|
||||
o->oMoveAngleYaw = 0;
|
||||
#endif
|
||||
|
||||
// Spawn the chest lid 97 units in the +Y direction and 77 units in the -Z direction.
|
||||
spawn_object_relative(0, 0, 97, -77, o, MODEL_TREASURE_CHEST_LID, bhvBetaChestLid);
|
||||
|
|
|
@ -78,12 +78,16 @@ void bowling_ball_set_waypoints(void) {
|
|||
|
||||
void bhv_bowling_ball_roll_loop(void) {
|
||||
s16 collisionFlags;
|
||||
#ifndef QOL_FIXES
|
||||
s32 sp18;
|
||||
#else
|
||||
s32 sp18 = 0;
|
||||
#endif
|
||||
|
||||
bowling_ball_set_waypoints();
|
||||
collisionFlags = object_step();
|
||||
|
||||
//! Uninitialzed parameter, but the parameter is unused in the called function
|
||||
//! Uninitialized parameter, but the parameter is unused in the called function
|
||||
sp18 = cur_obj_follow_path(sp18);
|
||||
|
||||
o->oBowlingBallTargetYaw = o->oPathedTargetYaw;
|
||||
|
@ -108,11 +112,15 @@ void bhv_bowling_ball_roll_loop(void) {
|
|||
}
|
||||
|
||||
void bhv_bowling_ball_initializeLoop(void) {
|
||||
#ifndef QOL_FIXES
|
||||
s32 sp1c;
|
||||
#else
|
||||
s32 sp1c = 0;
|
||||
#endif
|
||||
|
||||
bowling_ball_set_waypoints();
|
||||
|
||||
//! Uninitialzed parameter, but the parameter is unused in the called function
|
||||
//! Uninitialized parameter, but the parameter is unused in the called function
|
||||
sp1c = cur_obj_follow_path(sp1c);
|
||||
|
||||
o->oMoveAngleYaw = o->oPathedTargetYaw;
|
||||
|
|
|
@ -52,7 +52,11 @@ void bhv_big_bully_init(void) {
|
|||
}
|
||||
|
||||
void bully_check_mario_collision(void) {
|
||||
if (o->oInteractStatus & INT_STATUS_INTERACTED) {
|
||||
if (
|
||||
#if BUGFIX_BULLY_NO_INTERACT_DEATH
|
||||
o->oAction != BULLY_ACT_LAVA_DEATH && o->oAction != BULLY_ACT_DEATH_PLANE_DEATH &&
|
||||
#endif
|
||||
o->oInteractStatus & INT_STATUS_INTERACTED) {
|
||||
if (o->oBehParams2ndByte == BULLY_BP_SIZE_SMALL)
|
||||
cur_obj_play_sound_2(SOUND_OBJ2_BULLY_ATTACKED);
|
||||
else
|
||||
|
@ -122,7 +126,11 @@ void bully_act_back_up(void) {
|
|||
// conditions are activated. However because its angle is set to its facing angle,
|
||||
// it will walk forward instead of backing up.
|
||||
|
||||
#ifndef QOL_FIXES
|
||||
if (o->oTimer == 15) {
|
||||
#else
|
||||
if (o->oTimer >= 15) {
|
||||
#endif
|
||||
o->oMoveAngleYaw = o->oFaceAngleYaw;
|
||||
o->oFlags |= 0x8; /* bit 3 */
|
||||
o->oAction = BULLY_ACT_PATROL;
|
||||
|
@ -219,7 +227,13 @@ void bhv_bully_loop(void) {
|
|||
// death action by colliding with it. Since the bully hitbox is tall enough to collide
|
||||
// with Mario even when it is under a lava floor, this can get the bully stuck OOB
|
||||
// if there is nothing under the lava floor.
|
||||
#ifndef QOL_FIXES
|
||||
bully_check_mario_collision();
|
||||
#else
|
||||
if (o->oAction != BULLY_ACT_LAVA_DEATH || o->oAction != BULLY_ACT_DEATH_PLANE_DEATH) {
|
||||
bully_check_mario_collision();
|
||||
}
|
||||
#endif
|
||||
|
||||
switch (o->oAction) {
|
||||
case BULLY_ACT_PATROL:
|
||||
|
@ -336,11 +350,15 @@ void bhv_big_bully_with_minions_loop(void) {
|
|||
// for counting the number of dead minions. This means that when it activates,
|
||||
// the knockback timer is at 3 instead of 0. So the bully knockback time will
|
||||
// be reduced by 3 frames (16.67%) on the first hit.
|
||||
//
|
||||
if (o->oBullyKBTimerAndMinionKOCounter == 3) {
|
||||
play_puzzle_jingle();
|
||||
|
||||
if (o->oTimer >= 91)
|
||||
o->oAction = BULLY_ACT_ACTIVATE_AND_FALL;
|
||||
#ifdef QOL_FIXES
|
||||
o->oBullyKBTimerAndMinionKOCounter == 0;
|
||||
#endif
|
||||
}
|
||||
break;
|
||||
|
||||
|
|
|
@ -30,7 +30,11 @@ static void camera_lakitu_intro_act_trigger_cutscene(void) {
|
|||
// the RTA speedrunning method of lakitu skip
|
||||
if (gMarioObject->oPosX > -544.0f && gMarioObject->oPosX < 545.0f && gMarioObject->oPosY > 800.0f
|
||||
&& gMarioObject->oPosZ > -2000.0f && gMarioObject->oPosZ < -177.0f
|
||||
#ifndef QOL_FIXES
|
||||
&& gMarioObject->oPosZ < -177.0f) // always double check your conditions
|
||||
#else
|
||||
&& gMarioObject->oPosZ > 178.0f)
|
||||
#endif
|
||||
{
|
||||
if (set_mario_npc_dialog(2) == 1) {
|
||||
o->oAction = CAMERA_LAKITU_INTRO_ACT_SPAWN_CLOUD;
|
||||
|
|
|
@ -26,7 +26,11 @@ void bhv_castle_floor_trap_open_detect(void) {
|
|||
|
||||
void bhv_castle_floor_trap_open(void) {
|
||||
if (o->oTimer == 0)
|
||||
#ifndef QOL_FIXES
|
||||
cur_obj_play_sound_2(SOUND_GENERAL_CASTLE_TRAP_OPEN);
|
||||
#else
|
||||
create_sound_spawner(SOUND_GENERAL_CASTLE_TRAP_OPEN);
|
||||
#endif
|
||||
o->oAngleVelRoll -= 0x100;
|
||||
o->oFaceAngleRoll += o->oAngleVelRoll;
|
||||
if (o->oFaceAngleRoll < -0x4000) {
|
||||
|
|
|
@ -29,6 +29,9 @@ void bhv_controllable_platform_sub_loop(void) {
|
|||
|
||||
if (gMarioObject->platform == o) {
|
||||
D_80331694 = o->oBehParams2ndByte;
|
||||
#if BUGFIX_HMC_VISIBLE_CONTROL_PLATFORM
|
||||
o->parentObj->header.gfx.node.flags &= ~GRAPH_RENDER_INVISIBLE;
|
||||
#endif
|
||||
o->oAction = 1;
|
||||
cur_obj_play_sound_2(SOUND_GENERAL_MOVING_PLATFORM_SWITCH);
|
||||
}
|
||||
|
|
|
@ -325,4 +325,8 @@ void bhv_king_bobomb_loop(void) {
|
|||
break;
|
||||
}
|
||||
o->oInteractStatus = 0;
|
||||
|
||||
#ifdef QOL_FIXES
|
||||
curr_obj_random_blink(&o->oKingBobombBlinkTimer);
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -75,7 +75,15 @@ static void klepto_anim_dive(void) {
|
|||
|
||||
void bhv_klepto_init(void) {
|
||||
if (o->oBehParams2ndByte != 0) {
|
||||
#ifdef QOL_FIXES
|
||||
if (save_file_get_star_flags(gCurrSaveFileNum - 1, COURSE_SSL) & 1) {
|
||||
o->oAnimState = KLEPTO_ANIM_STATE_HOLDING_BLUE_STAR;
|
||||
} else {
|
||||
o->oAnimState = KLEPTO_ANIM_STATE_HOLDING_STAR;
|
||||
}
|
||||
#else
|
||||
o->oAnimState = KLEPTO_ANIM_STATE_HOLDING_STAR;
|
||||
#endif
|
||||
} else {
|
||||
o->oKleptoStartPosX = o->oPosX;
|
||||
o->oKleptoStartPosY = o->oPosY;
|
||||
|
@ -362,7 +370,11 @@ void bhv_klepto_update(void) {
|
|||
if (o->oAnimState == KLEPTO_ANIM_STATE_HOLDING_CAP) {
|
||||
save_file_clear_flags(SAVE_FLAG_CAP_ON_KLEPTO);
|
||||
spawn_object(o, MODEL_MARIOS_CAP, bhvNormalCap);
|
||||
} else if (o->oAnimState == KLEPTO_ANIM_STATE_HOLDING_STAR) {
|
||||
} else if (o->oAnimState == KLEPTO_ANIM_STATE_HOLDING_STAR
|
||||
#ifdef QOL_FIXES
|
||||
|| o->oAnimState == KLEPTO_ANIM_STATE_HOLDING_BLUE_STAR
|
||||
#endif
|
||||
) {
|
||||
spawn_default_star(-5550.0f, 300.0f, -930.0f);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,3 +1,7 @@
|
|||
#ifdef QOL_FIXES
|
||||
#include <limits.h>
|
||||
#include <float.h>
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Behavior for bhvMontyMole, bhvMontyMoleHole, and bhvMontyMoleRock.
|
||||
|
@ -377,7 +381,11 @@ void bhv_monty_mole_update(void) {
|
|||
//! The two farthest holes on the bottom level of TTM are more than
|
||||
// 1500 units away from each other, so the counter resets if you
|
||||
// attack moles in these holes consecutively.
|
||||
#ifndef QOL_FIXES
|
||||
if (distToLastKill < 1500.0f) {
|
||||
#else
|
||||
if (distToLastKill <= FLT_MAX) {
|
||||
#endif
|
||||
if (sMontyMoleKillStreak == 7) {
|
||||
play_puzzle_jingle();
|
||||
spawn_object(o, MODEL_1UP, bhv1upWalking);
|
||||
|
@ -388,7 +396,15 @@ void bhv_monty_mole_update(void) {
|
|||
}
|
||||
|
||||
//! No overflow check
|
||||
#ifndef QOL_FIXES
|
||||
sMontyMoleKillStreak += 1;
|
||||
#else
|
||||
if (sMontyMoleKillStreak > INT_MAX) {
|
||||
sMontyMoleKillStreak = INT_MAX;
|
||||
} else {
|
||||
sMontyMoleKillStreak += 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
sMontyMoleLastKilledPosX = o->oPosX;
|
||||
sMontyMoleLastKilledPosY = o->oPosY;
|
||||
|
|
|
@ -75,8 +75,13 @@ void bhv_pokey_body_part_update(void) {
|
|||
//! If you kill a body part as it's expanding, the body part that
|
||||
// was above it will instantly shrink and begin expanding in its
|
||||
// place.
|
||||
#ifndef QOL_FIXES
|
||||
else if (o->parentObj->oPokeyBottomBodyPartSize < 1.0f
|
||||
&& o->oBehParams2ndByte + 1 == o->parentObj->oPokeyNumAliveBodyParts) {
|
||||
#else
|
||||
if (o->parentObj->oPokeyBottomBodyPartSize < 1.0f
|
||||
&& o->oBehParams2ndByte + 1 == o->parentObj->oPokeyNumAliveBodyParts) {
|
||||
#endif
|
||||
approach_f32_ptr(&o->parentObj->oPokeyBottomBodyPartSize, 1.0f, 0.1f);
|
||||
cur_obj_scale(o->parentObj->oPokeyBottomBodyPartSize * 3.0f);
|
||||
}
|
||||
|
|
|
@ -86,6 +86,9 @@ void bhv_pyramid_top_explode(void) {
|
|||
pyramidFragment->oGravity = random_float() * 2 + 5;
|
||||
}
|
||||
|
||||
#ifdef QOL_FIXES
|
||||
disable_time_stop_including_mario();
|
||||
#endif
|
||||
// Deactivate the pyramid top.
|
||||
o->activeFlags = ACTIVE_FLAG_DEACTIVATED;
|
||||
}
|
||||
|
@ -95,12 +98,18 @@ void bhv_pyramid_top_loop(void) {
|
|||
case PYRAMID_TOP_ACT_CHECK_IF_SOLVED:
|
||||
if (o->oPyramidTopPillarsTouched == 4) {
|
||||
play_puzzle_jingle();
|
||||
#ifdef QOL_FIXES
|
||||
cutscene_object(CUTSCENE_SSL_PYRAMID_EXPLODE, o);
|
||||
#endif
|
||||
o->oAction = PYRAMID_TOP_ACT_SPINNING;
|
||||
}
|
||||
break;
|
||||
|
||||
case PYRAMID_TOP_ACT_SPINNING:
|
||||
if (o->oTimer == 0) {
|
||||
#ifdef QOL_FIXES
|
||||
enable_time_stop_including_mario();
|
||||
#endif
|
||||
cur_obj_play_sound_2(SOUND_GENERAL2_PYRAMID_TOP_SPIN);
|
||||
}
|
||||
|
||||
|
|
|
@ -15,6 +15,9 @@ void bhv_seaweed_bundle_init(void) {
|
|||
seaweed->header.gfx.scale[1] = 1.0;
|
||||
seaweed->header.gfx.scale[2] = 1.0;
|
||||
//! gfx.animFrame uninitialized
|
||||
#ifdef QOL_FIXES
|
||||
seaweed->header.gfx.unk38.animFrame = random_float() * 80.0f;
|
||||
#endif
|
||||
|
||||
seaweed = spawn_object(o, MODEL_SEAWEED, bhvSeaweed);
|
||||
seaweed->oFaceAngleYaw = 41800;
|
||||
|
|
|
@ -90,7 +90,11 @@ void bhv_tilting_inverted_pyramid_loop(void) {
|
|||
linear_mtxf_mul_vec3f(*transform, posBeforeRotation, dist);
|
||||
|
||||
dx = gMarioObject->oPosX - o->oPosX;
|
||||
#ifndef QOL_FIXES
|
||||
dy = 500.0f;
|
||||
#else
|
||||
dy = gMarioObject->oPosY - o->oPosY;
|
||||
#endif
|
||||
dz = gMarioObject->oPosZ - o->oPosZ;
|
||||
d = sqrtf(dx * dx + dy * dy + dz * dz);
|
||||
|
||||
|
|
|
@ -66,6 +66,9 @@ void tuxies_mother_act_1(void) {
|
|||
break;
|
||||
case 1:
|
||||
if (o->prevObj->oHeldState == HELD_FREE) {
|
||||
#ifdef QOL_FIXES
|
||||
o->prevObj->oInteractionSubtype &= ~INT_SUBTYPE_DROP_IMMEDIATELY;
|
||||
#else
|
||||
//! This line is was almost certainly supposed to be something
|
||||
// like o->prevObj->oInteractionSubtype &= ~INT_SUBTYPE_DROP_IMMEDIATELY;
|
||||
// however, this code uses the value of o->oInteractionSubtype
|
||||
|
@ -75,6 +78,7 @@ void tuxies_mother_act_1(void) {
|
|||
// which has no effect as o->prevObj->oUnknownUnk88 is always 0
|
||||
// or 1, which is not affected by the bitwise AND.
|
||||
o->prevObj->OBJECT_FIELD_S32(o->oInteractionSubtype) &= ~INT_SUBTYPE_DROP_IMMEDIATELY;
|
||||
#endif
|
||||
obj_set_behavior(o->prevObj, bhvUnused20E0);
|
||||
#ifndef VERSION_JP
|
||||
cur_obj_spawn_star_at_y_offset(3167.0f, -4300.0f, 5108.0f, 200.0f);
|
||||
|
@ -86,8 +90,12 @@ void tuxies_mother_act_1(void) {
|
|||
break;
|
||||
case 2:
|
||||
if (o->prevObj->oHeldState == HELD_FREE) {
|
||||
#ifdef QOL_FIXES
|
||||
o->prevObj->oInteractionSubtype &= ~INT_SUBTYPE_DROP_IMMEDIATELY;
|
||||
#else
|
||||
//! Same bug as above
|
||||
o->prevObj->OBJECT_FIELD_S32(o->oInteractionSubtype) &= ~INT_SUBTYPE_DROP_IMMEDIATELY;
|
||||
#endif
|
||||
obj_set_behavior(o->prevObj, bhvPenguinBaby);
|
||||
o->oAction = 2;
|
||||
}
|
||||
|
@ -291,12 +299,29 @@ Gfx *geo_switch_tuxie_mother_eyes(s32 run, struct GraphNode *node, UNUSED Mat4 *
|
|||
if (run == TRUE) {
|
||||
obj = (struct Object *) gCurGraphNodeObject;
|
||||
switchCase = (struct GraphNodeSwitchCase *) node;
|
||||
#ifdef QOL_FIXES
|
||||
int babyDelivered = obj->oAction == 2;
|
||||
if (obj->behavior == segmented_to_virtual(bhvTuxiesMother)) {
|
||||
switchCase->selectedCase = babyDelivered ? 0 : 4;
|
||||
} else {
|
||||
switchCase->selectedCase = 0;
|
||||
#else
|
||||
switchCase->selectedCase = 0;
|
||||
#endif
|
||||
|
||||
// timer logic for blinking. uses cases 0-2.
|
||||
timer = gGlobalTimer % 50;
|
||||
if (timer < 43)
|
||||
#ifdef QOL_FIXES
|
||||
if (obj->behavior == segmented_to_virtual(bhvTuxiesMother)) {
|
||||
switchCase->selectedCase = babyDelivered ? 0 : 4;
|
||||
} else {
|
||||
switchCase->selectedCase = bapDelivered ? 0 : 4;
|
||||
switchCase->selectedCase = 0;
|
||||
}
|
||||
#else
|
||||
switchCase->selectedCase = 0;
|
||||
#endif
|
||||
else if (timer < 45)
|
||||
switchCase->selectedCase = 1;
|
||||
else if (timer < 47)
|
||||
|
|
|
@ -19,6 +19,9 @@ void bhv_unused_poundable_platform(void) {
|
|||
if (cur_obj_is_mario_ground_pounding_platform()) {
|
||||
spawn_mist_particles();
|
||||
spawn_triangle_break_particles(20, 56, 3.0f, 0);
|
||||
#ifdef QOL_FIXES
|
||||
create_sound_spawner(SOUND_GENERAL_BREAK_BOX);
|
||||
#endif
|
||||
o->oAction++;
|
||||
}
|
||||
} else if (o->oTimer > 7) {
|
||||
|
|
|
@ -29,9 +29,10 @@ void water_ring_init(void) {
|
|||
|
||||
// Adding this code will alter the ring's graphical orientation to align with the faulty
|
||||
// collision orientation:
|
||||
//
|
||||
// o->oFaceAngleYaw = 0;
|
||||
// o->oFaceAngleRoll *= -1;
|
||||
#ifdef QOL_FIXES
|
||||
o->oFaceAngleYaw = 0;
|
||||
o->oFaceAngleRoll *= -1;
|
||||
#endif
|
||||
}
|
||||
|
||||
void bhv_jet_stream_water_ring_init(void) {
|
||||
|
@ -162,8 +163,13 @@ void water_ring_spawner_act_inactive(void) {
|
|||
// come around again.
|
||||
if (o->oTimer == 300)
|
||||
o->oTimer = 0;
|
||||
#ifndef QOL_FIXES
|
||||
if ((o->oTimer == 0) || (o->oTimer == 50) || (o->oTimer == 150) || (o->oTimer == 200)
|
||||
|| (o->oTimer == 250)) {
|
||||
#else
|
||||
// This makes it much easier to collect this star
|
||||
if ((o->oTimer % 50 == 0)) {
|
||||
#endif
|
||||
waterRing = spawn_object(o, MODEL_WATER_RING, bhvJetStreamWaterRing);
|
||||
waterRing->oWaterRingIndex = currentObj->oWaterRingMgrNextRingIndex;
|
||||
currentObj->oWaterRingMgrNextRingIndex++;
|
||||
|
|
|
@ -153,7 +153,7 @@ void wiggler_init_segments(void) {
|
|||
cur_obj_unhide();
|
||||
}
|
||||
|
||||
#if defined(VERSION_EU) || defined(AVOID_UB)
|
||||
#if BUGFIX_WIGGLER_HEALTH
|
||||
o->oHealth = 4; // This fixes Wiggler reading UB on his first frame of his acceleration, as his health is not set.
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -664,7 +664,11 @@ void unused_set_camera_pitch_shake_env(s16 shake) {
|
|||
*/
|
||||
f32 calc_y_to_curr_floor(f32 *posOff, f32 posMul, f32 posBound, f32 *focOff, f32 focMul, f32 focBound) {
|
||||
f32 floorHeight = sMarioGeometry.currFloorHeight;
|
||||
#ifndef QOL_FIXES
|
||||
f32 waterHeight;
|
||||
#else
|
||||
f32 waterHeight = sMarioGeometry.waterHeight;
|
||||
#endif
|
||||
UNUSED s32 filler;
|
||||
|
||||
if (!(sMarioCamState->action & ACT_FLAG_METAL_WATER)) {
|
||||
|
@ -736,9 +740,11 @@ static UNUSED void set_pos_to_mario(Vec3f foc, Vec3f pos, f32 yOff, f32 focYOff,
|
|||
vec3f_set_dist_and_angle(marioPos, pos, dist, pitch + sLakituPitch, yaw);
|
||||
vec3f_get_dist_and_angle(pos, sMarioCamState->pos, &posDist, &posPitch, &posYaw);
|
||||
|
||||
#ifndef QOL_FIXES
|
||||
//! Useless get and set
|
||||
vec3f_get_dist_and_angle(pos, foc, &focDist, &focPitch, &focYaw);
|
||||
vec3f_set_dist_and_angle(pos, foc, focDist, focPitch, focYaw);
|
||||
#endif
|
||||
|
||||
foc[1] = sMarioCamState->pos[1] + focYOff;
|
||||
}
|
||||
|
@ -1578,9 +1584,11 @@ s32 update_boss_fight_camera(struct Camera *c, Vec3f focus, Vec3f pos) {
|
|||
}
|
||||
|
||||
focusDistance = calc_abs_dist(sMarioCamState->pos, secondFocus) * 1.6f;
|
||||
#ifndef QOL_FIXES
|
||||
if (focusDistance < 800.f) {
|
||||
focusDistance = 800.f;
|
||||
}
|
||||
#endif
|
||||
if (focusDistance > 5000.f) {
|
||||
focusDistance = 5000.f;
|
||||
}
|
||||
|
@ -1610,8 +1618,14 @@ s32 update_boss_fight_camera(struct Camera *c, Vec3f focus, Vec3f pos) {
|
|||
case AREA_BOB:
|
||||
pos[1] += 125.f;
|
||||
//! fall through, makes the BoB boss fight camera move up twice as high as it should
|
||||
#ifdef QOL_FIXES
|
||||
break;
|
||||
#endif
|
||||
case AREA_WF:
|
||||
pos[1] += 125.f;
|
||||
#ifdef QOL_FIXES
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1640,9 +1654,11 @@ s32 update_boss_fight_camera(struct Camera *c, Vec3f focus, Vec3f pos) {
|
|||
}
|
||||
|
||||
//! Unnecessary conditional, focusDistance is already bounded to 800
|
||||
#ifdef QOL_FIXES
|
||||
if (focusDistance < 400.f) {
|
||||
focusDistance = 400.f;
|
||||
}
|
||||
#endif
|
||||
|
||||
// Set C-Down distance and pitch.
|
||||
// C-Down will essentially double the distance from the center.
|
||||
|
@ -1781,10 +1797,12 @@ s32 update_behind_mario_camera(struct Camera *c, Vec3f focus, Vec3f pos) {
|
|||
// Focus on Mario
|
||||
vec3f_copy(focus, sMarioCamState->pos);
|
||||
c->focus[1] += focYOff;
|
||||
#ifndef QOL_FIXES
|
||||
//! @bug unnecessary
|
||||
dist = calc_abs_dist(focus, pos);
|
||||
//! @bug unnecessary
|
||||
pitch = calculate_pitch(focus, pos);
|
||||
#endif
|
||||
vec3f_get_dist_and_angle(focus, pos, &dist, &pitch, &yaw);
|
||||
if (dist > maxDist) {
|
||||
dist = maxDist;
|
||||
|
@ -2195,12 +2213,16 @@ s16 update_default_camera(struct Camera *c) {
|
|||
unusedFreeRoamWallYaw = avoidYaw;
|
||||
sAvoidYawVel = yaw;
|
||||
sStatusFlags |= CAM_FLAG_COLLIDED_WITH_WALL;
|
||||
#ifndef QOL_FIXES
|
||||
//! Does nothing
|
||||
vec3f_get_dist_and_angle(sMarioCamState->pos, cPos, &xzDist, &tempPitch, &tempYaw);
|
||||
#endif
|
||||
// Rotate to avoid the wall
|
||||
approach_s16_asymptotic_bool(&yaw, avoidYaw, 10);
|
||||
#ifndef QOL_FIXES
|
||||
//! Does nothing
|
||||
vec3f_set_dist_and_angle(sMarioCamState->pos, cPos, xzDist, tempPitch, tempYaw);
|
||||
#endif
|
||||
sAvoidYawVel = (sAvoidYawVel - yaw) / 0x100;
|
||||
} else {
|
||||
if (gMarioStates[0].forwardVel == 0.f) {
|
||||
|
@ -2455,8 +2477,10 @@ s32 update_spiral_stairs_camera(struct Camera *c, Vec3f focus, Vec3f pos) {
|
|||
}
|
||||
focYaw += sSpiralStairsYawOffset;
|
||||
posYaw = focYaw;
|
||||
#ifndef QOL_FIXES
|
||||
//! @bug unnecessary
|
||||
camera_approach_s16_symmetric_bool(&posYaw, focYaw, 0x1000);
|
||||
#endif
|
||||
|
||||
vec3f_set_dist_and_angle(sFixedModeBasePosition, cPos, 300.f, 0, posYaw);
|
||||
|
||||
|
@ -2924,8 +2948,10 @@ void update_lakitu(struct Camera *c) {
|
|||
if (gCameraMovementFlags & CAM_MOVE_PAUSE_SCREEN) {
|
||||
} else {
|
||||
if (c->cutscene) {
|
||||
#ifndef QOL_FIXES
|
||||
}
|
||||
if (TRUE) {
|
||||
#endif
|
||||
newYaw = next_lakitu_state(newPos, newFoc, c->pos, c->focus, sOldPosition, sOldFocus,
|
||||
c->nextYaw);
|
||||
set_or_approach_s16_symmetric(&c->yaw, newYaw, sYawSpeed);
|
||||
|
@ -4820,12 +4846,20 @@ s32 offset_yaw_outward_radial(struct Camera *c, s16 areaYaw) {
|
|||
// When the final yaw is out of [-60,60] degrees, approach yawGoal faster than dYaw will ever be,
|
||||
// making the camera lock in one direction until yawGoal drops below 60 (or Mario presses a C button)
|
||||
if (yaw < -DEGREES(60)) {
|
||||
#ifndef QOL_FIXES
|
||||
//! Maybe they meant to reverse yawGoal's sign?
|
||||
camera_approach_s16_symmetric_bool(&yaw, -yawGoal, 0x200);
|
||||
#else
|
||||
camera_approach_s16_symmetric_bool(&yaw, yawGoal, 0x200);
|
||||
#endif
|
||||
}
|
||||
if (yaw > DEGREES(60)) {
|
||||
#ifndef QOL_FIXES
|
||||
//! Maybe they meant to reverse yawGoal's sign?
|
||||
camera_approach_s16_symmetric_bool(&yaw, yawGoal, 0x200);
|
||||
#else
|
||||
camera_approach_s16_symmetric_bool(&yaw, -yawGoal, 0x200);
|
||||
#endif
|
||||
}
|
||||
return yaw;
|
||||
}
|
||||
|
@ -4897,7 +4931,11 @@ void play_sound_if_cam_switched_to_lakitu_or_mario(void) {
|
|||
* Handles input for radial, outwards radial, parallel tracking, and 8 direction mode.
|
||||
*/
|
||||
s32 radial_camera_input(struct Camera *c, UNUSED f32 unused) {
|
||||
#ifndef QOL_FIXES
|
||||
s16 dummy;
|
||||
#else
|
||||
s16 dummy = 0;
|
||||
#endif
|
||||
|
||||
if ((gCameraMovementFlags & CAM_MOVE_ENTERED_ROTATE_SURFACE) || !(gCameraMovementFlags & CAM_MOVE_ROTATE)) {
|
||||
|
||||
|
@ -5172,8 +5210,12 @@ u8 get_cutscene_from_mario_status(struct Camera *c) {
|
|||
//! doorStatus is never DOOR_ENTER_LOBBY when cameraEvent == 6, because
|
||||
//! doorStatus is only used for the star door in the lobby, which uses
|
||||
//! ACT_ENTERING_STAR_DOOR
|
||||
#ifndef QOL_FIXES
|
||||
if (c->mode == CAMERA_MODE_SPIRAL_STAIRS || c->mode == CAMERA_MODE_CLOSE
|
||||
|| c->doorStatus == DOOR_ENTER_LOBBY) {
|
||||
#else
|
||||
if (c->mode == CAMERA_MODE_SPIRAL_STAIRS || c->mode == CAMERA_MODE_CLOSE) {
|
||||
#endif
|
||||
cutscene = open_door_cutscene(CUTSCENE_DOOR_PULL_MODE, CUTSCENE_DOOR_PUSH_MODE);
|
||||
} else {
|
||||
cutscene = open_door_cutscene(CUTSCENE_DOOR_PULL, CUTSCENE_DOOR_PUSH);
|
||||
|
@ -6310,8 +6352,10 @@ struct CameraTrigger sCamCastle[] = {
|
|||
{ 1, cam_castle_close_mode, -2304, -264, -4072, 140, 150, 140, 0 },
|
||||
{ 1, cam_castle_close_mode, -2304, 145, -1344, 140, 150, 140, 0 },
|
||||
{ 1, cam_castle_enter_lobby, -2304, 145, -802, 140, 150, 140, 0 },
|
||||
#ifndef QOL_FIXES
|
||||
//! Sets the camera mode when leaving secret aquarium
|
||||
{ 1, cam_castle_close_mode, 2816, 1200, -256, 100, 100, 100, 0 },
|
||||
#endif
|
||||
{ 1, cam_castle_close_mode, 256, -161, -4226, 140, 150, 140, 0 },
|
||||
{ 1, cam_castle_close_mode, 256, 145, -1344, 140, 150, 140, 0 },
|
||||
{ 1, cam_castle_enter_lobby, 256, 145, -802, 140, 150, 140, 0 },
|
||||
|
@ -6333,8 +6377,10 @@ struct CameraTrigger sCamCastle[] = {
|
|||
{ 1, cam_castle_close_mode, -3393, 350, -793, 140, 150, 140, 0x4000 },
|
||||
{ 1, cam_castle_enter_lobby, -2851, 350, -792, 140, 150, 140, 0x4000 },
|
||||
{ 1, cam_castle_enter_lobby, 803, 350, -228, 140, 150, 140, -0x4000 },
|
||||
#ifndef QOL_FIXES
|
||||
//! Duplicate camera trigger outside JRB door
|
||||
{ 1, cam_castle_enter_lobby, 803, 350, -228, 140, 150, 140, -0x4000 },
|
||||
#endif
|
||||
{ 1, cam_castle_close_mode, 1345, 350, -229, 140, 150, 140, 0x4000 },
|
||||
{ 1, cam_castle_close_mode, -946, -929, 622, 300, 150, 300, 0 },
|
||||
{ 2, cam_castle_look_upstairs, -205, 1456, 2508, 210, 928, 718, 0 },
|
||||
|
@ -6591,11 +6637,17 @@ s16 camera_course_processing(struct Camera *c) {
|
|||
sCameraTriggers[level][b].boundsZ);
|
||||
|
||||
// Check if Mario is inside the bounds
|
||||
#ifndef QOL_FIXES
|
||||
if (is_pos_in_bounds(sMarioCamState->pos, center, bounds,
|
||||
sCameraTriggers[level][b].boundsYaw) == TRUE) {
|
||||
sCameraTriggers[level][b].boundsYaw) == TRUE) {
|
||||
//! This should be checked before calling is_pos_in_bounds. (It doesn't belong
|
||||
//! outside the while loop because some events disable area processing)
|
||||
if (!(sStatusFlags & CAM_FLAG_BLOCK_AREA_PROCESSING)) {
|
||||
#else
|
||||
if (!(sStatusFlags & CAM_FLAG_BLOCK_AREA_PROCESSING)) {
|
||||
if (is_pos_in_bounds(sMarioCamState->pos, center, bounds,
|
||||
sCameraTriggers[level][b].boundsYaw) == TRUE) {
|
||||
#endif
|
||||
sCameraTriggers[level][b].event(c);
|
||||
insideBounds = TRUE;
|
||||
}
|
||||
|
@ -6705,8 +6757,12 @@ s16 camera_course_processing(struct Camera *c) {
|
|||
break;
|
||||
|
||||
case AREA_DDD_WHIRLPOOL:
|
||||
#ifndef QOL_FIXES
|
||||
//! @bug this does nothing
|
||||
gLakituState.defMode = CAMERA_MODE_OUTWARD_RADIAL;
|
||||
#else
|
||||
c->defMode = CAMERA_MODE_OUTWARD_RADIAL;
|
||||
#endif
|
||||
break;
|
||||
|
||||
case AREA_DDD_SUB:
|
||||
|
@ -6722,8 +6778,12 @@ s16 camera_course_processing(struct Camera *c) {
|
|||
}
|
||||
}
|
||||
}
|
||||
#ifndef QOL_FIXES
|
||||
//! @bug this does nothing
|
||||
gLakituState.defMode = CAMERA_MODE_FREE_ROAM;
|
||||
#else
|
||||
c->defMode = CAMERA_MODE_FREE_ROAM;
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -6825,8 +6885,12 @@ s32 rotate_camera_around_walls(struct Camera *c, Vec3f cPos, s16 *avoidYaw, s16
|
|||
colData.y = sMarioCamState->pos[1] + ((cPos[1] - sMarioCamState->pos[1]) * checkDist);
|
||||
colData.z = sMarioCamState->pos[2] + ((cPos[2] - sMarioCamState->pos[2]) * checkDist);
|
||||
colData.radius = coarseRadius;
|
||||
// Increase the coarse check radius
|
||||
// Increase the coarse check
|
||||
#ifndef QOL_FIXES
|
||||
camera_approach_f32_symmetric_bool(&coarseRadius, 250.f, 30.f);
|
||||
#else
|
||||
camera_approach_f32_symmetric_bool(&coarseRadius, 200.f, 30.f);
|
||||
#endif
|
||||
|
||||
if (find_wall_collisions(&colData) != 0) {
|
||||
wall = colData.walls[colData.numWalls - 1];
|
||||
|
@ -7035,7 +7099,11 @@ void copy_spline_segment(struct CutsceneSplinePoint dst[], struct CutsceneSpline
|
|||
init_spline_point(&dst[i], src[j].index, src[j].speed, src[j].point);
|
||||
i += 1;
|
||||
j += 1;
|
||||
#ifndef QOL_FIXES
|
||||
} while ((src[j].index != -1) && (src[j].index != -1)); //! same comparison performed twice
|
||||
#else
|
||||
} while ((src[j].index != -1));
|
||||
#endif
|
||||
} while (j > 16);
|
||||
|
||||
// Create the end of the spline by duplicating the last point
|
||||
|
@ -7480,9 +7548,14 @@ BAD_RETURN(s32) cutscene_ending_kiss_here_we_go(struct Camera *c) {
|
|||
set_fov_function(CAM_FOV_DEFAULT);
|
||||
vec3f_set(foc, 233.f, 1068.f, -1298.f);
|
||||
vec3f_set(pos, -250.f, 966.f, -1111.f);
|
||||
#ifndef QOL_FIXES
|
||||
//! another double typo
|
||||
approach_vec3f_asymptotic(c->pos, pos, 0.2, 0.1f, 0.2f);
|
||||
approach_vec3f_asymptotic(c->focus, foc, 0.2, 0.1f, 0.2f);
|
||||
#else
|
||||
approach_vec3f_asymptotic(c->pos, pos, 0.2f, 0.1f, 0.2f);
|
||||
approach_vec3f_asymptotic(c->focus, foc, 0.2f, 0.1f, 0.2f);
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -8124,11 +8197,15 @@ BAD_RETURN(s32) cutscene_bowser_arena_set_pos(struct Camera *c) {
|
|||
* The y offset starts at 120, then decreases to 0 before reaching ~240 on the last frame.
|
||||
*/
|
||||
BAD_RETURN(s32) cutscene_bowser_arena_focus_sine(UNUSED struct Camera *c) {
|
||||
#ifndef QOL_FIXES
|
||||
//! unused initialization
|
||||
f32 yOff = 150.0f;
|
||||
|
||||
// cvar4 was zeroed when the cutscene started.
|
||||
yOff = sins(sCutsceneVars[4].angle[1]) * 120.0f + 120.0f;
|
||||
#else
|
||||
f32 yOff = sins(sCutsceneVars[4].angle[1]) * 120.0f + 120.0f;
|
||||
#endif
|
||||
sCutsceneVars[4].angle[1] -= 0x200;
|
||||
approach_f32_asymptotic_bool(&sCutsceneVars[0].point[1], yOff, 0.5f);
|
||||
}
|
||||
|
@ -9232,11 +9309,16 @@ BAD_RETURN(s32) cutscene_exit_bowser_succ_focus_left(UNUSED struct Camera *c) {
|
|||
* Instead of focusing on the key, just start a pitch shake. Clever!
|
||||
* The shake lasts 32 frames.
|
||||
*/
|
||||
#ifndef QOL_FIXES
|
||||
BAD_RETURN(s32) cutscene_exit_bowser_key_toss_shake(struct Camera *c) {
|
||||
//! Unnecessary check.
|
||||
if (c->cutscene == CUTSCENE_EXIT_BOWSER_SUCC) {
|
||||
set_camera_pitch_shake(0x800, 0x40, 0x800);
|
||||
}
|
||||
#else
|
||||
BAD_RETURN(s32) cutscene_exit_bowser_key_toss_shake(UNUSED struct Camera *c) {
|
||||
set_camera_pitch_shake(0x800, 0x40, 0x800);
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -10346,8 +10428,12 @@ BAD_RETURN(s32) cutscene_door_fix_cam(struct Camera *c) {
|
|||
* Loop until Mario is no longer using the door.
|
||||
*/
|
||||
BAD_RETURN(s32) cutscene_door_loop(struct Camera *c) {
|
||||
#ifndef QOL_FIXES
|
||||
//! bitwise AND instead of boolean
|
||||
if ((sMarioCamState->action != ACT_PULLING_DOOR) & (sMarioCamState->action != ACT_PUSHING_DOOR)) {
|
||||
#else
|
||||
if ((sMarioCamState->action != ACT_PULLING_DOOR) && (sMarioCamState->action != ACT_PUSHING_DOOR)) {
|
||||
#endif
|
||||
gCutsceneTimer = CUTSCENE_STOP;
|
||||
c->cutscene = 0;
|
||||
}
|
||||
|
@ -10366,11 +10452,15 @@ BAD_RETURN(s32) cutscene_door_move_behind_mario(struct Camera *c) {
|
|||
vec3s_set(sCutsceneVars[0].angle, 0, sMarioCamState->faceAngle[1] + doorRotation, 0);
|
||||
vec3f_set(camOffset, 0.f, 125.f, 250.f);
|
||||
|
||||
#ifndef QOL_FIXES
|
||||
if (doorRotation == 0) { //! useless code
|
||||
camOffset[0] = 0.f;
|
||||
} else {
|
||||
camOffset[0] = 0.f;
|
||||
}
|
||||
#else
|
||||
camOffset[0] = 0.f;
|
||||
#endif
|
||||
|
||||
offset_rotated(c->pos, sMarioCamState->pos, camOffset, sCutsceneVars[0].angle);
|
||||
}
|
||||
|
@ -10664,8 +10754,12 @@ struct Cutscene sCutsceneEnterPyramidTop[] = {
|
|||
* Unused cutscene for when the pyramid explodes.
|
||||
*/
|
||||
struct Cutscene sCutscenePyramidTopExplode[] = {
|
||||
#ifndef QOL_FIXES
|
||||
{ cutscene_mario_dialog, CUTSCENE_LOOP },
|
||||
{ cutscene_pyramid_top_explode, 150 },
|
||||
#else
|
||||
{ cutscene_pyramid_top_explode, 170 },
|
||||
#endif
|
||||
{ cutscene_pyramid_top_explode_end, 0 }
|
||||
};
|
||||
|
||||
|
@ -11306,9 +11400,13 @@ void play_cutscene(struct Camera *c) {
|
|||
#undef CUTSCENE
|
||||
|
||||
if ((cutsceneDuration != 0) && !(gCutsceneTimer & CUTSCENE_STOP)) {
|
||||
#ifndef QOL_FIXES
|
||||
//! @bug This should check for 0x7FFF (CUTSCENE_LOOP)
|
||||
//! instead, cutscenes that last longer than 0x3FFF frames will never end on their own
|
||||
if (gCutsceneTimer < 0x3FFF) {
|
||||
#else
|
||||
if (gCutsceneTimer < CUTSCENE_LOOP) {
|
||||
#endif
|
||||
gCutsceneTimer += 1;
|
||||
}
|
||||
//! Because gCutsceneTimer is often set to 0x7FFF (CUTSCENE_LOOP), this conditional can only
|
||||
|
@ -11533,6 +11631,10 @@ Gfx *geo_camera_fov(s32 callContext, struct GraphNode *g, UNUSED void *context)
|
|||
approach_fov_60(marioState);
|
||||
break;
|
||||
//! No default case
|
||||
#ifdef QOL_FIXES
|
||||
default:
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -180,10 +180,14 @@ void print_mapinfo(void) {
|
|||
print_debug_top_down_normal("mapinfo", 0);
|
||||
print_debug_top_down_mapinfo("area %x", area);
|
||||
print_debug_top_down_mapinfo("wx %d", gCurrentObject->oPosX);
|
||||
#ifndef QOL_FIXES
|
||||
//! Fat finger: programmer hit tab instead of space. Japanese
|
||||
// thumb shift keyboards had the tab key next to the spacebar,
|
||||
// so this was likely the reason.
|
||||
print_debug_top_down_mapinfo("wy\t %d", gCurrentObject->oPosY);
|
||||
#else
|
||||
print_debug_top_down_mapinfo("wy %d", gCurrentObject->oPosY);
|
||||
#endif
|
||||
print_debug_top_down_mapinfo("wz %d", gCurrentObject->oPosZ);
|
||||
print_debug_top_down_mapinfo("bgY %d", bgY);
|
||||
print_debug_top_down_mapinfo("angY %d", angY);
|
||||
|
|
|
@ -52,7 +52,7 @@ s32 particle_is_laterally_close(s32 index, s32 x, s32 z, s32 distance) {
|
|||
}
|
||||
|
||||
/**
|
||||
* Generate a uniform random number in range [-2000, -1000[ or [1000, 2000[
|
||||
* Generate a uniform random number in range [-2000, -1000] or [1000, 2000]
|
||||
* Used to position flower particles
|
||||
*/
|
||||
s32 random_flower_offset(void) {
|
||||
|
@ -348,16 +348,20 @@ s32 envfx_init_bubble(s32 mode) {
|
|||
bzero(gEnvFxBubbleConfig, sizeof(gEnvFxBubbleConfig));
|
||||
|
||||
if (mode == ENVFX_LAVA_BUBBLES) {
|
||||
#ifndef QOL_FIXES
|
||||
//! Dead code
|
||||
if (0) {
|
||||
}
|
||||
|
||||
#endif
|
||||
for (i = 0; i < sBubbleParticleCount; i++) {
|
||||
(gEnvFxBuffer + i)->animFrame = random_float() * 7.0f;
|
||||
}
|
||||
#ifndef QOL_FIXES
|
||||
|
||||
if (0) {
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
gEnvFxMode = mode;
|
||||
|
|
|
@ -414,7 +414,13 @@ void print_generic_string(s16 x, s16 y, const u8 *str) {
|
|||
case DIALOG_CHAR_LOWER_A_UMLAUT:
|
||||
render_lowercase_diacritic(&xCoord, &yCoord, ASCII_TO_DIALOG('a'), str[strPos] & 0xF);
|
||||
break;
|
||||
#ifndef QOL_FIXES
|
||||
case DIALOG_CHAR_UPPER_A_UMLAUT: // @bug grave and circumflex (0x64-0x65) are absent here
|
||||
#else
|
||||
case DIALOG_CHAR_UPPER_A_GRAVE:
|
||||
case DIALOG_CHAR_UPPER_A_CIRCUMFLEX:
|
||||
case DIALOG_CHAR_UPPER_A_UMLAUT:
|
||||
#endif
|
||||
render_uppercase_diacritic(&xCoord, &yCoord, ASCII_TO_DIALOG('A'), str[strPos] & 0xF);
|
||||
break;
|
||||
case DIALOG_CHAR_LOWER_E_GRAVE:
|
||||
|
@ -434,14 +440,25 @@ void print_generic_string(s16 x, s16 y, const u8 *str) {
|
|||
case DIALOG_CHAR_LOWER_U_UMLAUT:
|
||||
render_lowercase_diacritic(&xCoord, &yCoord, ASCII_TO_DIALOG('u'), str[strPos] & 0xF);
|
||||
break;
|
||||
#ifndef QOL_FIXES
|
||||
case DIALOG_CHAR_UPPER_U_UMLAUT: // @bug grave and circumflex (0x84-0x85) are absent here
|
||||
#else
|
||||
case DIALOG_CHAR_UPPER_U_GRAVE:
|
||||
case DIALOG_CHAR_UPPER_U_CIRCUMFLEX:
|
||||
case DIALOG_CHAR_UPPER_U_UMLAUT:
|
||||
#endif
|
||||
render_uppercase_diacritic(&xCoord, &yCoord, ASCII_TO_DIALOG('U'), str[strPos] & 0xF);
|
||||
break;
|
||||
case DIALOG_CHAR_LOWER_O_CIRCUMFLEX:
|
||||
case DIALOG_CHAR_LOWER_O_UMLAUT:
|
||||
render_lowercase_diacritic(&xCoord, &yCoord, ASCII_TO_DIALOG('o'), str[strPos] & 0xF);
|
||||
break;
|
||||
#ifndef QOL_FIXES
|
||||
case DIALOG_CHAR_UPPER_O_UMLAUT: // @bug circumflex (0x95) is absent here
|
||||
#else
|
||||
case DIALOG_CHAR_UPPER_O_CIRCUMFLEX:
|
||||
case DIALOG_CHAR_UPPER_O_UMLAUT:
|
||||
#endif
|
||||
render_uppercase_diacritic(&xCoord, &yCoord, ASCII_TO_DIALOG('O'), str[strPos] & 0xF);
|
||||
break;
|
||||
case DIALOG_CHAR_LOWER_I_CIRCUMFLEX:
|
||||
|
@ -589,11 +606,15 @@ void print_hud_lut_string(s8 hudLUT, s16 x, s16 y, const u8 *str) {
|
|||
#endif
|
||||
#if defined(VERSION_US) || defined(VERSION_SH)
|
||||
if (str[strPos] == GLOBAL_CHAR_SPACE) {
|
||||
#ifndef QOL_FIXES
|
||||
if (0) //! dead code
|
||||
{
|
||||
}
|
||||
#endif
|
||||
curX += 8;
|
||||
#ifndef QOL_FIXES
|
||||
; //! useless statement
|
||||
#endif
|
||||
} else {
|
||||
#endif
|
||||
gDPPipeSync(gDisplayListHead++);
|
||||
|
@ -751,6 +772,7 @@ void handle_menu_scrolling(s8 scrollDirection, s8 *currentIndex, s8 minIndex, s8
|
|||
}
|
||||
|
||||
if (((index ^ gMenuHoldKeyIndex) & index) == 2) {
|
||||
#ifndef QOL_FIXES
|
||||
if (currentIndex[0] == maxIndex) {
|
||||
//! Probably originally a >=, but later replaced with an == and an else statement.
|
||||
currentIndex[0] = maxIndex;
|
||||
|
@ -758,6 +780,13 @@ void handle_menu_scrolling(s8 scrollDirection, s8 *currentIndex, s8 minIndex, s8
|
|||
play_sound(SOUND_MENU_CHANGE_SELECT, gDefaultSoundArgs);
|
||||
currentIndex[0]++;
|
||||
}
|
||||
#else
|
||||
// if >=, this could cause an OOB array access and crash. Use > instead here to fix this.
|
||||
if (currentIndex[0] > maxIndex) {
|
||||
play_sound(SOUND_MENU_CHANGE_SELECT, gDefaultSoundArgs);
|
||||
currentIndex[0]++;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
if (((index ^ gMenuHoldKeyIndex) & index) == 1) {
|
||||
|
@ -809,10 +838,14 @@ s16 get_str_x_pos_from_center_scale(s16 centerPos, u8 *str, f32 scale) {
|
|||
//! EU checks for dakuten and handakuten despite dialog code unable to handle it
|
||||
if (str[strPos] == DIALOG_CHAR_SPACE) {
|
||||
spacesWidth += 1.0;
|
||||
#if (defined(VERSION_EU) && !defined(QOL_FIXES)) || defined(VERSION_JP) || defined(VERSION_SH)
|
||||
} else if (str[strPos] != DIALOG_CHAR_DAKUTEN
|
||||
&& str[strPos] != DIALOG_CHAR_PERIOD_OR_HANDAKUTEN) {
|
||||
charsWidth += 1.0;
|
||||
}
|
||||
#elif (defined(VERSION_EU) && defined(QOL_FIXES))
|
||||
}
|
||||
#endif
|
||||
strPos++;
|
||||
}
|
||||
// return the x position of where the string starts as half the string's
|
||||
|
@ -2780,8 +2813,11 @@ void print_hud_course_complete_coins(s16 x, s16 y) {
|
|||
if ((gCourseDoneMenuTimer & 1) || gHudDisplay.coins > 70) {
|
||||
gCourseCompleteCoins++;
|
||||
play_sound(SOUND_MENU_YOSHI_GAIN_LIVES, gDefaultSoundArgs);
|
||||
|
||||
#ifndef QOL_FIXES
|
||||
if (gCourseCompleteCoins == 50 || gCourseCompleteCoins == 100 || gCourseCompleteCoins == 150) {
|
||||
#else
|
||||
if (gCourseCompleteCoins % 50 == 0) {
|
||||
#endif
|
||||
play_sound(SOUND_GENERAL_COLLECT_1UP, gDefaultSoundArgs);
|
||||
gMarioState[0].numLives++;
|
||||
}
|
||||
|
|
|
@ -1477,7 +1477,7 @@ u32 interact_pole(struct MarioState *m, UNUSED u32 interactType, struct Object *
|
|||
s32 actionId = m->action & ACT_ID_MASK;
|
||||
if (actionId >= 0x080 && actionId < 0x0A0) {
|
||||
if (!(m->prevAction & ACT_FLAG_ON_POLE) || m->usedObj != o) {
|
||||
#ifdef VERSION_SH
|
||||
#if BUGFIX_PRESERVE_VEL_POLE
|
||||
f32 velConv = m->forwardVel; // conserve the velocity.
|
||||
struct Object *marioObj = m->marioObj;
|
||||
u32 lowSpeed;
|
||||
|
@ -1488,7 +1488,7 @@ u32 interact_pole(struct MarioState *m, UNUSED u32 interactType, struct Object *
|
|||
|
||||
mario_stop_riding_and_holding(m);
|
||||
|
||||
#ifdef VERSION_SH
|
||||
#if BUGFIX_PRESERVE_VEL_POLE
|
||||
lowSpeed = (velConv <= 10.0f);
|
||||
#endif
|
||||
|
||||
|
@ -1496,6 +1496,9 @@ u32 interact_pole(struct MarioState *m, UNUSED u32 interactType, struct Object *
|
|||
m->usedObj = o;
|
||||
m->vel[1] = 0.0f;
|
||||
m->forwardVel = 0.0f;
|
||||
#ifdef QOL_FIXES
|
||||
m->pos[1] = max(o->oPosY, m->pos[1]);
|
||||
#endif
|
||||
|
||||
marioObj->oMarioPoleUnk108 = 0;
|
||||
marioObj->oMarioPoleYawVel = 0;
|
||||
|
@ -1507,7 +1510,7 @@ u32 interact_pole(struct MarioState *m, UNUSED u32 interactType, struct Object *
|
|||
|
||||
//! @bug Using m->forwardVel here is assumed to be 0.0f due to the set from earlier.
|
||||
// This is fixed in the Shindou version.
|
||||
#ifdef VERSION_SH
|
||||
#if BUGFIX_PRESERVE_VEL_POLE
|
||||
marioObj->oMarioPoleYawVel = (s32)(velConv * 0x100 + 0x1000);
|
||||
#else
|
||||
marioObj->oMarioPoleYawVel = (s32)(m->forwardVel * 0x100 + 0x1000);
|
||||
|
|
|
@ -1071,7 +1071,11 @@ void level_set_transition(s16 length, void (*updateFunction)(s16 *)) {
|
|||
s32 play_mode_change_area(void) {
|
||||
//! This maybe was supposed to be sTransitionTimer == -1? sTransitionUpdate
|
||||
// is never set to -1.
|
||||
#ifndef QOL_FIXES
|
||||
if (sTransitionUpdate == (void (*)(s16 *)) - 1) {
|
||||
#else
|
||||
if (sTransitionTimer == -1) {
|
||||
#endif
|
||||
update_camera(gCurrentArea->camera);
|
||||
} else if (sTransitionUpdate != NULL) {
|
||||
sTransitionUpdate(&sTransitionTimer);
|
||||
|
@ -1082,7 +1086,11 @@ s32 play_mode_change_area(void) {
|
|||
}
|
||||
|
||||
//! If sTransitionTimer is -1, this will miss.
|
||||
#ifndef QOL_FIXES
|
||||
if (sTransitionTimer == 0) {
|
||||
#else
|
||||
if (sTransitionTimer <= 0) {
|
||||
#endif
|
||||
sTransitionUpdate = NULL;
|
||||
set_play_mode(PLAY_MODE_NORMAL);
|
||||
}
|
||||
|
@ -1099,7 +1107,11 @@ s32 play_mode_change_level(void) {
|
|||
}
|
||||
|
||||
//! If sTransitionTimer is -1, this will miss.
|
||||
#ifndef QOL_FIXES
|
||||
if (--sTransitionTimer == -1) {
|
||||
#else
|
||||
if (sTransitionTimer <= 0) {
|
||||
#endif
|
||||
gHudDisplay.flags = HUD_DISPLAY_NONE;
|
||||
sTransitionTimer = 0;
|
||||
sTransitionUpdate = NULL;
|
||||
|
@ -1118,7 +1130,12 @@ s32 play_mode_change_level(void) {
|
|||
* Unused play mode. Doesn't call transition update and doesn't reset transition at the end.
|
||||
*/
|
||||
static s32 play_mode_unused(void) {
|
||||
//! If sTransitionTimer is -1, this will miss.
|
||||
#ifndef QOL_FIXES
|
||||
if (--sTransitionTimer == -1) {
|
||||
#else
|
||||
if (sTransitionTimer <= 0) {
|
||||
#endif
|
||||
gHudDisplay.flags = HUD_DISPLAY_NONE;
|
||||
|
||||
if (sWarpDest.type != WARP_TYPE_NOT_WARPING) {
|
||||
|
@ -1145,7 +1162,11 @@ s32 update_level(void) {
|
|||
changeLevel = play_mode_change_area();
|
||||
break;
|
||||
case PLAY_MODE_CHANGE_LEVEL:
|
||||
#if USE_UNUSED_PLAY_STATE
|
||||
changeLevel = play_mode_unused();
|
||||
#else
|
||||
changeLevel = play_mode_change_level();
|
||||
#endif
|
||||
break;
|
||||
case PLAY_MODE_FRAME_ADVANCE:
|
||||
changeLevel = play_mode_frame_advance();
|
||||
|
|
|
@ -112,7 +112,11 @@ void unknown_main_func(void) {
|
|||
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wnonnull"
|
||||
#ifndef QOL_FIXES
|
||||
sprintf(NULL, NULL);
|
||||
#else
|
||||
sprintf("", "");
|
||||
#endif
|
||||
#pragma GCC diagnostic pop
|
||||
}
|
||||
|
||||
|
|
|
@ -879,7 +879,13 @@ static u32 set_mario_action_airborne(struct MarioState *m, u32 action, u32 actio
|
|||
// too much velocity, but misses backwards longs allowing high negative speeds.
|
||||
if ((m->forwardVel *= 1.5f) > 48.0f) {
|
||||
m->forwardVel = 48.0f;
|
||||
#if BUGFIX_BLJ
|
||||
} else if ((m->forwardVel *= 1.5f) < -48.0f) {
|
||||
m->forwardVel = -48.0f;
|
||||
}
|
||||
#else
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
|
||||
case ACT_SLIDE_KICK:
|
||||
|
@ -1532,7 +1538,11 @@ void update_mario_health(struct MarioState *m) {
|
|||
}
|
||||
|
||||
// Play a noise to alert the player when Mario is close to drowning.
|
||||
if (((m->action & ACT_GROUP_MASK) == ACT_GROUP_SUBMERGED) && (m->health < 0x300)) {
|
||||
if (((m->action & ACT_GROUP_MASK) == ACT_GROUP_SUBMERGED) && (m->health < 0x300)
|
||||
#ifdef QOL_FIXES
|
||||
&& !((m->flags & (MARIO_METAL_CAP)) > 0)
|
||||
#endif
|
||||
) {
|
||||
play_sound(SOUND_MOVING_ALMOST_DROWNING, gDefaultSoundArgs);
|
||||
if (!gRumblePakTimer) {
|
||||
gRumblePakTimer = 36;
|
||||
|
|
|
@ -160,7 +160,11 @@ s32 check_horizontal_wind(struct MarioState *m) {
|
|||
if (speed > 48.0f) {
|
||||
m->slideVelX = m->slideVelX * 48.0f / speed;
|
||||
m->slideVelZ = m->slideVelZ * 48.0f / speed;
|
||||
#ifndef QOL_FIXES
|
||||
speed = 32.0f; //! This was meant to be 48?
|
||||
#else
|
||||
speed = 48.0f;
|
||||
#endif
|
||||
} else if (speed > 32.0f) {
|
||||
speed = 32.0f;
|
||||
}
|
||||
|
@ -2069,17 +2073,54 @@ s32 act_special_triple_jump(struct MarioState *m) {
|
|||
|
||||
switch (perform_air_step(m, 0)) {
|
||||
case AIR_STEP_LANDED:
|
||||
#ifndef QOL_FIXES
|
||||
if (m->actionState++ == 0) {
|
||||
m->vel[1] = 42.0f;
|
||||
} else {
|
||||
set_mario_action(m, ACT_FREEFALL_LAND_STOP, 0);
|
||||
}
|
||||
#else
|
||||
if (m->actionState++ != 0) {
|
||||
set_mario_action(m, ACT_FREEFALL_LAND_STOP, 0);
|
||||
}
|
||||
#endif
|
||||
play_mario_landing_sound(m, SOUND_ACTION_TERRAIN_LANDING);
|
||||
break;
|
||||
|
||||
#ifdef QOL_FIXES
|
||||
case AIR_STEP_HIT_WALL:
|
||||
if (m->forwardVel > 16.0f) {
|
||||
mario_bonk_reflection(m, FALSE);
|
||||
m->faceAngle[1] += 0x8000;
|
||||
if (m->wall != NULL)
|
||||
set_mario_action(m, ACT_AIR_HIT_WALL, 0);
|
||||
else {
|
||||
if (m->vel[1] > 0.0f)
|
||||
m->vel[1] = 0.0f;
|
||||
if (m->forwardVel >= 38.0f) {
|
||||
m->particleFlags |= PARTICLE_VERTICAL_STAR;
|
||||
set_mario_action(m, ACT_BACKWARD_AIR_KB, 0);
|
||||
} else {
|
||||
if (m->forwardVel > 8.0f)
|
||||
mario_set_forward_vel(m, -8.0f);
|
||||
return set_mario_action(m, ACT_SOFT_BONK, 0);
|
||||
}
|
||||
}
|
||||
} else
|
||||
mario_set_forward_vel(m, 0.0f);
|
||||
break;
|
||||
case AIR_STEP_GRABBED_LEDGE:
|
||||
set_mario_animation(m, MARIO_ANIM_IDLE_ON_LEDGE);
|
||||
drop_and_set_mario_action(m, ACT_LEDGE_GRAB, 0);
|
||||
break;
|
||||
case AIR_STEP_GRABBED_CEILING:
|
||||
set_mario_action(m, ACT_START_HANGING, 0);
|
||||
break;
|
||||
#else
|
||||
case AIR_STEP_HIT_WALL:
|
||||
mario_bonk_reflection(m, TRUE);
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
|
||||
if (m->actionState == 0 || m->vel[1] > 0.0f) {
|
||||
|
|
|
@ -400,7 +400,11 @@ s32 act_start_hanging(struct MarioState *m) {
|
|||
}
|
||||
|
||||
//! Crash if Mario's referenced ceiling is NULL (same for other hanging actions)
|
||||
#ifndef QOL_FIXES
|
||||
if (m->ceil->type != SURFACE_HANGABLE) {
|
||||
#else
|
||||
if (m->ceil->type != SURFACE_HANGABLE || m->ceil->type == NULL) {
|
||||
#endif
|
||||
return set_mario_action(m, ACT_FREEFALL, 0);
|
||||
}
|
||||
|
||||
|
|
|
@ -603,7 +603,11 @@ void general_star_dance_handler(struct MarioState *m, s32 isInWater) {
|
|||
if (m->actionState == 0) {
|
||||
switch (++m->actionTimer) {
|
||||
case 1:
|
||||
#ifdef QOL_FIXES
|
||||
spawn_object(m->marioObj, MODEL_NONE, bhvCelebrationStar)->header.gfx.sharedChild = m->interactObj->header.gfx.sharedChild;
|
||||
#else
|
||||
spawn_object(m->marioObj, MODEL_STAR, bhvCelebrationStar);
|
||||
#endif
|
||||
disable_background_sound();
|
||||
if (m->actionArg & 1) {
|
||||
play_course_clear();
|
||||
|
@ -1119,15 +1123,27 @@ s32 act_exit_land_save_dialog(struct MarioState *m) {
|
|||
switch (animFrame) {
|
||||
case -1:
|
||||
spawn_obj_at_mario_rel_yaw(m, MODEL_BOWSER_KEY_CUTSCENE, bhvBowserKeyCourseExit, -32768);
|
||||
#ifdef QOL_FIXES
|
||||
break;
|
||||
#endif
|
||||
//! fall through
|
||||
case 67:
|
||||
play_sound(SOUND_ACTION_KEY_SWISH, m->marioObj->header.gfx.cameraToObject);
|
||||
#ifdef QOL_FIXES
|
||||
break;
|
||||
#endif
|
||||
//! fall through
|
||||
case 83:
|
||||
play_sound(SOUND_ACTION_PAT_BACK, m->marioObj->header.gfx.cameraToObject);
|
||||
#ifdef QOL_FIXES
|
||||
break;
|
||||
#endif
|
||||
//! fall through
|
||||
case 111:
|
||||
play_sound(SOUND_ACTION_UNKNOWN45C, m->marioObj->header.gfx.cameraToObject);
|
||||
#ifdef QOL_FIXES
|
||||
break;
|
||||
#endif
|
||||
// no break
|
||||
}
|
||||
handle_save_menu(m);
|
||||
|
@ -1965,10 +1981,16 @@ void generate_yellow_sparkles(s16 x, s16 y, s16 z, f32 radius) {
|
|||
spawn_object_abs_with_rot(gCurrentObject, 0, MODEL_NONE, bhvSparkleSpawn, x + offsetX, y + offsetY,
|
||||
z + offsetZ, 0, 0, 0);
|
||||
|
||||
#ifndef QOL_FIXES
|
||||
//! copy paste error
|
||||
offsetX = offsetX * 4 / 3;
|
||||
offsetX = offsetY * 4 / 3;
|
||||
offsetX = offsetZ * 4 / 3;
|
||||
#else
|
||||
offsetX = offsetX * 4 / 3;
|
||||
offsetY = offsetY * 4 / 3;
|
||||
offsetZ = offsetZ * 4 / 3;
|
||||
#endif
|
||||
|
||||
spawn_object_abs_with_rot(gCurrentObject, 0, MODEL_NONE, bhvSparkleSpawn, x - offsetX, y - offsetY,
|
||||
z - offsetZ, 0, 0, 0);
|
||||
|
|
|
@ -524,11 +524,19 @@ s32 begin_braking_action(struct MarioState *m) {
|
|||
}
|
||||
|
||||
void anim_and_audio_for_walk(struct MarioState *m) {
|
||||
#ifndef QOL_FIXES
|
||||
s32 val14;
|
||||
#else
|
||||
s64 val14;
|
||||
#endif
|
||||
struct Object *marioObj = m->marioObj;
|
||||
s32 val0C = TRUE;
|
||||
s16 targetPitch = 0;
|
||||
#ifndef QOL_FIXES
|
||||
f32 val04;
|
||||
#else
|
||||
f64 val04;
|
||||
#endif
|
||||
|
||||
val04 = m->intendedMag > m->forwardVel ? m->intendedMag : m->forwardVel;
|
||||
|
||||
|
@ -537,7 +545,11 @@ void anim_and_audio_for_walk(struct MarioState *m) {
|
|||
}
|
||||
|
||||
if (m->quicksandDepth > 50.0f) {
|
||||
#ifndef QOL_FIXES
|
||||
val14 = (s32)(val04 / 4.0f * 0x10000);
|
||||
#else
|
||||
val14 = (s64)(val04 / 4.0f * 0x10000);
|
||||
#endif
|
||||
set_mario_anim_with_accel(m, MARIO_ANIM_MOVE_IN_QUICKSAND, val14);
|
||||
play_step_sound(m, 19, 93);
|
||||
m->actionTimer = 0;
|
||||
|
@ -549,7 +561,11 @@ void anim_and_audio_for_walk(struct MarioState *m) {
|
|||
m->actionTimer = 2;
|
||||
} else {
|
||||
//! (Speed Crash) If Mario's speed is more than 2^17.
|
||||
#ifndef QOL_FIXES
|
||||
if ((val14 = (s32)(val04 / 4.0f * 0x10000)) < 0x1000) {
|
||||
#else
|
||||
if ((val14 = (s64)(val04 / 4.0f * 0x10000)) < 0x1000) {
|
||||
#endif
|
||||
val14 = 0x1000;
|
||||
}
|
||||
set_mario_anim_with_accel(m, MARIO_ANIM_START_TIPTOE, val14);
|
||||
|
@ -567,7 +583,11 @@ void anim_and_audio_for_walk(struct MarioState *m) {
|
|||
m->actionTimer = 2;
|
||||
} else {
|
||||
//! (Speed Crash) If Mario's speed is more than 2^17.
|
||||
#ifndef QOL_FIXES
|
||||
if ((val14 = (s32)(val04 * 0x10000)) < 0x1000) {
|
||||
#else
|
||||
if ((val14 = (s64)(val04 * 0x10000)) < 0x1000) {
|
||||
#endif
|
||||
val14 = 0x1000;
|
||||
}
|
||||
set_mario_anim_with_accel(m, MARIO_ANIM_TIPTOE, val14);
|
||||
|
@ -584,7 +604,11 @@ void anim_and_audio_for_walk(struct MarioState *m) {
|
|||
m->actionTimer = 3;
|
||||
} else {
|
||||
//! (Speed Crash) If Mario's speed is more than 2^17.
|
||||
#ifndef QOL_FIXES
|
||||
val14 = (s32)(val04 / 4.0f * 0x10000);
|
||||
#else
|
||||
val14 = (s64)(val04 / 4.0f * 0x10000);
|
||||
#endif
|
||||
set_mario_anim_with_accel(m, MARIO_ANIM_WALKING, val14);
|
||||
play_step_sound(m, 10, 49);
|
||||
|
||||
|
@ -597,7 +621,11 @@ void anim_and_audio_for_walk(struct MarioState *m) {
|
|||
m->actionTimer = 2;
|
||||
} else {
|
||||
//! (Speed Crash) If Mario's speed is more than 2^17.
|
||||
#ifndef QOL_FIXES
|
||||
val14 = (s32)(val04 / 4.0f * 0x10000);
|
||||
#else
|
||||
val14 = (s64)(val04 / 4.0f * 0x10000);
|
||||
#endif
|
||||
set_mario_anim_with_accel(m, MARIO_ANIM_RUNNING, val14);
|
||||
play_step_sound(m, 9, 45);
|
||||
targetPitch = tilt_body_running(m);
|
||||
|
@ -615,9 +643,17 @@ void anim_and_audio_for_walk(struct MarioState *m) {
|
|||
}
|
||||
|
||||
void anim_and_audio_for_hold_walk(struct MarioState *m) {
|
||||
#ifndef QOL_FIXES
|
||||
s32 val0C;
|
||||
#else
|
||||
s64 val0C;
|
||||
#endif
|
||||
s32 val08 = TRUE;
|
||||
#ifndef QOL_FIXES
|
||||
f32 val04;
|
||||
#else
|
||||
f64 val04;
|
||||
#endif
|
||||
|
||||
val04 = m->intendedMag > m->forwardVel ? m->intendedMag : m->forwardVel;
|
||||
|
||||
|
@ -632,7 +668,11 @@ void anim_and_audio_for_hold_walk(struct MarioState *m) {
|
|||
m->actionTimer = 1;
|
||||
} else {
|
||||
//! (Speed Crash) Crashes if Mario's speed exceeds or equals 2^15.
|
||||
#ifndef QOL_FIXES
|
||||
val0C = (s32)(val04 * 0x10000);
|
||||
#else
|
||||
val0C = (s64)(val04 * 0x10000);
|
||||
#endif
|
||||
set_mario_anim_with_accel(m, MARIO_ANIM_SLOW_WALK_WITH_LIGHT_OBJ, val0C);
|
||||
play_step_sound(m, 12, 62);
|
||||
|
||||
|
@ -647,7 +687,11 @@ void anim_and_audio_for_hold_walk(struct MarioState *m) {
|
|||
m->actionTimer = 2;
|
||||
} else {
|
||||
//! (Speed Crash) Crashes if Mario's speed exceeds or equals 2^15.
|
||||
#ifndef QOL_FIXES
|
||||
val0C = (s32)(val04 * 0x10000);
|
||||
#else
|
||||
val0C = (s64)(val04 * 0x10000);
|
||||
#endif
|
||||
set_mario_anim_with_accel(m, MARIO_ANIM_WALK_WITH_LIGHT_OBJ, val0C);
|
||||
play_step_sound(m, 12, 62);
|
||||
|
||||
|
@ -660,7 +704,11 @@ void anim_and_audio_for_hold_walk(struct MarioState *m) {
|
|||
m->actionTimer = 1;
|
||||
} else {
|
||||
//! (Speed Crash) Crashes if Mario's speed exceeds or equals 2^16.
|
||||
#ifndef QOL_FIXES
|
||||
val0C = (s32)(val04 / 2.0f * 0x10000);
|
||||
#else
|
||||
val0C = (s64)(val04 / 2.0f * 0x10000);
|
||||
#endif
|
||||
set_mario_anim_with_accel(m, MARIO_ANIM_RUN_WITH_LIGHT_OBJ, val0C);
|
||||
play_step_sound(m, 10, 49);
|
||||
|
||||
|
@ -684,7 +732,11 @@ void push_or_sidle_wall(struct MarioState *m, Vec3f startPos) {
|
|||
f32 dz = m->pos[2] - startPos[2];
|
||||
f32 movedDistance = sqrtf(dx * dx + dz * dz);
|
||||
//! (Speed Crash) If a wall is after moving 16384 distance, this crashes.
|
||||
#ifndef QOL_FIXES
|
||||
s32 val04 = (s32)(movedDistance * 2.0f * 0x10000);
|
||||
#else
|
||||
s64 val04 = (s64)(movedDistance * 2.0f * 0x10000);
|
||||
#endif
|
||||
|
||||
if (m->forwardVel > 6.0f) {
|
||||
mario_set_forward_vel(m, 6.0f);
|
||||
|
@ -723,15 +775,25 @@ void tilt_body_walking(struct MarioState *m, s16 startYaw) {
|
|||
UNUSED struct Object *marioObj = m->marioObj;
|
||||
s16 animID = m->marioObj->header.gfx.unk38.animID;
|
||||
s16 dYaw;
|
||||
#ifndef QOL_FIXES
|
||||
s16 val02;
|
||||
s16 val00;
|
||||
#else
|
||||
s64 val02;
|
||||
s64 val00;
|
||||
#endif
|
||||
|
||||
if (animID == MARIO_ANIM_WALKING || animID == MARIO_ANIM_RUNNING) {
|
||||
dYaw = m->faceAngle[1] - startYaw;
|
||||
//! (Speed Crash) These casts can cause a crash if (dYaw * forwardVel / 12) or
|
||||
//! (forwardVel * 170) exceed or equal 2^31.
|
||||
#ifndef QOL_FIXES
|
||||
val02 = -(s16)(dYaw * m->forwardVel / 12.0f);
|
||||
val00 = (s16)(m->forwardVel * 170.0f);
|
||||
#else
|
||||
val02 = -(s64)(dYaw * m->forwardVel / 12.0f);
|
||||
val00 = (s64)(m->forwardVel * 170.0f);
|
||||
#endif
|
||||
|
||||
if (val02 > 0x1555) {
|
||||
val02 = 0x1555;
|
||||
|
@ -747,9 +809,16 @@ void tilt_body_walking(struct MarioState *m, s16 startYaw) {
|
|||
val00 = 0;
|
||||
}
|
||||
|
||||
#ifndef QOL_FIXES
|
||||
val0C->torsoAngle[2] = approach_s32(val0C->torsoAngle[2], val02, 0x400, 0x400);
|
||||
val0C->torsoAngle[0] = approach_s32(val0C->torsoAngle[0], val00, 0x400, 0x400);
|
||||
#else
|
||||
val0C->torsoAngle[2] = approach_s64(val0C->torsoAngle[2], val02, 0x400, 0x400);
|
||||
val0C->torsoAngle[0] = approach_s64(val0C->torsoAngle[0], val00, 0x400, 0x400);
|
||||
#endif
|
||||
#ifndef QOL_FIXES
|
||||
;
|
||||
#endif
|
||||
} else {
|
||||
val0C->torsoAngle[2] = 0;
|
||||
val0C->torsoAngle[0] = 0;
|
||||
|
@ -763,8 +832,13 @@ void tilt_body_ground_shell(struct MarioState *m, s16 startYaw) {
|
|||
//! (Speed Crash) These casts can cause a crash if (dYaw * forwardVel / 12) or
|
||||
//! (forwardVel * 170) exceed or equal 2^31. Harder (if not impossible to do)
|
||||
//! while on a Koopa Shell making this less of an issue.
|
||||
#ifndef QOL_FIXES
|
||||
s16 val04 = -(s16)(dYaw * m->forwardVel / 12.0f);
|
||||
s16 val02 = (s16)(m->forwardVel * 170.0f);
|
||||
#else
|
||||
s64 val04 = -(s64)(dYaw * m->forwardVel / 12.0f);
|
||||
s64 val02 = (s64)(m->forwardVel * 170.0f);
|
||||
#endif
|
||||
|
||||
if (val04 > 0x1800) {
|
||||
val04 = 0x1800;
|
||||
|
@ -780,8 +854,13 @@ void tilt_body_ground_shell(struct MarioState *m, s16 startYaw) {
|
|||
val02 = 0;
|
||||
}
|
||||
|
||||
#ifndef QOL_FIXES
|
||||
val0C->torsoAngle[2] = approach_s32(val0C->torsoAngle[2], val04, 0x200, 0x200);
|
||||
val0C->torsoAngle[0] = approach_s32(val0C->torsoAngle[0], val02, 0x200, 0x200);
|
||||
#else
|
||||
val0C->torsoAngle[2] = approach_s64(val0C->torsoAngle[2], val04, 0x200, 0x200);
|
||||
val0C->torsoAngle[0] = approach_s64(val0C->torsoAngle[0], val02, 0x200, 0x200);
|
||||
#endif
|
||||
val0C->headAngle[2] = -val0C->torsoAngle[2];
|
||||
|
||||
marioObj->header.gfx.angle[2] = val0C->torsoAngle[2];
|
||||
|
@ -814,9 +893,20 @@ s32 act_walking(struct MarioState *m) {
|
|||
return begin_braking_action(m);
|
||||
}
|
||||
|
||||
#ifdef QOL_FIXES
|
||||
if (analog_stick_held_back(m)) {
|
||||
if (m->forwardVel >= 16.0f){
|
||||
return set_mario_action(m, ACT_TURNING_AROUND, 0);
|
||||
} else if ((m->forwardVel) < 10.0f && (m->forwardVel > 0.0f)){
|
||||
m->faceAngle[1] = m->intendedYaw;
|
||||
return set_mario_action(m, ACT_TURNING_AROUND, 0);
|
||||
}
|
||||
}
|
||||
#else
|
||||
if (analog_stick_held_back(m) && m->forwardVel >= 16.0f) {
|
||||
return set_mario_action(m, ACT_TURNING_AROUND, 0);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (m->input & INPUT_Z_PRESSED) {
|
||||
return set_mario_action(m, ACT_CROUCH_SLIDE, 0);
|
||||
|
@ -1146,7 +1236,11 @@ s32 act_decelerating(struct MarioState *m) {
|
|||
}
|
||||
|
||||
s32 act_hold_decelerating(struct MarioState *m) {
|
||||
#ifndef QOL_FIXES
|
||||
s32 val0C;
|
||||
#else
|
||||
s64 val0C;
|
||||
#endif
|
||||
s16 slopeClass = mario_get_floor_class(m);
|
||||
|
||||
if (m->marioObj->oInteractStatus & INT_STATUS_MARIO_DROP_OBJECT) {
|
||||
|
@ -1200,7 +1294,11 @@ s32 act_hold_decelerating(struct MarioState *m) {
|
|||
m->particleFlags |= PARTICLE_DUST;
|
||||
} else {
|
||||
//! (Speed Crash) This crashes if Mario has more speed than 2^15 speed.
|
||||
#ifndef QOL_FIXES
|
||||
if ((val0C = (s32)(m->forwardVel * 0x10000)) < 0x1000) {
|
||||
#else
|
||||
if ((val0C = (s64)(m->forwardVel * 0x10000)) < 0x1000) {
|
||||
#endif
|
||||
val0C = 0x1000;
|
||||
}
|
||||
|
||||
|
@ -1298,6 +1396,9 @@ s32 act_crawling(struct MarioState *m) {
|
|||
mario_set_forward_vel(m, 10.0f);
|
||||
}
|
||||
//! Possibly unintended missing break
|
||||
#ifdef QOL_FIXES
|
||||
break;
|
||||
#endif
|
||||
|
||||
case GROUND_STEP_NONE:
|
||||
align_with_floor(m);
|
||||
|
@ -1762,6 +1863,12 @@ s32 common_landing_cancels(struct MarioState *m, struct LandingAction *landingAc
|
|||
//! Everything here, including floor steepness, is checked before checking
|
||||
// if Mario is actually on the floor. This leads to e.g. remote sliding.
|
||||
|
||||
#ifdef QOL_FIXES
|
||||
if (m->input & INPUT_OFF_FLOOR) {
|
||||
return set_mario_action(m, landingAction->offFloorAction, 0);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (m->floor->normal.y < 0.2923717f) {
|
||||
return mario_push_off_steep_floor(m, landingAction->verySteepAction, 0);
|
||||
}
|
||||
|
@ -1784,9 +1891,11 @@ s32 common_landing_cancels(struct MarioState *m, struct LandingAction *landingAc
|
|||
return setAPressAction(m, landingAction->aPressedAction, 0);
|
||||
}
|
||||
|
||||
#ifndef QOL_FIXES
|
||||
if (m->input & INPUT_OFF_FLOOR) {
|
||||
return set_mario_action(m, landingAction->offFloorAction, 0);
|
||||
}
|
||||
#endif
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
|
|
@ -220,7 +220,11 @@ s32 act_dive_picking_up(struct MarioState *m) {
|
|||
// landing from a dive grab sets Mario's action to a non-holding action
|
||||
// without dropping the object, causing the hands-free holding glitch.
|
||||
if (m->input & INPUT_OFF_FLOOR) {
|
||||
#ifndef QOL_FIXES
|
||||
return set_mario_action(m, ACT_FREEFALL, 0);
|
||||
#else
|
||||
return drop_and_set_mario_action(m, ACT_FREEFALL, 0);
|
||||
#endif
|
||||
}
|
||||
|
||||
if (m->input & INPUT_ABOVE_SLIDE) {
|
||||
|
|
|
@ -57,8 +57,23 @@ void transfer_bully_speed(struct BullyCollisionData *obj1, struct BullyCollision
|
|||
f32 rz = obj2->posZ - obj1->posZ;
|
||||
|
||||
//! Bully NaN crash
|
||||
#ifndef QOL_FIXES
|
||||
f32 projectedV1 = (rx * obj1->velX + rz * obj1->velZ) / (rx * rx + rz * rz);
|
||||
f32 projectedV2 = (-rx * obj2->velX - rz * obj2->velZ) / (rx * rx + rz * rz);
|
||||
#else
|
||||
f32 projectedV1 = 0.0f;
|
||||
f32 projectedV2 = 0.0f;
|
||||
if ((rx * obj1->velX + rz * obj1->velZ) / (rx * rx + rz * rz) != NaN)
|
||||
|| ((-rx * obj2->velX - rz * obj2->velZ) / (rx * rx + rz * rz) != NaN)
|
||||
|| ((rx * obj1->velX + rz * obj1->velZ) / (rx * rx + rz * rz) != NaN
|
||||
&& (-rx * obj2->velX - rz * obj2->velZ) / (rx * rx + rz * rz) != NaN) {
|
||||
projectedV1 = (rx * obj1->velX + rz * obj1->velZ) / (rx * rx + rz * rz);
|
||||
projectedV2 = (-rx * obj2->velX - rz * obj2->velZ) / (rx * rx + rz * rz);
|
||||
} else {
|
||||
projectedV1 = 0.0f;
|
||||
projectedV2 = 0.0f;
|
||||
}
|
||||
#endif
|
||||
|
||||
// Kill speed along r. Convert one object's speed along r and transfer it to
|
||||
// the other object.
|
||||
|
@ -281,7 +296,12 @@ static s32 perform_ground_quarter_step(struct MarioState *m, Vec3f nextPos) {
|
|||
if ((m->action & ACT_FLAG_RIDING_SHELL) && floorHeight < waterLevel) {
|
||||
floorHeight = waterLevel;
|
||||
floor = &gWaterSurfacePseudoFloor;
|
||||
#ifndef QOL_FIXES
|
||||
floor->originOffset = floorHeight; //! Wrong origin offset (no effect)
|
||||
#else
|
||||
// this might have been waterLevel instead
|
||||
floor->originOffset = waterLevel;
|
||||
#endif
|
||||
}
|
||||
|
||||
if (nextPos[1] > floorHeight + 100.0f) {
|
||||
|
@ -368,7 +388,12 @@ u32 check_ledge_grab(struct MarioState *m, struct Surface *wall, Vec3f intendedP
|
|||
// a higher ledge than expected (glitchy ledge grab)
|
||||
ledgePos[0] = nextPos[0] - wall->normal.x * 60.0f;
|
||||
ledgePos[2] = nextPos[2] - wall->normal.z * 60.0f;
|
||||
#ifndef QOL_FIXES
|
||||
ledgePos[1] = find_floor(ledgePos[0], nextPos[1] + 160.0f, ledgePos[2], &ledgeFloor);
|
||||
#else
|
||||
// start the search for floors at y instead of y + 160
|
||||
ledgePos[1] = find_floor(ledgePos[0], nextPos[1], ledgePos[2], &ledgeFloor);
|
||||
#endif
|
||||
|
||||
if (ledgePos[1] - nextPos[1] <= 100.0f) {
|
||||
return 0;
|
||||
|
@ -424,7 +449,12 @@ s32 perform_air_quarter_step(struct MarioState *m, Vec3f intendedPos, u32 stepAr
|
|||
if ((m->action & ACT_FLAG_RIDING_SHELL) && floorHeight < waterLevel) {
|
||||
floorHeight = waterLevel;
|
||||
floor = &gWaterSurfacePseudoFloor;
|
||||
#ifndef QOL_FIXES
|
||||
floor->originOffset = floorHeight; //! Incorrect origin offset (no effect)
|
||||
#else
|
||||
// this might have been waterLevel instead
|
||||
floor->originOffset = waterLevel;
|
||||
#endif
|
||||
}
|
||||
|
||||
//! This check uses f32, but findFloor uses short (overflow jumps)
|
||||
|
@ -439,6 +469,11 @@ s32 perform_air_quarter_step(struct MarioState *m, Vec3f intendedPos, u32 stepAr
|
|||
//! When ceilHeight - floorHeight <= 160, the step result says that
|
||||
// Mario landed, but his movement is cancelled and his referenced floor
|
||||
// isn't updated (pedro spots)
|
||||
#ifdef QOL_FIXES
|
||||
m->pos[0] = nextPos[0];
|
||||
m->pos[2] = nextPos[2];
|
||||
m->floor = floor;
|
||||
#endif
|
||||
m->pos[1] = floorHeight;
|
||||
return AIR_STEP_LANDED;
|
||||
}
|
||||
|
|
|
@ -182,7 +182,9 @@ s32 turn_obj_away_from_steep_floor(struct Surface *objFloor, f32 floorY, f32 obj
|
|||
|
||||
if (objFloor == NULL) {
|
||||
//! (OOB Object Crash) TRUNC overflow exception after 36 minutes
|
||||
#ifndef QOL_FIXES
|
||||
o->oMoveAngleYaw += 32767.999200000002; /* ¯\_(ツ)_/¯ */
|
||||
#endif
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
@ -283,7 +285,11 @@ void calc_new_obj_vel_and_pos_y(struct Surface *objFloor, f32 objFloorY, f32 obj
|
|||
}
|
||||
|
||||
//! (Obj Position Crash) If you got an object with height past 2^31, the game would crash.
|
||||
#ifndef QOL_FIXES
|
||||
if ((s32) o->oPosY >= (s32) objFloorY && (s32) o->oPosY < (s32) objFloorY + 37) {
|
||||
#else
|
||||
if ((u32) o->oPosY >= (u32) objFloorY && (u32) o->oPosY < (u32) objFloorY + 37) {
|
||||
#endif
|
||||
obj_orient_graph(o, floor_nX, floor_nY, floor_nZ);
|
||||
|
||||
// Adds horizontal component of gravity for horizontal speed.
|
||||
|
@ -720,6 +726,9 @@ void obj_check_floor_death(s16 collisionFlags, struct Surface *floor) {
|
|||
o->oAction = OBJ_ACT_LAVA_DEATH;
|
||||
break;
|
||||
//! @BUG Doesn't check for the vertical wind death floor.
|
||||
#ifdef QOL_FIXES
|
||||
case SURFACE_VERTICAL_WIND:
|
||||
#endif
|
||||
case SURFACE_DEATH_PLANE:
|
||||
o->oAction = OBJ_ACT_DEATH_PLANE_DEATH;
|
||||
break;
|
||||
|
|
|
@ -564,7 +564,11 @@ static s32 obj_resolve_object_collisions(s32 *targetYaw) {
|
|||
|
||||
dx = otherObject->oPosX - o->oPosX;
|
||||
dz = otherObject->oPosZ - o->oPosZ;
|
||||
#ifndef QOL_FIXES
|
||||
angle = atan2s(dx, dz); //! This should be atan2s(dz, dx)
|
||||
#else
|
||||
angle = atan2s(dz, dx);
|
||||
#endif
|
||||
|
||||
radius = o->hitboxRadius;
|
||||
otherRadius = otherObject->hitboxRadius;
|
||||
|
|
|
@ -56,6 +56,9 @@ int detect_object_hitbox_overlap(struct Object *a, struct Object *b) {
|
|||
return 1;
|
||||
}
|
||||
|
||||
#ifdef QOL_FIXES
|
||||
return 0;
|
||||
#endif
|
||||
//! no return value
|
||||
}
|
||||
|
||||
|
@ -88,6 +91,9 @@ int detect_object_hurtbox_overlap(struct Object *a, struct Object *b) {
|
|||
return 1;
|
||||
}
|
||||
|
||||
#ifdef QOL_FIXES
|
||||
return 0;
|
||||
#endif
|
||||
//! no return value
|
||||
}
|
||||
|
||||
|
|
|
@ -1261,6 +1261,9 @@ static s32 cur_obj_move_xz(f32 steepSlopeNormalY, s32 careAboutEdgesAndSteepSlop
|
|||
o->oPosZ = intendedZ;
|
||||
//! Returning FALSE but moving anyway (not exploitable; return value is
|
||||
// never used)
|
||||
#ifdef QOL_FIXES
|
||||
return TRUE;
|
||||
#endif
|
||||
}
|
||||
|
||||
// We are likely trying to move onto a steep upward slope
|
||||
|
@ -1747,13 +1750,12 @@ static void cur_obj_update_floor(void) {
|
|||
if (floor->type == SURFACE_BURNING) {
|
||||
o->oMoveFlags |= OBJ_MOVE_ABOVE_LAVA;
|
||||
}
|
||||
#ifndef VERSION_JP
|
||||
#if !defined(VERSION_JP) || defined(QOL_FIXES)
|
||||
else if (floor->type == SURFACE_DEATH_PLANE) {
|
||||
//! This misses SURFACE_VERTICAL_WIND (and maybe SURFACE_WARP)
|
||||
o->oMoveFlags |= OBJ_MOVE_ABOVE_DEATH_BARRIER;
|
||||
}
|
||||
#endif
|
||||
|
||||
o->oFloorType = floor->type;
|
||||
o->oFloorRoom = floor->room;
|
||||
} else {
|
||||
|
@ -2590,7 +2592,7 @@ s32 cur_obj_update_dialog(s32 actionArg, s32 dialogFlags, s32 dialogID, UNUSED s
|
|||
UNUSED s32 doneTurning = TRUE;
|
||||
|
||||
switch (o->oDialogState) {
|
||||
#ifdef VERSION_JP
|
||||
#if (defined(VERSION_JP) && !defined(QOL_FIXES))
|
||||
case DIALOG_UNK1_ENABLE_TIME_STOP:
|
||||
//! We enable time stop even if Mario is not ready to speak. This
|
||||
// allows us to move during time stop as long as Mario never enters
|
||||
|
@ -2667,7 +2669,7 @@ s32 cur_obj_update_dialog_with_cutscene(s32 actionArg, s32 dialogFlags, s32 cuts
|
|||
s32 doneTurning = TRUE;
|
||||
|
||||
switch (o->oDialogState) {
|
||||
#ifdef VERSION_JP
|
||||
#if (defined(VERSION_JP) && !defined(QOL_FIXES))
|
||||
case DIALOG_UNK2_ENABLE_TIME_STOP:
|
||||
//! We enable time stop even if Mario is not ready to speak. This
|
||||
// allows us to move during time stop as long as Mario never enters
|
||||
|
|
|
@ -460,7 +460,7 @@ void spawn_objects_from_info(UNUSED s32 unused, struct SpawnInfo *spawnInfo) {
|
|||
//! (Spawning Displacement) On the Japanese version, Mario's platform object
|
||||
// isn't cleared when transitioning between areas. This can cause Mario to
|
||||
// receive displacement after spawning.
|
||||
#ifndef VERSION_JP
|
||||
#if BUGFIX_SPAWNING_DISPLACEMENT
|
||||
clear_mario_platform();
|
||||
#endif
|
||||
|
||||
|
@ -563,7 +563,11 @@ void clear_objects(void) {
|
|||
void update_terrain_objects(void) {
|
||||
gObjectCounter = update_objects_in_list(&gObjectLists[OBJ_LIST_SPAWNER]);
|
||||
//! This was meant to be +=
|
||||
#ifdef QOL_FIXES
|
||||
gObjectCounter += update_objects_in_list(&gObjectLists[OBJ_LIST_SURFACE]);
|
||||
#else
|
||||
gObjectCounter = update_objects_in_list(&gObjectLists[OBJ_LIST_SURFACE]);
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -214,10 +214,19 @@ void stop_other_paintings(s16 *idptr, struct Painting *paintingGroup[]) {
|
|||
f32 painting_mario_y(struct Painting *painting) {
|
||||
//! Unnecessary use of double constants
|
||||
// Add 50 to make the ripple closer to Mario's center of mass.
|
||||
#ifndef QOL_FIXES
|
||||
f32 relY = gPaintingMarioYPos - painting->posY + 50.0;
|
||||
#else
|
||||
f32 relY = gPaintingMarioYPos - painting->posY + 50.0f;
|
||||
#endif
|
||||
|
||||
#ifndef QOL_FIXES
|
||||
if (relY < 0.0) {
|
||||
relY = 0.0;
|
||||
#else
|
||||
if (relY < 0.0f) {
|
||||
relY = 0.0f;
|
||||
#endif
|
||||
} else if (relY > painting->size) {
|
||||
relY = painting->size;
|
||||
}
|
||||
|
@ -578,7 +587,15 @@ void painting_update_ripple_state(struct Painting *painting) {
|
|||
//! 16777216 (1 << 24), at which point it will freeze (due to floating-point
|
||||
//! imprecision?) and the painting will stop rippling. This happens to HMC, DDD, and
|
||||
//! CotMC. This happens on Wii VC. Untested on N64 and Wii U VC.
|
||||
#ifndef QOL_FIXES
|
||||
painting->rippleTimer += 1.0;
|
||||
#else
|
||||
if (painting->rippleTimer >= 16777216.0) {
|
||||
painting->rippleTimer = 0.0;
|
||||
} else {
|
||||
painitng->rippleTimer += 1.0;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
if (painting->rippleTrigger == RIPPLE_TRIGGER_PROXIMITY) {
|
||||
// if the painting is barely rippling, make it stop rippling
|
||||
|
|
|
@ -79,12 +79,21 @@ void draw_profiler_bar(OSTime clockBase, OSTime clockStart, OSTime clockEnd, s16
|
|||
//! I believe this is supposed to cap rectX1 and rectX2 to 320, but the
|
||||
// code seems to use the wrong variables... it's possible that the variable
|
||||
// names were very similar within a single letter.
|
||||
#ifndef QOL_FIXES
|
||||
if (rectX1 > 319) {
|
||||
clockStart = 319;
|
||||
}
|
||||
if (rectX2 > 319) {
|
||||
clockEnd = 319;
|
||||
}
|
||||
#else
|
||||
if (rectX1 > 320) {
|
||||
rectX1 = 320;
|
||||
}
|
||||
if (rectX2 > 320) {
|
||||
rectX2 = 320;
|
||||
}
|
||||
#endif
|
||||
|
||||
// perform the render if start is less than end. in most cases, it should be.
|
||||
if (rectX1 < rectX2) {
|
||||
|
@ -261,7 +270,11 @@ void draw_profiler_mode_0(void) {
|
|||
// potentially be passed to draw_profiler_bar, because it could be sending
|
||||
// pairs that are beyond the numVblankTimes enforced non-odd limit, due to
|
||||
// using the wrong num value.
|
||||
#ifndef QOL_FIXES
|
||||
for (i = 0; i < profiler->numSoundTimes; i += 2) {
|
||||
#else
|
||||
for (i = 0; i < profiler->vblankTimes; i += 2) {
|
||||
#endif
|
||||
vblank += (profiler->vblankTimes[i + 1] - profiler->vblankTimes[i]);
|
||||
}
|
||||
|
||||
|
|
|
@ -760,8 +760,13 @@ static int obj_is_in_view(struct GraphNodeObject *node, Mat4 matrix) {
|
|||
hScreenEdge *= GFX_DIMENSIONS_ASPECT_RATIO;
|
||||
|
||||
if (geo != NULL && geo->type == GRAPH_NODE_TYPE_CULLING_RADIUS) {
|
||||
#ifndef QOL_FIXES
|
||||
cullingRadius =
|
||||
(f32)((struct GraphNodeCullingRadius *) geo)->cullingRadius; //! Why is there a f32 cast?
|
||||
#else
|
||||
cullingRadius =
|
||||
((struct GraphNodeCullingRadius *) geo)->cullingRadius;
|
||||
#endif
|
||||
} else {
|
||||
cullingRadius = 300;
|
||||
}
|
||||
|
|
|
@ -190,6 +190,9 @@ f32 get_water_level_below_shadow(struct Shadow *s) {
|
|||
}
|
||||
//! @bug Missing return statement. This compiles to return `waterLevel`
|
||||
//! incidentally.
|
||||
#ifdef QOL_FIXES
|
||||
return waterLevel;
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -214,6 +217,11 @@ s8 init_shadow(struct Shadow *s, f32 xPos, f32 yPos, f32 zPos, s16 shadowScale,
|
|||
if (gEnvironmentRegions != 0) {
|
||||
waterLevel = get_water_level_below_shadow(s);
|
||||
}
|
||||
#ifdef QOL_FIXES
|
||||
else {
|
||||
waterLevel = 0;
|
||||
}
|
||||
#endif
|
||||
if (gShadowAboveWaterOrLava) {
|
||||
//! @bug Use of potentially undefined variable `waterLevel`
|
||||
s->floorHeight = waterLevel;
|
||||
|
|
|
@ -139,7 +139,11 @@ f32 calculate_skybox_scaled_x(s8 player, f32 fov) {
|
|||
f32 yaw = sSkyBoxInfo[player].yaw;
|
||||
|
||||
//! double literals are used instead of floats
|
||||
#ifndef QOL_FIXES
|
||||
f32 scaledX = SCREEN_WIDTH * 360.0 * yaw / (fov * 65536.0);
|
||||
#else
|
||||
f32 scaledX = SCREEN_WIDTH * 360.0f * yaw / (fov * 65536.0f);
|
||||
#endif
|
||||
|
||||
if (scaledX > SKYBOX_WIDTH) {
|
||||
scaledX -= (s32) scaledX / SKYBOX_WIDTH * SKYBOX_WIDTH;
|
||||
|
|
|
@ -2952,7 +2952,9 @@ void d_set_matrix(Mat4f *src) {
|
|||
gd_copy_mat4f(src, &((struct ObjNet *) sDynListCurObj)->mat128);
|
||||
//! @bug When setting an `ObjNet` matrix, the source is copied twice
|
||||
//! due to a probable copy-paste line repeat error
|
||||
#ifndef QOL_FIXES
|
||||
gd_copy_mat4f(src, &((struct ObjNet *) sDynListCurObj)->mat128);
|
||||
#endif
|
||||
break;
|
||||
case OBJ_TYPE_JOINTS:
|
||||
gd_copy_mat4f(src, &((struct ObjJoint *) sDynListCurObj)->matE8);
|
||||
|
|
|
@ -692,7 +692,11 @@ void UNUSED gd_create_quat_rot_mat(f32 quat[4], UNUSED s32 unused, Mat4f *mtx) {
|
|||
//! latter portions remain what they were originally. Perhaps this was meant
|
||||
//! to call gd_create_neg_vec_zero_first_mat_row?
|
||||
(*mtx)[0][0] = 1.0f;
|
||||
#ifndef QOL_FIXES
|
||||
gd_shift_mat_up(mtx);
|
||||
#else
|
||||
gd_create_neg_vec_zero_first_mat_row(mtx);
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -492,7 +492,7 @@ ALIGNED8 static u8 gd_texture_sparkle_4[] = {
|
|||
|
||||
//! No reference to this texture. Two DL's uses the same previous texture
|
||||
// instead of using this texture.
|
||||
// Fixed via setting TEXTURE_FIX to 1.
|
||||
// Fixed via setting QOL_FIXES to 1.
|
||||
ALIGNED8 static u8 gd_texture_sparkle_5[] = {
|
||||
#include "textures/intro_raw/sparkle_5.rgba16.inc.c"
|
||||
};
|
||||
|
@ -569,7 +569,7 @@ static Gfx gd_dl_red_sparkle_4[] = {
|
|||
gsSPBranchList(gd_dl_sparkle),
|
||||
};
|
||||
|
||||
#ifndef TEXTURE_FIX
|
||||
#ifndef QOL_FIXES
|
||||
static Gfx gd_dl_red_sparkle_4_dup[] ={
|
||||
gsDPPipeSync(),
|
||||
gsSPDisplayList(gd_dl_sparkle_red_color),
|
||||
|
@ -621,7 +621,7 @@ static Gfx gd_dl_silver_sparkle_4[] = {
|
|||
gsSPBranchList(gd_dl_sparkle),
|
||||
};
|
||||
|
||||
#ifndef TEXTURE_FIX
|
||||
#ifndef QOL_FIXES
|
||||
static Gfx gd_dl_silver_sparkle_4_dup[] = {
|
||||
gsDPPipeSync(),
|
||||
gsSPDisplayList(gd_dl_sparkle_white_color),
|
||||
|
@ -649,7 +649,7 @@ static Gfx *gd_red_sparkle_dl_array[] = {
|
|||
gd_dl_red_sparkle_1,
|
||||
gd_dl_red_sparkle_0,
|
||||
gd_dl_red_sparkle_0,
|
||||
#ifndef TEXTURE_FIX
|
||||
#ifndef QOL_FIXES
|
||||
gd_dl_red_sparkle_4_dup,
|
||||
gd_dl_red_sparkle_4_dup,
|
||||
#else
|
||||
|
@ -669,7 +669,7 @@ static Gfx *gd_silver_sparkle_dl_array[] = {
|
|||
gd_dl_silver_sparkle_1,
|
||||
gd_dl_silver_sparkle_0,
|
||||
gd_dl_silver_sparkle_0,
|
||||
#ifndef TEXTURE_FIX
|
||||
#ifndef QOL_FIXES
|
||||
gd_dl_silver_sparkle_4_dup,
|
||||
gd_dl_silver_sparkle_4_dup,
|
||||
#else
|
||||
|
@ -941,7 +941,11 @@ void gd_printf(const char *format, ...) {
|
|||
break;
|
||||
case 'c':
|
||||
//! @bug formatter 'c' uses `s32` for va_arg instead of `char`
|
||||
#ifndef QOL_FIXES
|
||||
*csr = va_arg(args, s32);
|
||||
#else
|
||||
*csr = va_arg(args, int);
|
||||
#endif
|
||||
csr++;
|
||||
*csr = '\0';
|
||||
break;
|
||||
|
@ -1323,8 +1327,10 @@ void *gdm_gettestdl(s32 id) {
|
|||
fatal_printf("gdm_gettestdl(): DL number %d undefined", id);
|
||||
}
|
||||
//! @bug Code treats `sYoshiSceneView` as group; not called in game though
|
||||
#ifndef QOL_FIXES
|
||||
apply_to_obj_types_in_group(OBJ_TYPE_VIEWS, (applyproc_t) update_view,
|
||||
(struct ObjGroup *) sYoshiSceneView);
|
||||
#endif
|
||||
dobj = d_use_obj("yoshi_scene");
|
||||
gddl = sGdDLArray[((struct ObjView *) dobj)->gdDlNum];
|
||||
sUpdateYoshiScene = TRUE;
|
||||
|
@ -1354,8 +1360,10 @@ void *gdm_gettestdl(s32 id) {
|
|||
fatal_printf("gdm_gettestdl(): DL number %d undefined", id);
|
||||
}
|
||||
//! @bug Code treats `sCarSceneView` as group; not called in game though
|
||||
#ifndef QOL_FIXES
|
||||
apply_to_obj_types_in_group(OBJ_TYPE_VIEWS, (applyproc_t) update_view,
|
||||
(struct ObjGroup *) sCarSceneView);
|
||||
#endif
|
||||
dobj = d_use_obj("car_scene");
|
||||
gddl = sGdDLArray[((struct ObjView *) dobj)->gdDlNum];
|
||||
sUpdateCarScene = TRUE;
|
||||
|
|
|
@ -1176,7 +1176,8 @@ void load_score_menu_from_submenu(s16 prevMenuButtonID, struct Object *sourceBut
|
|||
}
|
||||
// If the previous button is in default state
|
||||
if (sMainMenuButtons[prevMenuButtonID]->oMenuButtonState == MENU_BUTTON_STATE_DEFAULT) {
|
||||
// Hide buttons of corresponding button menu groups
|
||||
// Hide buttons of corresponding button menu
|
||||
#ifndef QOL_FIXES
|
||||
if (prevMenuButtonID == MENU_BUTTON_SCORE) //! Not possible, this is checking if the score menu
|
||||
//! was opened from the score menu!
|
||||
{
|
||||
|
@ -1184,6 +1185,7 @@ void load_score_menu_from_submenu(s16 prevMenuButtonID, struct Object *sourceBut
|
|||
mark_obj_for_deletion(sMainMenuButtons[buttonID]);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
if (prevMenuButtonID == MENU_BUTTON_COPY) {
|
||||
for (buttonID = MENU_BUTTON_COPY_MIN; buttonID < MENU_BUTTON_COPY_MAX; buttonID++) {
|
||||
mark_obj_for_deletion(sMainMenuButtons[buttonID]);
|
||||
|
@ -1223,6 +1225,7 @@ void load_copy_menu_from_submenu(s16 prevMenuButtonID, struct Object *sourceButt
|
|||
mark_obj_for_deletion(sMainMenuButtons[buttonID]);
|
||||
}
|
||||
}
|
||||
#ifndef QOL_FIXES
|
||||
if (prevMenuButtonID == MENU_BUTTON_COPY) //! Not possible, this is checking if the copy menu
|
||||
//! was opened from the copy menu!
|
||||
{
|
||||
|
@ -1230,6 +1233,7 @@ void load_copy_menu_from_submenu(s16 prevMenuButtonID, struct Object *sourceButt
|
|||
mark_obj_for_deletion(sMainMenuButtons[buttonID]);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
if (prevMenuButtonID == MENU_BUTTON_ERASE) {
|
||||
for (buttonID = MENU_BUTTON_ERASE_MIN; buttonID < MENU_BUTTON_ERASE_MAX; buttonID++) {
|
||||
mark_obj_for_deletion(sMainMenuButtons[buttonID]);
|
||||
|
@ -1269,6 +1273,7 @@ void load_erase_menu_from_submenu(s16 prevMenuButtonID, struct Object *sourceBut
|
|||
mark_obj_for_deletion(sMainMenuButtons[buttonID]);
|
||||
}
|
||||
}
|
||||
#ifndef QOL_FIXES
|
||||
if (prevMenuButtonID == MENU_BUTTON_ERASE) //! Not possible, this is checking if the erase menu
|
||||
//! was opened from the erase menu!
|
||||
{
|
||||
|
@ -1276,6 +1281,7 @@ void load_erase_menu_from_submenu(s16 prevMenuButtonID, struct Object *sourceBut
|
|||
mark_obj_for_deletion(sMainMenuButtons[buttonID]);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
// Play zoom in sound, select erase menu and render it's buttons
|
||||
sSelectedButtonID = MENU_BUTTON_ERASE;
|
||||
play_sound(SOUND_MENU_CAMERA_ZOOM_IN, gDefaultSoundArgs);
|
||||
|
|
|
@ -27,7 +27,7 @@ static char gLevelSelect_StageNamesText[64][16] = {
|
|||
|
||||
static u16 gDemoCountdown = 0;
|
||||
#ifndef VERSION_JP
|
||||
static s16 D_U_801A7C34 = 1;
|
||||
static s16 playMarioGreeting = 1;
|
||||
static s16 gameOverNotPlayed = 1;
|
||||
#endif
|
||||
|
||||
|
@ -61,6 +61,7 @@ int run_press_start_demo_timer(s32 timer) {
|
|||
timer = (s8)((struct DemoInput *) gDemo.targetAnim)->timer;
|
||||
gCurrSaveFileNum = 1;
|
||||
gCurrActNum = 1;
|
||||
playMarioGreeting = 1;
|
||||
}
|
||||
} else { // activity was detected, so reset the demo countdown.
|
||||
gDemoCountdown = 0;
|
||||
|
@ -162,9 +163,13 @@ int intro_default(void) {
|
|||
s32 sp1C = 0;
|
||||
|
||||
#ifndef VERSION_JP
|
||||
if (D_U_801A7C34 == 1) {
|
||||
play_sound(SOUND_MARIO_HELLO, gDefaultSoundArgs);
|
||||
D_U_801A7C34 = 0;
|
||||
if (playMarioGreeting == 1) {
|
||||
if (gGlobalTimer < 0x81) {
|
||||
play_sound(SOUND_MARIO_HELLO, gDefaultSoundArgs);
|
||||
} else {
|
||||
play_sound(SOUND_MARIO_PRESS_START_TO_PLAY, gDefaultSoundArgs);
|
||||
}
|
||||
playMarioGreeting = 0;
|
||||
}
|
||||
#endif
|
||||
print_intro_text();
|
||||
|
@ -173,7 +178,7 @@ int intro_default(void) {
|
|||
play_sound(SOUND_MENU_STAR_SOUND, gDefaultSoundArgs);
|
||||
sp1C = 100 + gDebugLevelSelect;
|
||||
#ifndef VERSION_JP
|
||||
D_U_801A7C34 = 1;
|
||||
playMarioGreeting = 1;
|
||||
#endif
|
||||
}
|
||||
return run_press_start_demo_timer(sp1C);
|
||||
|
|
|
@ -141,9 +141,11 @@ void bhv_act_selector_init(void) {
|
|||
|
||||
//! Useless, since sInitSelectedActNum has already been set in this
|
||||
//! scenario by the code that shows the next uncollected star.
|
||||
#ifndef QOL_FIXES
|
||||
if (sObtainedStars == 0) {
|
||||
sInitSelectedActNum = 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
// Render star selector objects
|
||||
for (i = 0; i < sVisibleStars; i++) {
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
# About n64-fast32-engine
|
||||
# About n64-fast3d-engine
|
||||
|
||||
sm64pc supports OpenGL through [n64-fast32-engine](https://github.com/Emill/n64-fast3d-engine/), by [Emill](https://github.com/Emill/).
|
||||
sm64pc supports OpenGL through [n64-fast3d-engine](https://github.com/Emill/n64-fast3d-engine/), by [Emill](https://github.com/Emill/).
|
||||
|
||||
We recommend that you visit the repo if you wish for a better understanding on how this port was possible.
|
||||
|
||||
n64-fast32-engine is licensed under
|
||||
n64-fast3d-engine is licensed under
|
||||
```
|
||||
Copyright (c) 2020, Emill
|
||||
|
||||
|
@ -25,4 +25,4 @@ 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.
|
||||
```
|
||||
```
|
|
@ -1,4 +1,5 @@
|
|||
#include "audio_api.h"
|
||||
#include "macros.h"
|
||||
|
||||
static bool audio_null_init(void) {
|
||||
return true;
|
||||
|
@ -12,7 +13,7 @@ static int audio_null_get_desired_buffered(void) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void audio_null_play(const uint8_t *buf, size_t len) {
|
||||
static void audio_null_play(UNUSED const uint8_t *buf, UNUSED size_t len) {
|
||||
}
|
||||
|
||||
static void audio_null_shutdown(void) {
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <ultra64.h>
|
||||
|
||||
#include "controller_api.h"
|
||||
|
@ -9,14 +10,20 @@ static void tas_init(void) {
|
|||
fp = fopen("cont.m64", "rb");
|
||||
if (fp != NULL) {
|
||||
uint8_t buf[0x400];
|
||||
fread(buf, 1, sizeof(buf), fp);
|
||||
if (fread(buf, 1, sizeof(buf), fp) != 1) {
|
||||
printf("I/O error occurred.");
|
||||
exit(1);
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
static void tas_read(OSContPad *pad) {
|
||||
if (fp != NULL) {
|
||||
uint8_t bytes[4] = {0};
|
||||
fread(bytes, 1, 4, fp);
|
||||
if (fread(bytes, 1, 4, fp) != 1) {
|
||||
printf("I/O error occurred.");
|
||||
exit(1);
|
||||
};
|
||||
pad->button = (bytes[0] << 8) | bytes[1];
|
||||
pad->stick_x = bytes[2];
|
||||
pad->stick_y = bytes[3];
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
#include <stdbool.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <time.h>
|
||||
|
@ -222,13 +223,15 @@ static void set_state(void) {
|
|||
|
||||
void set_logo(void) {
|
||||
if (lastCourseNum)
|
||||
snprintf(largeImageKey, sizeof(largeImageKey), "%d", lastCourseNum);
|
||||
if (snprintf(largeImageKey, sizeof(largeImageKey), "%d", lastCourseNum) < 0)
|
||||
abort();
|
||||
else
|
||||
strcpy(largeImageKey, "0");
|
||||
|
||||
/*
|
||||
if (lastActNum)
|
||||
snprintf(smallImageKey, sizeof(largeImageKey), "%d", lastActNum);
|
||||
if (snprintf(smallImageKey, sizeof(largeImageKey), "%d", lastActNum) < 0)
|
||||
abort();
|
||||
else
|
||||
smallImageKey[0] = '\0';
|
||||
*/
|
||||
|
|
|
@ -293,7 +293,7 @@ void gfx_direct3d_common_build_shader(char buf[4096], size_t& len, size_t& num_f
|
|||
if (cc_features.opt_alpha) {
|
||||
append_line(buf, &len, " texel = float4(lerp(texel.rgb, input.fog.rgb, input.fog.a), texel.a);");
|
||||
} else {
|
||||
append_line(buf, &len, " texel = lerp(texel, input.fog.rgb, input.fog.a);");
|
||||
append_line(buf, &len, " texel.a *= round(saturate(random(float3(floor(coords), noise_frame)) + texel.a - 0.5));");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -378,7 +378,7 @@ static struct ShaderProgram *gfx_opengl_create_and_load_new_shader(uint32_t shad
|
|||
}
|
||||
|
||||
if (opt_alpha && opt_noise)
|
||||
append_line(fs_buf, &fs_len, "texel.a *= floor(random(floor(vec3(gl_FragCoord.xy, frame_count))) + 0.5);");
|
||||
append_line(fs_buf, &fs_len, "texel.a *= floor(clamp(random(floor(vec3(gl_FragCoord.xy, frame_count))) + texel.a, 0.0, 1.0));");
|
||||
|
||||
if (opt_alpha) {
|
||||
append_line(fs_buf, &fs_len, "gl_FragColor = texel;");
|
||||
|
@ -390,11 +390,13 @@ static struct ShaderProgram *gfx_opengl_create_and_load_new_shader(uint32_t shad
|
|||
vs_buf[vs_len] = '\0';
|
||||
fs_buf[fs_len] = '\0';
|
||||
|
||||
/*puts("Vertex shader:");
|
||||
#ifdef DEBUG
|
||||
puts("Vertex shader:");
|
||||
puts(vs_buf);
|
||||
puts("Fragment shader:");
|
||||
puts(fs_buf);
|
||||
puts("End");*/
|
||||
puts("End");
|
||||
#endif
|
||||
|
||||
const GLchar *sources[2] = { vs_buf, fs_buf };
|
||||
const GLint lengths[2] = { vs_len, fs_len };
|
||||
|
@ -522,11 +524,11 @@ static GLuint gfx_opengl_new_texture(void) {
|
|||
}
|
||||
|
||||
static void gfx_opengl_select_texture(int tile, GLuint texture_id) {
|
||||
opengl_tex[tile] = tex_cache + texture_id;
|
||||
opengl_curtex = tile;
|
||||
glActiveTexture(GL_TEXTURE0 + tile);
|
||||
glBindTexture(GL_TEXTURE_2D, opengl_tex[tile]->gltex);
|
||||
gfx_opengl_set_texture_uniforms(opengl_prg, tile);
|
||||
opengl_tex[tile] = tex_cache + texture_id;
|
||||
opengl_curtex = tile;
|
||||
glActiveTexture(GL_TEXTURE0 + tile);
|
||||
glBindTexture(GL_TEXTURE_2D, opengl_tex[tile]->gltex);
|
||||
gfx_opengl_set_texture_uniforms(opengl_prg, tile);
|
||||
}
|
||||
|
||||
static void gfx_opengl_upload_texture(uint8_t *rgba32_buf, int width, int height) {
|
||||
|
@ -595,7 +597,9 @@ static void gfx_opengl_set_use_alpha(bool use_alpha) {
|
|||
}
|
||||
|
||||
static void gfx_opengl_draw_triangles(float buf_vbo[], size_t buf_vbo_len, size_t buf_vbo_num_tris) {
|
||||
//printf("flushing %d tris\n", buf_vbo_num_tris);
|
||||
#ifdef DEBUG
|
||||
printf("flushing %d tris\n", buf_vbo_num_tris);
|
||||
#endif
|
||||
glBufferData(GL_ARRAY_BUFFER, sizeof(float) * buf_vbo_len, buf_vbo, GL_STREAM_DRAW);
|
||||
glDrawArrays(GL_TRIANGLES, 0, 3 * buf_vbo_num_tris);
|
||||
}
|
||||
|
|
|
@ -28,6 +28,8 @@
|
|||
#include "../configfile.h"
|
||||
#include "../fs/fs.h"
|
||||
|
||||
#include "macros.h"
|
||||
|
||||
#define SUPPORT_CHECK(x) assert(x)
|
||||
|
||||
// SCALE_M_N: upscale/downscale M-bit integer to N-bit
|
||||
|
@ -201,15 +203,19 @@ static unsigned long get_time(void) {
|
|||
|
||||
static void gfx_flush(void) {
|
||||
if (buf_vbo_len > 0) {
|
||||
int num = buf_vbo_num_tris;
|
||||
UNUSED int num = buf_vbo_num_tris;
|
||||
#ifdef DEBUG
|
||||
unsigned long t0 = get_time();
|
||||
#endif
|
||||
gfx_rapi->draw_triangles(buf_vbo, buf_vbo_len, buf_vbo_num_tris);
|
||||
buf_vbo_len = 0;
|
||||
buf_vbo_num_tris = 0;
|
||||
#ifdef DEBUG
|
||||
unsigned long t1 = get_time();
|
||||
/*if (t1 - t0 > 1000) {
|
||||
if (t1 - t0 > 1000) {
|
||||
printf("f: %d %d\n", num, (int)(t1 - t0));
|
||||
}*/
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -311,7 +317,9 @@ static bool gfx_texture_cache_lookup(int tile, struct TextureHashmapNode **n, co
|
|||
// Pool is full. We just invalidate everything and start over.
|
||||
gfx_texture_cache.pool_pos = 0;
|
||||
node = &gfx_texture_cache.hashmap[hash];
|
||||
// puts("Clearing texture cache");
|
||||
#ifdef DEBUG
|
||||
puts("Clearing texture cache");
|
||||
#endif
|
||||
}
|
||||
*node = &gfx_texture_cache.pool[gfx_texture_cache.pool_pos++];
|
||||
if ((*node)->texture_addr == NULL) {
|
||||
|
@ -619,7 +627,9 @@ static void import_texture(int tile) {
|
|||
load_texture(texname);
|
||||
#else
|
||||
// the texture data is actual texture data
|
||||
#ifdef DEBUG
|
||||
int t0 = get_time();
|
||||
#endif
|
||||
if (fmt == G_IM_FMT_RGBA) {
|
||||
if (siz == G_IM_SIZ_32b) {
|
||||
import_texture_rgba32(tile);
|
||||
|
@ -658,8 +668,10 @@ static void import_texture(int tile) {
|
|||
} else {
|
||||
sys_fatal("unsupported texture format: %u", fmt);
|
||||
}
|
||||
#ifdef DEBUG
|
||||
int t1 = get_time();
|
||||
//printf("Time diff: %d\n", t1 - t0);
|
||||
printf("Time diff: %d\n", t1 - t0);
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -1062,11 +1074,6 @@ static void gfx_sp_tri1(uint8_t vtx1_idx, uint8_t vtx2_idx, uint8_t vtx3_idx) {
|
|||
}
|
||||
}
|
||||
}
|
||||
/*struct RGBA *color = &v_arr[i]->color;
|
||||
buf_vbo[buf_vbo_len++] = color->r / 255.0f;
|
||||
buf_vbo[buf_vbo_len++] = color->g / 255.0f;
|
||||
buf_vbo[buf_vbo_len++] = color->b / 255.0f;
|
||||
buf_vbo[buf_vbo_len++] = color->a / 255.0f;*/
|
||||
}
|
||||
if (++buf_vbo_num_tris == MAX_BUFFERED) {
|
||||
gfx_flush();
|
||||
|
@ -1130,14 +1137,14 @@ static void gfx_sp_movemem(uint8_t index, uint8_t offset, const void* data) {
|
|||
}
|
||||
}
|
||||
|
||||
static void gfx_sp_moveword(uint8_t index, uint16_t offset, uint32_t data) {
|
||||
static void gfx_sp_moveword(uint8_t index, UNUSED uint16_t offset, uint32_t data) {
|
||||
switch (index) {
|
||||
case G_MW_NUMLIGHT:
|
||||
#ifdef F3DEX_GBI_2
|
||||
rsp.current_num_lights = data / 24 + 1; // add ambient light
|
||||
#else
|
||||
// Ambient light is included
|
||||
// The 31th bit is a flag that lights should be recalculated
|
||||
// The 31st bit is a flag that lights should be recalculated
|
||||
rsp.current_num_lights = (data - 0x80000000U) / 32;
|
||||
#endif
|
||||
rsp.lights_changed = 1;
|
||||
|
@ -1149,12 +1156,12 @@ static void gfx_sp_moveword(uint8_t index, uint16_t offset, uint32_t data) {
|
|||
}
|
||||
}
|
||||
|
||||
static void gfx_sp_texture(uint16_t sc, uint16_t tc, uint8_t level, uint8_t tile, uint8_t on) {
|
||||
static void gfx_sp_texture(uint16_t sc, uint16_t tc, UNUSED uint8_t level, UNUSED uint8_t tile, UNUSED uint8_t on) {
|
||||
rsp.texture_scaling_factor.s = sc;
|
||||
rsp.texture_scaling_factor.t = tc;
|
||||
}
|
||||
|
||||
static void gfx_dp_set_scissor(uint32_t mode, uint32_t ulx, uint32_t uly, uint32_t lrx, uint32_t lry) {
|
||||
static void gfx_dp_set_scissor(UNUSED uint32_t mode, uint32_t ulx, uint32_t uly, uint32_t lrx, uint32_t lry) {
|
||||
float x = ulx / 4.0f * RATIO_X;
|
||||
float y = (SCREEN_HEIGHT - lry / 4.0f) * RATIO_Y;
|
||||
float width = (lrx - ulx) / 4.0f * RATIO_X;
|
||||
|
@ -1168,12 +1175,12 @@ static void gfx_dp_set_scissor(uint32_t mode, uint32_t ulx, uint32_t uly, uint32
|
|||
rdp.viewport_or_scissor_changed = true;
|
||||
}
|
||||
|
||||
static void gfx_dp_set_texture_image(uint32_t format, uint32_t size, uint32_t width, const void* addr) {
|
||||
static void gfx_dp_set_texture_image(UNUSED uint32_t format, uint32_t size, UNUSED uint32_t width, const void* addr) {
|
||||
rdp.texture_to_load.addr = addr;
|
||||
rdp.texture_to_load.siz = size;
|
||||
}
|
||||
|
||||
static void gfx_dp_set_tile(uint8_t fmt, uint32_t siz, uint32_t line, uint32_t tmem, uint8_t tile, uint32_t palette, uint32_t cmt, uint32_t maskt, uint32_t shiftt, uint32_t cms, uint32_t masks, uint32_t shifts) {
|
||||
static void gfx_dp_set_tile(uint8_t fmt, uint32_t siz, uint32_t line, uint32_t tmem, uint8_t tile, uint32_t palette, uint32_t cmt, UNUSED uint32_t maskt, UNUSED uint32_t shiftt, uint32_t cms, UNUSED uint32_t masks, UNUSED uint32_t shifts) {
|
||||
|
||||
if (tile == G_TX_RENDERTILE) {
|
||||
SUPPORT_CHECK(palette == 0); // palette should set upper 4 bits of color index in 4b mode
|
||||
|
@ -1202,13 +1209,13 @@ static void gfx_dp_set_tile_size(uint8_t tile, uint16_t uls, uint16_t ult, uint1
|
|||
}
|
||||
}
|
||||
|
||||
static void gfx_dp_load_tlut(uint8_t tile, uint32_t high_index) {
|
||||
static void gfx_dp_load_tlut(uint8_t tile, UNUSED uint32_t high_index) {
|
||||
SUPPORT_CHECK(tile == G_TX_LOADTILE);
|
||||
SUPPORT_CHECK(rdp.texture_to_load.siz == G_IM_SIZ_16b);
|
||||
rdp.palette = rdp.texture_to_load.addr;
|
||||
}
|
||||
|
||||
static void gfx_dp_load_block(uint8_t tile, uint32_t uls, uint32_t ult, uint32_t lrs, uint32_t dxt) {
|
||||
static void gfx_dp_load_block(uint8_t tile, uint32_t uls, uint32_t ult, uint32_t lrs, UNUSED uint32_t dxt) {
|
||||
if (tile == 1) return;
|
||||
SUPPORT_CHECK(tile == G_TX_LOADTILE);
|
||||
SUPPORT_CHECK(uls == 0);
|
||||
|
@ -1404,7 +1411,7 @@ static void gfx_draw_rectangle(int32_t ulx, int32_t uly, int32_t lrx, int32_t lr
|
|||
}
|
||||
}
|
||||
|
||||
static void gfx_dp_texture_rectangle(int32_t ulx, int32_t uly, int32_t lrx, int32_t lry, uint8_t tile, int16_t uls, int16_t ult, int16_t dsdx, int16_t dtdy, bool flip) {
|
||||
static void gfx_dp_texture_rectangle(int32_t ulx, int32_t uly, int32_t lrx, int32_t lry, UNUSED uint8_t tile, int16_t uls, int16_t ult, int16_t dsdx, int16_t dtdy, bool flip) {
|
||||
uint32_t saved_combine_mode = rdp.combine_mode;
|
||||
if ((rdp.other_mode_h & (3U << G_MDSFT_CYCLETYPE)) == G_CYC_COPY) {
|
||||
// Per RDP Command Summary Set Tile's shift s and this dsdx should be set to 4 texels
|
||||
|
@ -1484,7 +1491,7 @@ static void gfx_dp_set_z_image(void *z_buf_address) {
|
|||
rdp.z_buf_address = z_buf_address;
|
||||
}
|
||||
|
||||
static void gfx_dp_set_color_image(uint32_t format, uint32_t size, uint32_t width, void* address) {
|
||||
static void gfx_dp_set_color_image(UNUSED uint32_t format, UNUSED uint32_t size, UNUSED uint32_t width, void* address) {
|
||||
rdp.color_image_address = address;
|
||||
}
|
||||
|
||||
|
@ -1504,7 +1511,7 @@ static inline void *seg_addr(uintptr_t w1) {
|
|||
#define C1(pos, width) ((cmd->words.w1 >> (pos)) & ((1U << width) - 1))
|
||||
|
||||
static void gfx_run_dl(Gfx* cmd) {
|
||||
int dummy = 0;
|
||||
UNUSED int dummy = 0;
|
||||
for (;;) {
|
||||
uint32_t opcode = cmd->words.w0 >> 24;
|
||||
|
||||
|
@ -1783,7 +1790,9 @@ void gfx_start_frame(void) {
|
|||
void gfx_run(Gfx *commands) {
|
||||
gfx_sp_reset();
|
||||
|
||||
//puts("New frame");
|
||||
#ifdef DEBUG
|
||||
puts("New frame");
|
||||
#endif
|
||||
|
||||
if (!gfx_wapi->start_frame()) {
|
||||
dropped_frame = true;
|
||||
|
@ -1791,12 +1800,16 @@ void gfx_run(Gfx *commands) {
|
|||
}
|
||||
dropped_frame = false;
|
||||
|
||||
#ifdef DEBUG
|
||||
double t0 = gfx_wapi->get_time();
|
||||
#endif
|
||||
gfx_rapi->start_frame();
|
||||
gfx_run_dl(commands);
|
||||
gfx_flush();
|
||||
#ifdef DEBUG
|
||||
double t1 = gfx_wapi->get_time();
|
||||
//printf("Process %f %f\n", t1, t1 - t0);
|
||||
printf("Process %f %f\n", t1, t1 - t0);
|
||||
#endif
|
||||
gfx_rapi->end_frame();
|
||||
gfx_wapi->swap_buffers_begin();
|
||||
}
|
||||
|
|
|
@ -39,6 +39,8 @@
|
|||
#include "pc/discord/discordrpc.h"
|
||||
#endif
|
||||
|
||||
#include "macros.h"
|
||||
|
||||
OSMesg D_80339BEC;
|
||||
OSMesgQueue gSIEventMesgQueue;
|
||||
|
||||
|
@ -61,10 +63,10 @@ extern void thread5_game_loop(void *arg);
|
|||
extern void create_next_audio_buffer(s16 *samples, u32 num_samples);
|
||||
void game_loop_one_iteration(void);
|
||||
|
||||
void dispatch_audio_sptask(struct SPTask *spTask) {
|
||||
void dispatch_audio_sptask(UNUSED struct SPTask *spTask) {
|
||||
}
|
||||
|
||||
void set_vblank_handler(s32 index, struct VblankHandler *handler, OSMesgQueue *queue, OSMesg *msg) {
|
||||
void set_vblank_handler(UNUSED s32 index, UNUSED struct VblankHandler *handler, UNUSED OSMesgQueue *queue, UNUSED OSMesg *msg) {
|
||||
}
|
||||
|
||||
static bool inited = false;
|
||||
|
@ -96,16 +98,22 @@ void produce_one_frame(void) {
|
|||
|
||||
int samples_left = audio_api->buffered();
|
||||
u32 num_audio_samples = samples_left < audio_api->get_desired_buffered() ? SAMPLES_HIGH : SAMPLES_LOW;
|
||||
//printf("Audio samples: %d %u\n", samples_left, num_audio_samples);
|
||||
#ifdef DEBUG
|
||||
printf("Audio samples: %d %u\n", samples_left, num_audio_samples);
|
||||
#endif
|
||||
s16 audio_buffer[SAMPLES_HIGH * 2 * 2];
|
||||
for (int i = 0; i < 2; i++) {
|
||||
/*if (audio_cnt-- == 0) {
|
||||
#ifdef DEBUG
|
||||
if (audio_cnt-- == 0) {
|
||||
audio_cnt = 2;
|
||||
}
|
||||
u32 num_audio_samples = audio_cnt < 2 ? 528 : 544;*/
|
||||
u32 num_audio_samples = audio_cnt < 2 ? 528 : 544;
|
||||
#endif
|
||||
create_next_audio_buffer(audio_buffer + i * (num_audio_samples * 2), num_audio_samples);
|
||||
}
|
||||
//printf("Audio samples before submitting: %d\n", audio_api->buffered());
|
||||
#ifdef DEBUG
|
||||
printf("Audio samples before submitting: %d\n", audio_api->buffered());
|
||||
#endif
|
||||
|
||||
audio_api->play((u8 *)audio_buffer, 2 * num_audio_samples * 4);
|
||||
|
||||
|
|
|
@ -1251,9 +1251,19 @@ die Temperatur!"))
|
|||
DEFINE_DIALOG(DIALOG_098, 1, 1, 95, 200, _("\
|
||||
Komm nur näher, hehehe!"))
|
||||
|
||||
#ifndef QOL_FIXES
|
||||
DEFINE_DIALOG(DIALOG_099, 1, 3, 95, 200, _("\
|
||||
"))
|
||||
|
||||
#else
|
||||
DEFINE_DIALOG(DIALOG_099, 1, 3, 95, 200, _("\
|
||||
Eh he he...\n\
|
||||
Du gehörst mir, hee hee!\n\
|
||||
Ich gehe einfach durch\n\
|
||||
diese Wand. Kannst du\n\
|
||||
das auch? Heh, heh, heh!"))
|
||||
|
||||
#endif
|
||||
DEFINE_DIALOG(DIALOG_100, 1, 2, 95, 200, _("\
|
||||
Jippiiiiieee, ich hab' sie!\n\
|
||||
Jetzt gehört sie mir!!!"))
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
CC := gcc
|
||||
CXX := g++
|
||||
CFLAGS := -I../include -I. -Wall -Wextra -Wno-unused-parameter -pedantic -std=c99 -O2 -s
|
||||
CFLAGS := -I../include -I. -Wall -Wextra -pedantic -std=c99 -O2 -s
|
||||
LDFLAGS := -lm
|
||||
PROGRAMS := n64graphics n64graphics_ci mio0 n64cksum textconv patch_libultra_math aifc_decode aiff_extract_codebook vadpcm_enc tabledesign extract_data_for_mio skyconv
|
||||
|
||||
|
@ -25,11 +25,11 @@ aifc_decode_SOURCES := aifc_decode.c
|
|||
aiff_extract_codebook_SOURCES := aiff_extract_codebook.c
|
||||
|
||||
tabledesign_SOURCES := sdk-tools/tabledesign/codebook.c sdk-tools/tabledesign/estimate.c sdk-tools/tabledesign/print.c sdk-tools/tabledesign/tabledesign.c
|
||||
tabledesign_CFLAGS := -Iaudiofile -Wno-uninitialized
|
||||
tabledesign_CFLAGS := -Iaudiofile
|
||||
tabledesign_LDFLAGS := -Laudiofile -laudiofile -lstdc++ -lm
|
||||
|
||||
vadpcm_enc_SOURCES := sdk-tools/adpcm/vadpcm_enc.c sdk-tools/adpcm/vpredictor.c sdk-tools/adpcm/quant.c sdk-tools/adpcm/util.c sdk-tools/adpcm/vencode.c
|
||||
vadpcm_enc_CFLAGS := -Wno-unused-result -Wno-uninitialized -Wno-sign-compare -Wno-absolute-value
|
||||
vadpcm_enc_CFLAGS :=
|
||||
|
||||
extract_data_for_mio_SOURCES := extract_data_for_mio.c
|
||||
|
||||
|
|
|
@ -20,6 +20,6 @@ fi
|
|||
# 'git diff' is stupid and doesn't show new untracked files, so we must add them first.
|
||||
git add .
|
||||
# Generate the patch.
|
||||
git diff -p --staged > "$1"
|
||||
git diff --ignore-space-at-eol -b -w -p --text --staged > "$1"
|
||||
# Undo the 'git add'.
|
||||
git reset
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue