diff --git a/Makefile b/Makefile index dd90f62..b229ce7 100644 --- a/Makefile +++ b/Makefile @@ -68,7 +68,7 @@ ENDLINE := \n' ### Compiler Options ### ASFLAGS := -G 0 -I include -mips3 -mabi=32 -CFLAGS := -O1 -G0 -mips3 -mgp32 -mfp32 +CFLAGS := -O1 -G0 -mips3 -mgp32 -mfp32 -Wa,--vr4300mul-off CPPFLAGS := -I include -I $(BUILD_DIR)/include -I src -DF3DEX_GBI_2 LDFLAGS := -T undefined_syms.txt -T undefined_funcs.txt -T undefined_funcs_auto.txt -T undefined_syms_auto.txt -T $(LD_SCRIPT) -Map $(LD_MAP) --no-check-sections CFLAGS_CHECK := -fsyntax-only -fsigned-char -nostdinc -fno-builtin -D CC_CHECK\ @@ -86,9 +86,7 @@ DEPENDS := $(OBJECTS:=.d) ### Targets ### -#build/src/libultra/os/%.o: CFLAGS := -O2 $(CFLAGSCOMMON) -#build/src/libultra/libc/%.o: CFLAGS := -O2 $(CFLAGSCOMMON) -#build/src/lib/%.o: CFLAGS := -O2 $(CFLAGSCOMMON) +build/src/libhmath/%.o: CFLAGS := -O2 -G0 -mips3 -mgp32 -mfp32 -ffast-math all: $(ROM) @@ -112,8 +110,6 @@ split: test: $(ROM) $(V)$(EMULATOR) $< - -export VR4300MUL := OFF # Compile .c files with kmc gcc (use strip to fix objects so that they can be linked with modern gnu ld) $(BUILD_DIR)/src/%.c.o: src/%.c @$(PRINT)$(GREEN)Compiling C file: $(ENDGREEN)$(BLUE)$<$(ENDBLUE)$(ENDLINE) diff --git a/include/common_structs.h b/include/common_structs.h index a0cf201..2d21089 100644 --- a/include/common_structs.h +++ b/include/common_structs.h @@ -3,18 +3,13 @@ #include "common.h" #include "process.h" +#include "math.h" #define MAX_PLAYERS 4 #define OS_K0_TO_PHYSICAL(x) (u32)(((char *)(x)-0x80000000)) #define OS_PHYSICAL_TO_K0(x) (void *)(((u32)(x)+0x80000000)) -typedef struct { - f32 x; - f32 y; - f32 z; -} HuVec3F; - typedef struct objectt { /*0x00*/ struct objectt *prev; /*0x04*/ struct objectt *next; diff --git a/include/math.h b/include/math.h index d380476..c227df3 100644 --- a/include/math.h +++ b/include/math.h @@ -1,8 +1,22 @@ #ifndef _MATH_H_ #define _MATH_H_ +#include "PR/ultratypes.h" + #define M_PI 3.14159265358979323846 +typedef struct { + f32 x; + f32 y; + f32 z; +} HuVec3F; + +typedef struct { + s32 x; + s32 y; + s32 z; +} HuVec3I; + // TODO: Where are these in libultra, if anywhere? float sinf(float); //double sin(double); @@ -10,5 +24,11 @@ float cosf(float); //double cos(double); float sqrtf(float); +float HuSqrtf(float x); + +void HuVecCopyXYZ(HuVec3F * out, f32 x, f32 y, f32 z); +void HuVecCopy3F(HuVec3F * out, HuVec3F * a); +f32 HuVecGetLengthSqr3F(HuVec3F * vec); +f32 HuVecGetLength3F(HuVec3F * vec); #endif diff --git a/marioparty3.yaml b/marioparty3.yaml index dd0639b..04a6160 100644 --- a/marioparty3.yaml +++ b/marioparty3.yaml @@ -72,6 +72,7 @@ segments: - [0x47D60, asm] - [0x4B120, asm] - [0x4BF40, asm] + - [0x4E010, asm, profiler] - [0x4E5A0, c, rom] - [0x4E800, asm] - [0x4F720, c, "process"] @@ -310,10 +311,12 @@ segments: - [0x88440, asm] - [0x88460, asm] - [0x88710, asm] - - [0x88830, asm] - - [0x88CE0, asm] - - [0x88CF0, asm] - - [0x88D50, asm] + - [0x88830, asm] # last libultra scope + - [0x88CE0, c, libhmath/sqrtf] + - [0x88CF0, c, libhmath/vecmag] + - [0x88D50, c, libhmath/vecnorm] + - [0x88DE0, c, libhmath/vecdot] + - [0x88E10, asm] - [0x890B0, asm] - [0x89120, asm] - [0x89510, asm] @@ -325,15 +328,20 @@ segments: - [0x8A4A0, asm] - [0x8A4D0, asm] - [0x8A580, asm] - - [0x8A610, asm] - - [0x8A640, asm] - - [0x8A670, asm] - - [0x8A6B0, asm] - - [0x8A6F0, asm] - - [0x8A770, asm] - - [0x8A830, asm] - - [0x8A860, asm] - - [0x8A890, asm] + - [0x8A610, c, libhmath/veccopy] + - [0x8A640, c, libhmath/vecneg] + - [0x8A670, c, libhmath/vecadd] + - [0x8A6B0, c, libhmath/vecsub] + - [0x8A6F0, c, libhmath/vecmuls] + - [0x8A720, c, libhmath/vecadds] + - [0x8A770, c, libhmath/veclinc] + - [0x8A830, c, libhmath/vecmags3f] + - [0x8A860, c, libhmath/vecmag3f] + - [0x8A890, c, libhmath/vecnorm3f] + - [0x8A920, c, libhmath/vecdist] + - [0x8A9B0, c, libhmath/vecdot3f] + - [0x8A9E0, c, libhmath/veccross] + - [0x8AA30, c, libhmath/veceq] - [0x8AA90, asm] - [0x8AC30, asm] - [0x8AC70, asm] diff --git a/permuter_settings.toml b/permuter_settings.toml new file mode 100644 index 0000000..a967cd5 --- /dev/null +++ b/permuter_settings.toml @@ -0,0 +1,13 @@ +compiler_command = "tools/gcc_2.7.2/gcc -w -Iinclude -Isrc -D_LANGUAGE_C -D_FINALROM -DVERSION=us -DF3DEX_GBI_2 -D_MIPS_SZLONG=32 -nostdinc -c -G0 -O3 -x c -B tools/gcc_2.7.2/ -Wmissing-braces -Wimplicit -Wredundant-decls -Wstrict-prototypes -DPERMUTER -fforce-addr" + +assembler_command = "mips-linux-gnu-as -EB -march=vr4300 -mtune=vr4300 -Iinclude" + +compiler_type = "gcc" + +[preserve_macros] +"gs?[DS]P.*" = "void" +OVERRIDE_FLAG_CHECK = "int" +OS_K0_TO_PHYSICAL = "int" +"G_.*" = "int" +"TEXEL.*" = "int" +PRIMITIVE = "int" \ No newline at end of file diff --git a/src/libhmath/sqrtf.c b/src/libhmath/sqrtf.c new file mode 100644 index 0000000..264ec8b --- /dev/null +++ b/src/libhmath/sqrtf.c @@ -0,0 +1,5 @@ +#include "common.h" + +f32 HuSqrtf(f32 x) { + return sqrtf(x); +} diff --git a/src/libhmath/vecadd.c b/src/libhmath/vecadd.c new file mode 100644 index 0000000..857aa93 --- /dev/null +++ b/src/libhmath/vecadd.c @@ -0,0 +1,14 @@ +#include "common.h" +#include "math.h" + +void HuVecAdd(HuVec3F * out, HuVec3F * a, HuVec3F * b) +{ + float x = a->x + b->x; + float y = a->y + b->y; + float z = a->z + b->z; + + out->x = x; + out->y = y; + out->z = z; +} + diff --git a/src/libhmath/vecadds.c b/src/libhmath/vecadds.c new file mode 100644 index 0000000..e1f03ad --- /dev/null +++ b/src/libhmath/vecadds.c @@ -0,0 +1,14 @@ +#include "common.h" +#include "math.h" + +void HuVecAddScaled(HuVec3F * out, HuVec3F * a, f32 scalar, HuVec3F * b) +{ + float x = a->x + (scalar * b->x); + float y = a->y + (scalar * b->y); + float z = a->z + (scalar * b->z); + + out->x = x; + out->y = y; + out->z = z; +} + diff --git a/src/libhmath/veccopy.c b/src/libhmath/veccopy.c new file mode 100644 index 0000000..4c50297 --- /dev/null +++ b/src/libhmath/veccopy.c @@ -0,0 +1,15 @@ +#include "common.h" +#include "math.h" + +void HuVecCopyXYZ(HuVec3F * out, f32 x, f32 y, f32 z) +{ + out->x = x; + out->y = y; + out->z = z; +} + +void HuVecCopy3F(HuVec3F * out, HuVec3F * a) +{ + *out = *a; +} + diff --git a/src/libhmath/veccross.c b/src/libhmath/veccross.c new file mode 100644 index 0000000..6848c3e --- /dev/null +++ b/src/libhmath/veccross.c @@ -0,0 +1,15 @@ +#include "math.h" + +void HuVecCross(HuVec3F * out, HuVec3F * a, HuVec3F * b) +{ + f32 vector1Y = a->y; + f32 vector2Z = b->z; + f32 vector1Z = a->z; + f32 vector2Y = b->y; + f32 vector2X = b->x; + f32 vector1X = a->x; + + out->x = (vector1Y * vector2Z) - (vector1Z * vector2Y); + out->y = (vector1Z * vector2X) - (vector1X * vector2Z); + out->z = (vector1X * vector2Y) - (vector1Y * vector2X); +} diff --git a/src/libhmath/vecdist.c b/src/libhmath/vecdist.c new file mode 100644 index 0000000..d779113 --- /dev/null +++ b/src/libhmath/vecdist.c @@ -0,0 +1,37 @@ +#include "common.h" +#include "math.h" + +// this matches, but the entire file needs to have inlined assembly for the mulmul fix to work +#ifdef NONMATCHING +f32 _HuVecDistanceSqr(HuVec3F * a, HuVec3F * b) +{ + f32 x; + f32 y; + f32 z; + + x = a->x - b->x; + y = a->y - b->y; + z = a->z - b->z; + + return (x * x) + (y * y) + (z * z); +} +#else +INCLUDE_ASM(f32, "libhmath/vecdist", HuVecDistanceSqr, HuVec3F * a, HuVec3F * b); +#endif + +// https://decomp.me/scratch/02P6S +// // the original output has the function prologue near the end rather than the start +#ifdef NONMATCHING +f32 _HuVecDistance(HuVec3F * arg0, HuVec3F * arg1) { + f32 temp_f0; + f32 temp_f12; + f32 temp_f2; + + temp_f0 = arg0->x - arg1->x; + temp_f2 = arg0->y - arg1->y; + temp_f12 = arg0->z - arg1->z; + return HuSqrtf((temp_f0 * temp_f0) + (temp_f2 * temp_f2) + (temp_f12 * temp_f12)); +} +#else +INCLUDE_ASM(f32, "libhmath/vecdist", HuVecDistance, HuVec3F * a, HuVec3F * b); +#endif diff --git a/src/libhmath/vecdot.c b/src/libhmath/vecdot.c new file mode 100644 index 0000000..b05390a --- /dev/null +++ b/src/libhmath/vecdot.c @@ -0,0 +1,7 @@ +#include "common.h" + +f32 HuVecDotProduct(f32 aX, f32 aY, f32 aZ, f32 bX, f32 bY, f32 bZ) +{ + return (aX * bX) + (aY * bY) + (aZ * bZ); +} + diff --git a/src/libhmath/vecdot3f.c b/src/libhmath/vecdot3f.c new file mode 100644 index 0000000..f9a4f28 --- /dev/null +++ b/src/libhmath/vecdot3f.c @@ -0,0 +1,6 @@ +#include "math.h" + +f32 HuVecDot3F(HuVec3F * a, HuVec3F * b) +{ + return (a->x * b->x) + (a->y * b->y) + (a->z * b->z); +} diff --git a/src/libhmath/veceq.c b/src/libhmath/veceq.c new file mode 100644 index 0000000..c9fa9d5 --- /dev/null +++ b/src/libhmath/veceq.c @@ -0,0 +1,9 @@ +#include "common.h" +#include "math.h" + +s32 HuVecIsEqual(HuVec3F * a, HuVec3F * b) { + if ((a->x == b->x) && (a->y == b->y) && (a->z == b->z)) { + return TRUE; + } + return FALSE; +} diff --git a/src/libhmath/veclinc.c b/src/libhmath/veclinc.c new file mode 100644 index 0000000..e06421a --- /dev/null +++ b/src/libhmath/veclinc.c @@ -0,0 +1,33 @@ +#include "common.h" +#include "math.h" + +void HuVecLinearComb(HuVec3F * out, f32 scale, HuVec3F * a, f32 arg3, HuVec3F * b) +{ + float x = (scale * a->x) + (arg3 * b->x); + float y = (scale * a->y) + (arg3 * b->y); + float z = (scale * a->z) + (arg3 * b->z); + + out->x = x; + out->y = y; + out->z = z; +} + +void HuVecLinearComb2D(HuVec3F * out, HuVec3F * scale, HuVec3F * a, HuVec3F * b) +{ + f32 scaleX; + f32 scaleY; + f32 x; + f32 y; + f32 z; + + scaleX = scale->x; + scaleY = scale->y; + + x = (scaleX * a->x) + (scaleY * b->x); + y = (scaleX * a->y) + (scaleY * b->y); + z = (scaleX * a->z) + (scaleY * b->z); + + out->x = x; + out->y = y; + out->z = z; +} diff --git a/src/libhmath/vecmag.c b/src/libhmath/vecmag.c new file mode 100644 index 0000000..b13f575 --- /dev/null +++ b/src/libhmath/vecmag.c @@ -0,0 +1,14 @@ +#include +#include "math.h" + +f32 HuSqrtf(f32); +f32 HuVecGetLengthSqr(f32 arg0, f32 arg1, f32 arg2); +f32 HuVecGetLength(f32 arg0, f32 arg1, f32 arg2); + +f32 HuVecGetLengthSqr(f32 arg0, f32 arg1, f32 arg2) { + return (arg0 * arg0) + (arg1 * arg1) + (arg2 * arg2); +} + +f32 mulHuVecGetLength(f32 arg0, f32 arg1, f32 arg2) { + return HuSqrtf(HuVecGetLengthSqr(arg0, arg1, arg2)); +} \ No newline at end of file diff --git a/src/libhmath/vecmag3f.c b/src/libhmath/vecmag3f.c new file mode 100644 index 0000000..8025902 --- /dev/null +++ b/src/libhmath/vecmag3f.c @@ -0,0 +1,7 @@ +#include "common.h" +#include "math.h" + +float HuVecGetLength3F(HuVec3F * vec) +{ + return HuSqrtf(HuVecGetLengthSqr3F(vec)); +} diff --git a/src/libhmath/vecmags3f.c b/src/libhmath/vecmags3f.c new file mode 100644 index 0000000..b724b37 --- /dev/null +++ b/src/libhmath/vecmags3f.c @@ -0,0 +1,16 @@ +#include "common.h" +#include "math.h" + +f32 HuVecGetLengthSqr3F(HuVec3F * vec) +{ + f32 x; + f32 y; + f32 z; + + x = vec->x; + y = vec->y; + z = vec->z; + + return (x * x) + (y * y) + (z * z); +} + diff --git a/src/libhmath/vecmuls.c b/src/libhmath/vecmuls.c new file mode 100644 index 0000000..8a738ec --- /dev/null +++ b/src/libhmath/vecmuls.c @@ -0,0 +1,13 @@ +#include "common.h" +#include "math.h" + +void HuVecMulScalar(HuVec3F * out, f32 scalar, HuVec3F * a) +{ + float x = scalar * a->x; + float y = scalar * a->y; + float z = scalar * a->z; + + out->x = x; + out->y = y; + out->z = z; +} diff --git a/src/libhmath/vecneg.c b/src/libhmath/vecneg.c new file mode 100644 index 0000000..5f84f36 --- /dev/null +++ b/src/libhmath/vecneg.c @@ -0,0 +1,14 @@ +#include "common.h" +#include "math.h" + +void HuVecNeg(HuVec3F * out, HuVec3F * a) { + + float x = -a->x; + float y = -a->y; + float z = -a->z; + + out->x = x; + out->y = y; + out->z = z; +} + diff --git a/src/libhmath/vecnorm.c b/src/libhmath/vecnorm.c new file mode 100644 index 0000000..ece58cd --- /dev/null +++ b/src/libhmath/vecnorm.c @@ -0,0 +1,19 @@ +#include "common.h" +#include "math.h" + +void HuVecNormalize(f32 * x, f32 * y, f32 * z) +{ + f32 oldX; + f32 oldY; + f32 oldZ; + f32 invMag; + + oldX = *x; + oldY = *y; + oldZ = *z; + invMag = 1.0f / HuSqrtf((oldX * oldX) + (oldY * oldY) + (oldZ * oldZ)); + + *x *= invMag; + *y *= invMag; + *z *= invMag; +} \ No newline at end of file diff --git a/src/libhmath/vecnorm3f.c b/src/libhmath/vecnorm3f.c new file mode 100644 index 0000000..b77b724 --- /dev/null +++ b/src/libhmath/vecnorm3f.c @@ -0,0 +1,25 @@ +#include "common.h" +#include "math.h" + +// https://decomp.me/scratch/6UMIQ +// the original output has the function prologue near the end rather than the start +#ifdef NONMATCHING +void _HuVecNormalize3F(HuVec3F * vec) +{ + f32 x; + f32 y; + f32 z; + f32 invMag; + + x = vec->x; + y = vec->y; + z = vec->z; + invMag = 1.0f / HuSqrtf((x * x) + (y * y) + (z * z)); + + vec->x = invMag * x; + vec->y = invMag * y; + vec->z = invMag * z; +} +#else +INCLUDE_ASM(void, "libhmath/vecnorm3f", HuVecNormalize3F, HuVec3F * vec); +#endif \ No newline at end of file diff --git a/src/libhmath/vecsub.c b/src/libhmath/vecsub.c new file mode 100644 index 0000000..f10ff9b --- /dev/null +++ b/src/libhmath/vecsub.c @@ -0,0 +1,14 @@ +#include "common.h" +#include "math.h" + +void HuVecSubtract(HuVec3F * dest, HuVec3F * a, HuVec3F * b) { + + + float x = a->x - b->x; + float y = a->y - b->y; + float z = a->z - b->z; + + dest->x = x; + dest->y = y; + dest->z = z; +} diff --git a/src/overlays/board_gate_guy/3D8AC0.c b/src/overlays/board_gate_guy/3D8AC0.c index 218f82e..282dcd4 100644 --- a/src/overlays/board_gate_guy/3D8AC0.c +++ b/src/overlays/board_gate_guy/3D8AC0.c @@ -1,4 +1,5 @@ #include "GateGuy.h" +#include "math.h" void func_801059D0_3D8AC0(void) { D_800CDD58 = 1; @@ -142,10 +143,10 @@ void* func_80106740_3D9830(s32 arg0) { return temp_v0; } -void func_801067D4_3D98C4(object* arg0, s32 arg1) { +void func_801067D4_3D98C4(object* arg0, HuVec3F * arg1) { func_800D8E88(); func_8001C814_1D414(*arg0->unk3C->unk40, 3, 0); - func_80089A20_8A620(&arg0->coords, arg1); + HuVecCopy3F(&arg0->coords, arg1); } INCLUDE_ASM(s32, "overlays/board_gate_guy/3D8AC0", func_80106828_3D9918); diff --git a/src/overlays/gate_guy_intro1/3D8930.c b/src/overlays/gate_guy_intro1/3D8930.c index 2417a7f..334cb49 100644 --- a/src/overlays/gate_guy_intro1/3D8930.c +++ b/src/overlays/gate_guy_intro1/3D8930.c @@ -12,4 +12,4 @@ extern board_overlay_entrypoint D_80105AE0_3D8A70[]; void func_801059A0_3D8930(void) { //func_800359E0_365E0 is ExecBoardScene from mp1 func_800359E0_365E0(D_80105AE0_3D8A70, D_800A1764_A2364); -} +} \ No newline at end of file diff --git a/symbol_addrs.txt b/symbol_addrs.txt index 1ccaf8b..28e2845 100644 --- a/symbol_addrs.txt +++ b/symbol_addrs.txt @@ -450,4 +450,27 @@ guPerspective = 0x8007B010; guNormalize = 0x80082B00; gCurrentPlayerIndex = 0x800CD067; guLookAtF = 0x80088210; -guLookAt = 0x80079800; \ No newline at end of file +guLookAt = 0x80079800; +HuSqrtf = 0x800880E0; + +HuVecGetLengthSqr = 0x800880F4; +HuVecGetLength = 0x80088120; +HuVecNormalize = 0x80088150; +HuVecDotProduct = 0x800881E0; +HuVecCopyXYZ = 0x80089A10; +HuVecCopy3F = 0x80089A20; +HuVecNeg = 0x80089A40; +HuVecAdd = 0x80089A70; +HuVecSubtract = 0x80089AB0; +HuVecMulScalar = 0x80089AF0; +HuVecAddScaled = 0x80089B20; +HuVecLinearComb = 0x80089B70; +HuVecLinearComb2D = 0x80089BD0; +HuVecGetLengthSqr3F = 0x80089C30; +HuVecGetLength3F = 0x80089C60; +HuVecNormalize3F = 0x80089C90; +HuVecDistanceSqr = 0x80089D20; +HuVecDistance = 0x80089D60; +HuVecDot3F = 0x80089DB0; +HuVecCross = 0x80089DE0; +HuVecIsEqual = 0x80089E30; \ No newline at end of file diff --git a/tools/gcc_2.7.2/ar b/tools/gcc_2.7.2/ar index d320211..e238cc1 100755 Binary files a/tools/gcc_2.7.2/ar and b/tools/gcc_2.7.2/ar differ diff --git a/tools/gcc_2.7.2/as b/tools/gcc_2.7.2/as index 915f3da..97f700d 100755 Binary files a/tools/gcc_2.7.2/as and b/tools/gcc_2.7.2/as differ diff --git a/tools/gcc_2.7.2/objcopy b/tools/gcc_2.7.2/objcopy index c044a43..9ab4404 100755 Binary files a/tools/gcc_2.7.2/objcopy and b/tools/gcc_2.7.2/objcopy differ diff --git a/tools/gcc_2.7.2/strip b/tools/gcc_2.7.2/strip index d6f49da..1645037 100755 Binary files a/tools/gcc_2.7.2/strip and b/tools/gcc_2.7.2/strip differ