From 83163f4d4bb4217f0d973328afe92e7f50d01396 Mon Sep 17 00:00:00 2001 From: Dragorn421 Date: Tue, 13 Dec 2022 02:55:57 +0100 Subject: [PATCH] Fix misc GCC compatibility issues (#1463) * Fix osGetMemSize being optimized to `return 8MB` by gcc Co-authored-by: Tharo <17233964+Thar0@users.noreply.github.com> Co-authored-by: ariahiro64 <45049787+ariahiro64@users.noreply.github.com> * Workaround f32 to s16 cast for binang being UB if binang doesn't fit s16 Co-authored-by: Tharo <17233964+Thar0@users.noreply.github.com> Co-authored-by: ariahiro64 <45049787+ariahiro64@users.noreply.github.com> * osGetMemSize fixup * include z64math in z64camera Co-authored-by: Tharo <17233964+Thar0@users.noreply.github.com> Co-authored-by: ariahiro64 <45049787+ariahiro64@users.noreply.github.com> --- include/z64camera.h | 3 ++- include/z64math.h | 10 ++++++++-- src/libultra/os/getmemsize.c | 4 ++-- 3 files changed, 12 insertions(+), 5 deletions(-) diff --git a/include/z64camera.h b/include/z64camera.h index bf302e5330..dad8a19ecc 100644 --- a/include/z64camera.h +++ b/include/z64camera.h @@ -3,10 +3,11 @@ #include "ultra64.h" #include "z64cutscene.h" +#include "z64math.h" #include "z64save.h" // these two angle conversion macros are slightly inaccurate -#define CAM_DEG_TO_BINANG(degrees) (s16)((degrees) * 182.04167f + .5f) +#define CAM_DEG_TO_BINANG(degrees) (s16)TRUNCF_BINANG((degrees) * 182.04167f + .5f) #define CAM_BINANG_TO_DEG(binang) ((f32)(binang) * (360.0001525f / 65535.0f)) #define CAM_STAT_CUT 0 diff --git a/include/z64math.h b/include/z64math.h index b4a128dfb3..6661a8dc22 100644 --- a/include/z64math.h +++ b/include/z64math.h @@ -100,9 +100,15 @@ typedef VecSphGeo VecGeo; #define IS_ZERO(f) (fabsf(f) < 0.008f) +// Casting a float to an integer, when the float value is larger than what the integer type can hold, +// leads to undefined behavior. For example (f32)0x8000 doesn't fit in a s16, so it cannot be cast to s16. +// This isn't an issue with IDO, but is one with for example GCC. +// A partial workaround is to cast to s32 then s16, hoping all binang values used will fit a s32. +#define TRUNCF_BINANG(f) (s16)(s32)(f) + // Angle conversion macros -#define DEG_TO_BINANG(degrees) (s16)((degrees) * (0x8000 / 180.0f)) -#define RAD_TO_BINANG(radians) (s16)((radians) * (0x8000 / M_PI)) +#define DEG_TO_BINANG(degrees) (s16)TRUNCF_BINANG((degrees) * (0x8000 / 180.0f)) +#define RAD_TO_BINANG(radians) (s16)TRUNCF_BINANG((radians) * (0x8000 / M_PI)) #define RAD_TO_DEG(radians) ((radians) * (180.0f / M_PI)) #define DEG_TO_RAD(degrees) ((degrees) * (M_PI / 180.0f)) #define BINANG_TO_DEG(binang) ((f32)(binang) * (180.0f / 0x8000)) diff --git a/src/libultra/os/getmemsize.c b/src/libultra/os/getmemsize.c index 78eac6ebcf..787346de63 100644 --- a/src/libultra/os/getmemsize.c +++ b/src/libultra/os/getmemsize.c @@ -3,13 +3,13 @@ #define STEP 0x100000 u32 osGetMemSize(void) { - u32* ptr; + vu32* ptr; u32 size = 0x400000; u32 data0; u32 data1; while (size < 0x800000) { - ptr = (u32*)(0xA0000000 + size); + ptr = (vu32*)(K1BASE + size); data0 = *ptr; data1 = ptr[STEP / 4 - 1];