diff --git a/Makefile b/Makefile index b0149d18..3ca55deb 100644 --- a/Makefile +++ b/Makefile @@ -25,6 +25,8 @@ CC_CHECK_COMP ?= gcc OBJDUMP_BUILD ?= 0 # Number of threads to compress with N_THREADS ?= $(shell nproc) +# If COMPILER is GCC, compile with GCC instead of IDO. +COMPILER ?= ido # Whether to colorize build messages COLOR ?= 1 # Whether to hide commands or not @@ -63,6 +65,57 @@ LD_SCRIPT := linker_scripts/$(VERSION)/$(TARGET).ld #### Setup #### +# If gcc is used, define the NON_MATCHING flag respectively so the files that +# are safe to be used can avoid using GLOBAL_ASM which doesn't work with gcc. +ifeq ($(COMPILER),gcc) + $(warning WARNING: GCC support is experimental. Use at your own risk.) + CFLAGS += -DCOMPILER_GCC + NON_MATCHING := 1 +endif + +# Detect compiler and set variables appropriately. +ifeq ($(COMPILER),gcc) + CC := $(MIPS_BINUTILS_PREFIX)gcc +else +ifeq ($(COMPILER),ido) + CC := tools/ido_recomp/$(DETECTED_OS)/7.1/cc + CC_OLD := tools/ido_recomp/$(DETECTED_OS)/5.3/cc +else +$(error Unsupported compiler. Please use either ido or gcc as the COMPILER variable.) +endif +endif + +# ditch g3, we aren't using that in GCC +ifeq ($(COMPILER),gcc) + OPTFLAGS := -Os +else + OPTFLAGS := -O2 -g3 +endif + +ifeq ($(COMPILER),gcc) + CFLAGS += -G 0 -ffast-math -fno-unsafe-math-optimizations -march=vr4300 -mfix4300 -mabi=32 -mno-abicalls -mdivide-breaks -fno-zero-initialized-in-bss -fno-toplevel-reorder -ffreestanding -fno-common -fno-merge-constants -mno-explicit-relocs -mno-split-addresses $(CHECK_WARNINGS) -funsigned-char + MIPS_VERSION := -mips3 +else + # we support Microsoft extensions such as anonymous structs, which the compiler does support but warns for their usage. Surpress the warnings with -woff. + CFLAGS += -G 0 -non_shared -fullwarn -verbose -Xcpluscomm $(IINC) -nostdinc -Wab,-r4300_mul -woff 649,838,712,516 + MIPS_VERSION := -mips2 +endif + +ifeq ($(COMPILER),ido) + # Have CC_CHECK pretend to be a MIPS compiler + MIPS_BUILTIN_DEFS := -D_MIPS_ISA_MIPS2=2 -D_MIPS_ISA=_MIPS_ISA_MIPS2 -D_ABIO32=1 -D_MIPS_SIM=_ABIO32 -D_MIPS_SZINT=32 -D_MIPS_SZLONG=32 -D_MIPS_SZPTR=32 + CC_CHECK = gcc -fno-builtin -fsyntax-only -funsigned-char -std=gnu90 -D_LANGUAGE_C -DNON_MATCHING $(MIPS_BUILTIN_DEFS) $(IINC) $(CHECK_WARNINGS) + ifeq ($(shell getconf LONG_BIT), 32) + # Work around memory allocation bug in QEMU + export QEMU_GUEST_BASE := 1 + else + # Ensure that gcc (warning check) treats the code as 32-bit + CC_CHECK += -m32 + endif +else + CC_CHECK = @: +endif + BUILD_DEFINES ?= ifeq ($(VERSION),us) @@ -73,7 +126,7 @@ endif ifeq ($(NON_MATCHING),1) BUILD_DEFINES += -DNON_MATCHING -DAVOID_UB - COMPARE := 0 + CPPFLAGS += -DNON_MATCHING -DAVOID_UB endif MAKE = make @@ -190,10 +243,6 @@ else CC_CHECK := @: endif - -CFLAGS += -G 0 -non_shared -Xcpluscomm -nostdinc -Wab,-r4300_mul - -WARNINGS := -fullwarn -verbose -woff 624,649,838,712,516,513,596,564,594,709 ASFLAGS := -march=vr4300 -32 -G0 COMMON_DEFINES := -D_MIPS_SZLONG=32 GBI_DEFINES := -DF3DEX_GBI @@ -202,8 +251,6 @@ AS_DEFINES := -DMIPSEB -D_LANGUAGE_ASSEMBLY -D_ULTRA64 C_DEFINES := -DLANGUAGE_C -D_LANGUAGE_C -DBUILD_VERSION=VERSION_H ${RELEASE_DEFINES} ENDIAN := -EB -OPTFLAGS := -O2 -g3 -MIPS_VERSION := -mips2 ICONV_FLAGS := --from-code=UTF-8 --to-code=EUC-JP # Use relocations and abi fpr names in the dump @@ -247,6 +294,9 @@ DEP_FILES := $(O_FILES:.o=.d) \ # create build directories $(shell mkdir -p $(BUILD_DIR)/linker_scripts/$(VERSION) $(BUILD_DIR)/linker_scripts/$(VERSION)/auto $(foreach dir,$(SRC_DIRS) $(ASM_DIRS) $(BIN_DIRS),$(BUILD_DIR)/$(dir))) +ifeq ($(COMPILER),ido) +CFLAGS += -G 0 -non_shared -Xcpluscomm -nostdinc -Wab,-r4300_mul +WARNINGS := -fullwarn -verbose -woff 624,649,838,712,516,513,596,564,594,709 # directory flags build/src/libultra/gu/%.o: OPTFLAGS := -O3 -g0 @@ -281,8 +331,41 @@ build/src/libultra/gu/mtxutil.o: CC := $(IDO) build/src/libultra/gu/cosf.o: CC := $(IDO) build/src/libultra/libc/xprintf.o: CC := $(IDO) build/src/libultra/libc/xldtob.o: CC := $(IDO) +else +# directory flags +build/src/libultra/gu/%.o: OPTFLAGS := -Os +build/src/libultra/io/%.o: OPTFLAGS := -Os +build/src/libultra/os/%.o: OPTFLAGS := -Os +build/src/libultra/rmon/%.o: OPTFLAGS := -Os +build/src/libultra/debug/%.o: OPTFLAGS := -Os +build/src/libultra/host/%.o: OPTFLAGS := -Os +build/src/audio/audio_load.o: OPTFLAGS := -Os # Crashes with -O2 and -O3 +build/src/audio/%.o: OPTFLAGS := -O2 -g -#build/src/%.o: CC := $(ASM_PROC) $(ASM_PROC_FLAGS) $(IDO) -- $(AS) $(ASFLAGS) -- +# per-file flags +build/src/libc_sprintf.o: OPTFLAGS := -Os +build/src/libc_math64.o: OPTFLAGS := -Os + +build/src/libultra/libc/ldiv.o: OPTFLAGS := -Os +build/src/libultra/libc/string.o: OPTFLAGS := -Os +build/src/libultra/libc/xlitob.o: OPTFLAGS := -Os +build/src/libultra/libc/xldtob.o: OPTFLAGS := -Os +build/src/libultra/libc/xprintf.o: OPTFLAGS := -Os +build/src/libultra/libc/ll.o: OPTFLAGS := -Os +build/src/libultra/libc/ll.o: MIPS_VERSION := -mips3 + +# cc & asm-processor +build/src/libultra/gu/sqrtf.o: OPTFLAGS := -Os +build/src/libultra/gu/sinf.o: OPTFLAGS := -Os +build/src/libultra/gu/lookat.o: OPTFLAGS := -Os +build/src/libultra/gu/ortho.o: OPTFLAGS := -Os +build/src/libultra/libc/ll.o: OPTFLAGS := -Os +build/src/libultra/gu/perspective.o: OPTFLAGS := -Os +build/src/libultra/gu/mtxutil.o: OPTFLAGS := -Os +build/src/libultra/gu/cosf.o: OPTFLAGS := -Os +build/src/libultra/libc/xprintf.o: OPTFLAGS := -Os +build/src/libultra/libc/xldtob.o: OPTFLAGS := -Os +endif all: uncompressed diff --git a/include/libc/math.h b/include/libc/math.h index 0e63d99b..4eb99a73 100644 --- a/include/libc/math.h +++ b/include/libc/math.h @@ -41,7 +41,9 @@ double fabs(double f); #endif float sqrtf(float f); +#if defined(__sgi) #pragma intrinsic(sqrtf) +#endif double sqrt(double d); #pragma intrinsic(sqrt) diff --git a/src/audio/audio_heap.c b/src/audio/audio_heap.c index 69c5e6ca..2f59b183 100644 --- a/src/audio/audio_heap.c +++ b/src/audio/audio_heap.c @@ -765,6 +765,7 @@ u8* AudioHeap_AllocPermanent(s32 tableType, s32 id, u32 size) { ramAddr = AudioHeap_Alloc(&gPermanentPool.pool, size); gPermanentPool.entry[index].ramAddr = ramAddr; + if (ramAddr == NULL) { return NULL; } @@ -772,7 +773,10 @@ u8* AudioHeap_AllocPermanent(s32 tableType, s32 id, u32 size) { gPermanentPool.entry[index].tableType = tableType; gPermanentPool.entry[index].id = id; gPermanentPool.entry[index].size = size; - // return temp; + +#ifdef AVOID_UB + return ramAddr; +#endif } void* AudioHeap_AllocTemporarySampleCache(s32 size, s32 fontId, s32 sampleAddr, s8 medium) { diff --git a/src/audio/note_data.c b/src/audio/note_data.c index 79225a4b..20fd3353 100644 --- a/src/audio/note_data.c +++ b/src/audio/note_data.c @@ -280,7 +280,7 @@ u16 gHaasEffectDelaySizes[64] = { }; // clang-format off -s16 D_800DD200[] = { +ALIGNED(16) s16 D_800DD200[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, diff --git a/src/audio/wave_samples.c b/src/audio/wave_samples.c index b21d31be..60406673 100644 --- a/src/audio/wave_samples.c +++ b/src/audio/wave_samples.c @@ -1,7 +1,7 @@ #include "sys.h" // clang-format off -s16 gSawtoothWaveSample[] = { +ALIGNED(16) s16 gSawtoothWaveSample[] = { // Frequency of 1 0, 1023, 2047, 3071, 4095, 5119, 6143, 7167, 8191, 9215, 10239, 11263, 12287, 13311, 14335, 15359, @@ -43,7 +43,7 @@ s16 gSawtoothWaveSample[] = { 0, 8191, 16383, 24575, -32767, -24575, -16383, -8191, }; -s16 gTriangleWaveSample[] = { +ALIGNED(16) s16 gTriangleWaveSample[] = { // Frequency of 1 0, 2047, 4095, 6143, 8191, 10239, 12287, 14335, 16383, 18431, 20479, 22527, 24575, 26623, 28671, 30719, @@ -85,7 +85,7 @@ s16 gTriangleWaveSample[] = { 0, 16383, 32767, 16383, 0, -16383, -32767, -16383, }; -s16 gSineWaveSample[] = { +ALIGNED(16) s16 gSineWaveSample[] = { // Frequency of 1 0, 3211, 6392, 9511, 12539, 15446, 18204, 20787, 23169, 25329, 27244, 28897, 30272, 31356, 32137, 32609, @@ -127,7 +127,7 @@ s16 gSineWaveSample[] = { 0, 23169, 32767, 23169, 0, -23169, -32767, -23169, }; -s16 gSquareWaveSample[] = { +ALIGNED(16) s16 gSquareWaveSample[] = { // Frequency of 1 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -169,7 +169,7 @@ s16 gSquareWaveSample[] = { 0, 0, 32767, 32767, 0, 0, -32767, -32767, }; -s16 gWhiteNoiseSample[] = { +ALIGNED(16) s16 gWhiteNoiseSample[] = { // Frequency of 1 0, -25689, -25791, 27803, -27568, -21030, 22174, 6298, 27071, -18531, 28649, 2284, 3380, 6890, -12682, -21114, @@ -212,7 +212,7 @@ s16 gWhiteNoiseSample[] = { }; // Sine White Noise? -s16 gUnkSample[] = { +ALIGNED(16) s16 gUnkSample[] = { // Frequency of 1 0, 16316, 20148, 20257, 27209, -32657, 29264, 27259, -29394, -21494, -26410, 30770, 30033, 29130, 20206, 14129, @@ -255,6 +255,7 @@ s16 gUnkSample[] = { }; // clang-format on +ALIGNED(16) s16* gWaveSamples[] = { gSawtoothWaveSample, gTriangleWaveSample, gSineWaveSample, gSquareWaveSample, gWhiteNoiseSample, gUnkSample, }; diff --git a/src/libultra/gcc_fix/sqrtf.c.inc b/src/libultra/gcc_fix/sqrtf.c.inc new file mode 100644 index 00000000..b1dbee47 --- /dev/null +++ b/src/libultra/gcc_fix/sqrtf.c.inc @@ -0,0 +1,130 @@ +/* --------------------------------------------------------------------------------*/ +/* Depending on the toolchain used, an appropriate precompiled libgcc library */ +/* may not exist and cannot be linked against. Until we have a better work around, */ +/* necessary gcc functions are hosted here in order to properly compile. */ +/* This file is NOT a part of the original game and only exists to help gcc work. */ +/* --------------------------------------------------------------------------------*/ + +asm(" \n\ + .set push \n\ + .set noat \n\ + .set noreorder \n\ + .set gp=64 \n\ + \n\ +.global sqrtf \n\ +sqrtf: \n\ + jr $ra \n\ + sqrt.s $f0, $f12 \n\ + nop \n\ + nop \n\ + \n"); + +asm(" \n\ + .set push \n\ + .set noat \n\ + .set noreorder \n\ + .set gp=64 \n\ + \n\ +.global __umoddi3 \n\ +__umoddi3: \n\ + .type __umoddi3, @function \n\ + .ent __umoddi3 \n\ + sw $a0, ($sp) \n\ + sw $a1, 4($sp) \n\ + sw $a2, 8($sp) \n\ + sw $a3, 0xc($sp) \n\ + ld $t7, 8($sp) \n\ + ld $t6, ($sp) \n\ + ddivu $zero, $t6, $t7 \n\ + bnez $t7, 1f \n\ + nop \n\ + break 7 \n\ +1: \n\ + mfhi $v0 \n\ + dsll32 $v1, $v0, 0 \n\ + dsra32 $v1, $v1, 0 \n\ + jr $ra \n\ + dsra32 $v0, $v0, 0 \n\ + .end __umoddi3 \n\ + .size __umoddi3, . - __umoddi3 \n\ + \n\ +.global __udivdi3 \n\ +__udivdi3: \n\ + .type __udivdi3, @function \n\ + .ent __udivdi3 \n\ + sw $a0, ($sp) \n\ + sw $a1, 4($sp) \n\ + sw $a2, 8($sp) \n\ + sw $a3, 0xc($sp) \n\ + ld $t7, 8($sp) \n\ + ld $t6, ($sp) \n\ + ddivu $zero, $t6, $t7 \n\ + bnez $t7, 1f \n\ + nop \n\ + break 7 \n\ +1: \n\ + mflo $v0 \n\ + dsll32 $v1, $v0, 0 \n\ + dsra32 $v1, $v1, 0 \n\ + jr $ra \n\ + dsra32 $v0, $v0, 0 \n\ + .end __udivdi3 \n\ + .size __udivdi3, . - __udivdi3 \n\ + \n\ +.global __moddi3 \n\ +__moddi3: \n\ + .type __moddi3, @function \n\ + .ent __moddi3 \n\ + sw $a0, ($sp) \n\ + sw $a1, 4($sp) \n\ + sw $a2, 8($sp) \n\ + sw $a3, 0xc($sp) \n\ + ld $t7, 8($sp) \n\ + ld $t6, ($sp) \n\ + ddivu $zero, $t6, $t7 \n\ + bnez $t7, 1f \n\ + nop \n\ + break 7 \n\ +1: \n\ + mfhi $v0 \n\ + dsll32 $v1, $v0, 0 \n\ + dsra32 $v1, $v1, 0 \n\ + jr $ra \n\ + dsra32 $v0, $v0, 0 \n\ + .end __moddi3 \n\ + .size __moddi3, . - __moddi3 \n\ + \n\ +.global __divdi3 \n\ +__divdi3: \n\ + .type __divdi3, @function \n\ + .ent __divdi3 \n\ + sw $a0, ($sp) \n\ + sw $a1, 4($sp) \n\ + sw $a2, 8($sp) \n\ + sw $a3, 0xc($sp) \n\ + ld $t7, 8($sp) \n\ + ld $t6, ($sp) \n\ + ddiv $zero, $t6, $t7 \n\ + nop \n\ + bnez $t7, 1f \n\ + nop \n\ + break 7 \n\ +1: \n\ + daddiu $at, $zero, -1 \n\ + bne $t7, $at, 2f \n\ + daddiu $at, $zero, 1 \n\ + dsll32 $at, $at, 0x1f \n\ + bne $t6, $at, 2f \n\ + nop \n\ + break 6 \n\ +2: \n\ + mflo $v0 \n\ + dsll32 $v1, $v0, 0 \n\ + dsra32 $v1, $v1, 0 \n\ + jr $ra \n\ + dsra32 $v0, $v0, 0 \n\ + .end __divdi3 \n\ + .size __divdi3, . - __divdi3 \n\ + \n\ + .set pop \n\ + \n"); diff --git a/src/libultra/gu/sqrtf.c b/src/libultra/gu/sqrtf.c index 57df68b3..d8221c18 100644 --- a/src/libultra/gu/sqrtf.c +++ b/src/libultra/gu/sqrtf.c @@ -1,6 +1,10 @@ #include "PR/ultratypes.h" #include "libc/math.h" +#ifdef COMPILER_GCC +#include "src/libultra/gcc_fix/sqrtf.c.inc" +#endif + f32 guSqrtf(f32 value) { return sqrtf(value); } diff --git a/src/overlays/ovl_menu/fox_option.c b/src/overlays/ovl_menu/fox_option.c index 25c9d7e8..3536c47f 100644 --- a/src/overlays/ovl_menu/fox_option.c +++ b/src/overlays/ovl_menu/fox_option.c @@ -365,6 +365,14 @@ void Option_Setup(void) { bool playedExpertMode; s32 i; +#if MODS_LEVEL_SELECT == 1 + for (i = 0; i < PLANET_MAX; i++) { + gSaveFile.save.data.planet[i].expertClear = 1; + gSaveFile.save.data.planet[i].normalClear = 1; + gSaveFile.save.data.planet[i].played = 1; + } + Save_Write(); +#endif gVIsPerFrame = 2; sOptionCardList[0].unk_00.unk_08 = D_OPT_8003B50; diff --git a/src/sys/sys_fault.c b/src/sys/sys_fault.c index 9eb0cd9b..864a3be7 100644 --- a/src/sys/sys_fault.c +++ b/src/sys/sys_fault.c @@ -241,6 +241,8 @@ void Fault_ThreadEntry(void* arg0) { func_8000762C(300, 10, "-"); gControllerPlugged[0] = 1; + +#if 1 // Turn this off for instant crash debugger (no button combination needed) while (var_s5 == 0) { osSendMesg(&gSerialThreadMsgQueue, (OSMesg) SI_READ_CONTROLLER, OS_MESG_PRI_NORMAL); osRecvMesg(&gControllerMsgQueue, NULL, OS_MESG_BLOCK); @@ -312,6 +314,8 @@ void Fault_ThreadEntry(void* arg0) { var_s0 = 0; } } +#endif + func_80007910(sp40); while (1) { ;