From 3475651701f991b636a74e0254ef1b9682fa1126 Mon Sep 17 00:00:00 2001 From: Tharo <17233964+Thar0@users.noreply.github.com> Date: Fri, 27 Oct 2023 15:06:44 +0100 Subject: [PATCH] libc cleanup (#1568) * libc cleanup * Suggested changes, small alloca tweak * Remove printf include --- Makefile | 2 +- include/alloca.h | 7 - include/attributes.h | 2 +- include/fault.h | 1 + include/fp.h | 34 ---- include/functions.h | 30 ++-- include/libc/alloca.h | 9 + include/libc/assert.h | 45 +++++ include/libc/math.h | 39 +++-- include/libc/stdarg.h | 66 +++++--- include/libc/stdbool.h | 7 +- include/libc/stddef.h | 12 +- include/libc/stdio.h | 9 + include/libc/stdlib.h | 13 +- include/libc/string.h | 11 ++ include/macros.h | 8 - include/message_data_fmt.h | 2 + include/ultra64.h | 14 +- include/ultra64/gu.h | 18 ++ include/ultra64/libc.h | 12 ++ include/ultra64/printf.h | 33 ---- include/ultra64/xstdio.h | 44 +++++ spec | 8 +- src/boot/assert.c | 6 +- src/boot/is_debug.c | 2 +- src/code/code_800FCE80.c | 1 - src/code/fault_drawer.c | 2 +- src/code/gfxprint.c | 2 +- src/code/load.c | 2 +- src/code/z_actor.c | 10 +- src/code/z_collision_check.c | 2 - src/libultra/libc/absf.c | 8 +- src/libultra/libc/ldiv.c | 6 +- src/libultra/libc/ll.c | 47 +++--- src/libultra/libc/llcvt.c | 18 +- src/libultra/libc/sprintf.c | 32 ++++ src/libultra/libc/sqrt.c | 8 +- src/libultra/libc/string.c | 22 +-- src/libultra/{rmon => libc}/xldtob.c | 100 +++++------ src/libultra/libc/xlitob.c | 58 +++++++ src/libultra/{rmon => libc}/xprintf.c | 159 ++++++++++-------- src/libultra/rmon/sprintf.c | 28 --- src/libultra/rmon/xlitob.c | 56 ------ .../actors/ovl_Door_Gerudo/z_door_gerudo.c | 2 +- .../actors/ovl_Door_Shutter/z_door_shutter.c | 2 +- .../actors/ovl_player_actor/z_player.c | 4 +- 46 files changed, 571 insertions(+), 432 deletions(-) delete mode 100644 include/alloca.h delete mode 100644 include/fp.h create mode 100644 include/libc/alloca.h create mode 100644 include/libc/assert.h create mode 100644 include/libc/stdio.h create mode 100644 include/libc/string.h create mode 100644 include/ultra64/libc.h delete mode 100644 include/ultra64/printf.h create mode 100644 include/ultra64/xstdio.h create mode 100644 src/libultra/libc/sprintf.c rename src/libultra/{rmon => libc}/xldtob.c (79%) create mode 100644 src/libultra/libc/xlitob.c rename src/libultra/{rmon => libc}/xprintf.c (51%) delete mode 100644 src/libultra/rmon/sprintf.c delete mode 100644 src/libultra/rmon/xlitob.c diff --git a/Makefile b/Makefile index e292f566da..4239c18f53 100644 --- a/Makefile +++ b/Makefile @@ -98,7 +98,7 @@ OBJDUMP := $(MIPS_BINUTILS_PREFIX)objdump EMULATOR ?= EMU_FLAGS ?= -INC := -Iinclude -Isrc -Ibuild -I. +INC := -Iinclude -Iinclude/libc -Isrc -Ibuild -I. # Check code syntax with host compiler CHECK_WARNINGS := -Wall -Wextra -Wno-format-security -Wno-unknown-pragmas -Wno-unused-parameter -Wno-unused-variable -Wno-missing-braces diff --git a/include/alloca.h b/include/alloca.h deleted file mode 100644 index 4e8720f7e8..0000000000 --- a/include/alloca.h +++ /dev/null @@ -1,7 +0,0 @@ -#ifndef ALLOCA_H -#define ALLOCA_H - -void* alloca(u32); -#define alloca __builtin_alloca - -#endif diff --git a/include/attributes.h b/include/attributes.h index 13fbe70f42..f58cc8122d 100644 --- a/include/attributes.h +++ b/include/attributes.h @@ -1,7 +1,7 @@ #ifndef ATTRIBUTES_H #define ATTRIBUTES_H -#ifndef __GNUC__ +#if !defined(__GNUC__) && !defined(__attribute__) #define __attribute__(x) #endif diff --git a/include/fault.h b/include/fault.h index c5837f99a3..778f708e9b 100644 --- a/include/fault.h +++ b/include/fault.h @@ -2,6 +2,7 @@ #define FAULT_H #include "ultra64.h" +#include "attributes.h" #include "padmgr.h" // These are the same as the 3-bit ansi color codes diff --git a/include/fp.h b/include/fp.h deleted file mode 100644 index c733be914c..0000000000 --- a/include/fp.h +++ /dev/null @@ -1,34 +0,0 @@ -#ifndef FP_H -#define FP_H -#include "ultra64.h" - -extern f32 qNaN0x3FFFFF; -extern f32 qNaN0x10000; -extern f32 sNaN0x3FFFFF; - -f32 floorf(f32 x); -f64 floor(f64 x); -s32 lfloorf(f32 x); -s32 lfloor(f64 x); - -f32 ceilf(f32 x); -f64 ceil(f64 x); -s32 lceilf(f32 x); -s32 lceil(f64 x); - -f32 truncf(f32 x); -f64 trunc(f64 x); -s32 ltruncf(f32 x); -s32 ltrunc(f64 x); - -f32 nearbyintf(f32 x); -f64 nearbyint(f64 x); -s32 lnearbyintf(f32 x); -s32 lnearbyint(f64 x); - -f32 roundf(f32 x); -f64 round(f64 x); -s32 lroundf(f32 x); -s32 lround(f64 x); - -#endif diff --git a/include/functions.h b/include/functions.h index 2714f6fa6c..506f31e5f4 100644 --- a/include/functions.h +++ b/include/functions.h @@ -5,15 +5,21 @@ #include "macros.h" f32 fabsf(f32 f); -#ifndef __sgi -#define fabsf(f) __builtin_fabsf((f32)(f)) -#else +#ifdef __sgi #pragma intrinsic(fabsf) +#else +#define fabsf(f) __builtin_fabsf((f32)(f)) #endif + f32 sqrtf(f32 f); +#ifdef __sgi #pragma intrinsic(sqrtf) +#endif + f64 sqrt(f64 f); +#ifdef __sgi #pragma intrinsic(sqrt) +#endif void cleararena(void); void bootproc(void); @@ -30,12 +36,9 @@ void Locale_ResetRegion(void); u32 func_80001F48(void); u32 func_80001F8C(void); u32 Locale_IsRegionNative(void); -NORETURN void __assert(const char* exp, const char* file, s32 line); void isPrintfInit(void); -void osSyncPrintfUnused(const char* fmt, ...); -void osSyncPrintf(const char* fmt, ...); void rmonPrintf(const char* fmt, ...); -void* is_proutSyncPrintf(void* arg, const char* str, u32 count); +void* is_proutSyncPrintf(void* arg, const char* str, size_t count); NORETURN void func_80002384(const char* exp, const char* file, u32 line); OSPiHandle* osDriveRomInit(void); void Mio0_Decompress(Yaz0Header* hdr, u8* dst); @@ -57,8 +60,6 @@ void LogUtils_CheckValidPointer(const char* exp, void* ptr, const char* file, s3 void LogUtils_LogThreadId(const char* name, s32 line); void LogUtils_HungupThread(const char* name, s32 line); void LogUtils_ResetHungup(void); -s32 vsprintf(char* dst, const char* fmt, va_list args); -s32 sprintf(char* dst, const char* fmt, ...); void __osPiCreateAccessQueue(void); void __osPiGetAccess(void); void __osPiRelAccess(void); @@ -75,7 +76,6 @@ void __osDispatchThread(void); void __osCleanupThread(void); void __osDequeueThread(OSThread** queue, OSThread* thread); void osDestroyThread(OSThread* thread); -void bzero(void* __s, s32 __n); void osCreateThread(OSThread* thread, OSId id, void (*entry)(void*), void* arg, void* sp, OSPri pri); void __osSetSR(u32); u32 __osGetSR(void); @@ -92,12 +92,8 @@ void osViSetMode(OSViMode* mode); u32 __osProbeTLB(void*); u32 osGetMemSize(void); void osSetEventMesg(OSEvent e, OSMesgQueue* mq, OSMesg msg); -s32 _Printf(PrintCallback, void* arg, const char* fmt, va_list ap); void osUnmapTLBAll(void); s32 osEPiStartDma(OSPiHandle* handle, OSIoMesg* mb, s32 direction); -const char* strchr(const char* str, s32 ch); -u32 strlen(const char* str); -void* memcpy(void* dst, const void* src, size_t size); void osInvalICache(void* vaddr, s32 nbytes); void osCreateMesgQueue(OSMesgQueue* mq, OSMesg* msg, s32 count); void osInvalDCache(void* vaddr, s32 nbytes); @@ -108,7 +104,6 @@ OSPri osGetThreadPri(OSThread* thread); s32 __osEPiRawReadIo(OSPiHandle* handle, u32 devAddr, u32* data); void osViSwapBuffer(void* frameBufPtr); s32 __osEPiRawStartDma(OSPiHandle* handle, s32 direction, u32 cartAddr, void* dramAddr, size_t size); -u32 bcmp(void* __sl, void* __s2, u32 __n); OSTime osGetTime(void); void __osTimerServicesInit(void); void __osTimerInterrupt(void); @@ -116,7 +111,6 @@ void __osSetTimerIntr(OSTime time); OSTime __osInsertTimer(OSTimer* timer); u32 osGetCount(void); void __osSetCompare(u32); -void* bcopy(void* __src, void* __dest, u32 __n); s32 __osDisableInt(void); void __osRestoreInt(s32); void __osViInit(void); @@ -132,10 +126,6 @@ void osMapTLBRdb(void); void osYieldThread(void); u32 __osGetCause(void); s32 __osEPiRawWriteIo(OSPiHandle* handle, u32 devAddr, u32 data); -void _Litob(_Pft* args, u8 type); -ldiv_t ldiv(s32 num, s32 denom); -lldiv_t lldiv(s64 num, s64 denom); -void _Ldtob(_Pft* args, u8 type); s32 __osSiRawWriteIo(void* devAddr, u32 val); void osCreateViManager(OSPri pri); OSViContext* __osViGetCurrentContext(void); diff --git a/include/libc/alloca.h b/include/libc/alloca.h new file mode 100644 index 0000000000..7bf44d764f --- /dev/null +++ b/include/libc/alloca.h @@ -0,0 +1,9 @@ +#ifndef ALLOCA_H +#define ALLOCA_H + +#include "stddef.h" + +void* alloca(size_t); +#define alloca(size) __builtin_alloca(size) + +#endif diff --git a/include/libc/assert.h b/include/libc/assert.h new file mode 100644 index 0000000000..96393c0e7c --- /dev/null +++ b/include/libc/assert.h @@ -0,0 +1,45 @@ +#ifndef ASSERT_H +#define ASSERT_H + +#if !defined(__GNUC__) && !defined(__attribute__) +#define __attribute__(x) +#endif + +// Runtime assertions + +__attribute__((noreturn)) void __assert(const char* assertion, const char* file, int line); + +// assert for matching +#ifndef NDEBUG +# ifndef NON_MATCHING +# define ASSERT(cond, msg, file, line) ((cond) ? ((void)0) : __assert(msg, file, line)) +# else +# define ASSERT(cond, msg, file, line) ((cond) ? ((void)0) : __assert(#cond, __FILE__, __LINE__)) +# endif +#else +# define ASSERT(cond, msg, file, line) ((void)0) +#endif + +// standard assert macro +#ifndef NDEBUG +# define assert(cond) ASSERT(cond, #cond, __FILE__, __LINE__) +#else +# define assert(cond) ((void)0) +#endif + +// Static/compile-time assertions + +#if defined(__GNUC__) || (__STDC_VERSION__ >= 201112L) +# define static_assert(cond, msg) _Static_assert(cond, msg) +#else +# ifndef GLUE +# define GLUE(a, b) a##b +# endif +# ifndef GLUE2 +# define GLUE2(a, b) GLUE(a, b) +# endif + +# define static_assert(cond, msg) typedef char GLUE2(static_assertion_failed, __LINE__)[(cond) ? 1 : -1] +#endif + +#endif diff --git a/include/libc/math.h b/include/libc/math.h index 2858084eba..831be6de7e 100644 --- a/include/libc/math.h +++ b/include/libc/math.h @@ -5,24 +5,37 @@ #define M_PI 3.14159265358979323846f #define M_SQRT2 1.41421356237309504880f -#define FLT_MAX 340282346638528859811704183484516925440.0f +#define MAXFLOAT 3.40282347e+38f #define SHT_MAX 32767.0f #define SHT_MINV (1.0f / SHT_MAX) -typedef union { - struct { - u32 hi; - u32 lo; - } word; +float floorf(float); +double floor(double); +long lfloorf(float); +long lfloor(double); - f64 d; -} du; +float ceilf(float); +double ceil(double); +long lceilf(float); +long lceil(double); -typedef union { - u32 i; - f32 f; -} fu; +float truncf(float); +double trunc(double); +long ltruncf(float); +long ltrunc(double); -extern f32 __libm_qnan_f; +float nearbyintf(float); +double nearbyint(double); +long lnearbyintf(float); +long lnearbyint(double); + +float roundf(float); +double round(double); +long lroundf(float); +long lround(double); + +extern float qNaN0x3FFFFF; +extern float qNaN0x10000; +extern float sNaN0x3FFFFF; #endif diff --git a/include/libc/stdarg.h b/include/libc/stdarg.h index 0744dfa609..35ce4f944e 100644 --- a/include/libc/stdarg.h +++ b/include/libc/stdarg.h @@ -1,43 +1,57 @@ #ifndef STDARG_H #define STDARG_H -// When building with GCC, use the official vaarg macros to avoid warnings -// and possibly bad codegen. +// When building with GCC, use the official vaarg macros to avoid warnings and possibly bad codegen. + #ifdef __GNUC__ -#define va_list __builtin_va_list + +#define va_list __builtin_va_list #define va_start __builtin_va_start -#define va_arg __builtin_va_arg -#define va_end __builtin_va_end +#define va_arg __builtin_va_arg +#define va_end __builtin_va_end + #else +#ifndef _VA_LIST_ +# define _VA_LIST_ typedef char* va_list; -#define _FP 1 -#define _INT 0 +#endif + +#define _INT 0 +#define _FP 1 #define _STRUCT 2 #define _VA_FP_SAVE_AREA 0x10 -#define _VA_ALIGN(p, a) (((u32)(((char*)p) + ((a) > 4 ? (a) : 4) - 1)) & -((a) > 4 ? (a) : 4)) -#define va_start(vp, parmN) (vp = ((va_list)&parmN + sizeof(parmN))) -#define __va_stack_arg(list, mode) \ - ( \ - ((list) = (char*)_VA_ALIGN(list, __builtin_alignof(mode)) + \ - _VA_ALIGN(sizeof(mode), 4)), \ - (((char*)list) - (_VA_ALIGN(sizeof(mode), 4) - sizeof(mode)))) +#define _VA_ALIGN(p, a) (((unsigned int)(((char*)p) + ((a) > 4 ? (a) : 4) - 1)) & -((a) > 4 ? (a) : 4)) -#define __va_double_arg(list, mode) \ - ( \ - (((s32)list & 0x1) /* 1 byte aligned? */ \ - ? (list = (char*)((s32)list + 7), (char*)((s32)list - 6 - _VA_FP_SAVE_AREA)) \ - : (((s32)list & 0x2) /* 2 byte aligned? */ \ - ? (list = (char*)((s32)list + 10), (char*)((s32)list - 24 - _VA_FP_SAVE_AREA)) \ - : __va_stack_arg(list, mode)))) +#define va_start(list, parmN) (list = ((va_list)&parmN + sizeof(parmN))) -#define va_arg(list, mode) ((mode*)(((__builtin_classof(mode) == _FP && \ - __builtin_alignof(mode) == sizeof(f64)) \ - ? __va_double_arg(list, mode) \ - : __va_stack_arg(list, mode))))[-1] +#define __va_stack_arg(list, mode) \ + ( \ + ((list) = (char*)_VA_ALIGN(list, __builtin_alignof(mode)) + \ + _VA_ALIGN(sizeof(mode), 4)), \ + (((char*)list) - (_VA_ALIGN(sizeof(mode), 4) - sizeof(mode))) \ + ) + +#define __va_double_arg(list, mode) \ + ( \ + (((long)list & 0x1) /* 1 byte aligned? */ \ + ? (list = (char*)((long)list + 7), (char*)((long)list - 6 - _VA_FP_SAVE_AREA)) \ + : (((long)list & 0x2) /* 2 byte aligned? */ \ + ? (list = (char*)((long)list + 10), (char*)((long)list - 24 - _VA_FP_SAVE_AREA)) \ + : __va_stack_arg(list, mode))) \ + ) + +#define va_arg(list, mode) \ + ((mode*)(((__builtin_classof(mode) == _FP && \ + __builtin_alignof(mode) == sizeof(double)) \ + ? __va_double_arg(list, mode) \ + : __va_stack_arg(list, mode))))[-1] + +/* No cleanup processing is required for the end of a varargs list: */ #define va_end(__list) -#endif +#endif /* __GNUC__ */ + #endif diff --git a/include/libc/stdbool.h b/include/libc/stdbool.h index 7a0aa35433..045c90a5e9 100644 --- a/include/libc/stdbool.h +++ b/include/libc/stdbool.h @@ -5,7 +5,12 @@ #ifndef __cplusplus -#define bool u32 +#if (__STDC_VERSION__ >= 199901L) +#define bool _Bool +#else +#define bool unsigned int +#endif + #define false 0 #define true 1 diff --git a/include/libc/stddef.h b/include/libc/stddef.h index 5d4f666b49..45620895ee 100644 --- a/include/libc/stddef.h +++ b/include/libc/stddef.h @@ -3,10 +3,16 @@ #define NULL ((void*)0) +#if !defined(_SIZE_T) && !defined(_SIZE_T_) +#define _SIZE_T + +#if !defined(_MIPS_SZLONG) || (_MIPS_SZLONG == 32) +typedef unsigned int size_t; +#endif #if defined(_MIPS_SZLONG) && (_MIPS_SZLONG == 64) -typedef unsigned long size_t; -#else -typedef unsigned int size_t; +typedef unsigned long size_t; +#endif + #endif #ifdef __GNUC__ diff --git a/include/libc/stdio.h b/include/libc/stdio.h new file mode 100644 index 0000000000..ce91816145 --- /dev/null +++ b/include/libc/stdio.h @@ -0,0 +1,9 @@ +#ifndef STDIO_H +#define STDIO_H + +#include "stdarg.h" + +int sprintf(char* dst, const char* fmt, ...); +int vsprintf(char* dst, const char* fmt, va_list args); + +#endif diff --git a/include/libc/stdlib.h b/include/libc/stdlib.h index 75657d8dbd..632fd25ae3 100644 --- a/include/libc/stdlib.h +++ b/include/libc/stdlib.h @@ -1,16 +1,17 @@ #ifndef STDLIB_H #define STDLIB_H -#include "ultra64.h" - typedef struct lldiv_t { - s64 quot; - s64 rem; + long long quot; + long long rem; } lldiv_t; typedef struct ldiv_t { - s32 quot; - s32 rem; + long quot; + long rem; } ldiv_t; +ldiv_t ldiv(long num, long denom); +lldiv_t lldiv(long long num, long long denom); + #endif diff --git a/include/libc/string.h b/include/libc/string.h new file mode 100644 index 0000000000..3f9a5cee71 --- /dev/null +++ b/include/libc/string.h @@ -0,0 +1,11 @@ +#ifndef STRING_H +#define STRING_H + +#include "stddef.h" + +char* strchr(const char*, int); +size_t strlen(const char*); + +void* memcpy(void*, const void*, size_t); + +#endif diff --git a/include/macros.h b/include/macros.h index f25069118b..8514a6924e 100644 --- a/include/macros.h +++ b/include/macros.h @@ -171,14 +171,6 @@ extern struct GraphicsContext* __gfxCtx; #define VTX_T(x,y,z,s,t,cr,cg,cb,a) { { x, y, z }, 0, { s, t }, { cr, cg, cb, a } } -#ifdef NDEBUG -#define ASSERT(cond, msg, file, line) ((void)0) -#elif defined(REAL_ASSERT_MACRO) -#define ASSERT(cond, msg, file, line) ((cond) ? ((void)0) : __assert(#cond, __FILE__, __LINE__)) -#else -#define ASSERT(cond, msg, file, line) ((cond) ? ((void)0) : __assert(msg, file, line)) -#endif - #define gDPSetTileCustom(pkt, fmt, siz, width, height, pal, cms, cmt, masks, maskt, shifts, shiftt) \ do { \ gDPPipeSync(pkt); \ diff --git a/include/message_data_fmt.h b/include/message_data_fmt.h index 7ec967b503..447117d81f 100644 --- a/include/message_data_fmt.h +++ b/include/message_data_fmt.h @@ -7,7 +7,9 @@ * The strings are used in the message_data_static files themselves, as you can only concat strings with other strings */ +#ifndef GLUE #define GLUE(a, b) a##b +#endif #define STRINGIFY(s) #s #define EXPAND_AND_STRINGIFY(s) STRINGIFY(s) diff --git a/include/ultra64.h b/include/ultra64.h index 6eadfb6af4..f6460c5834 100644 --- a/include/ultra64.h +++ b/include/ultra64.h @@ -1,16 +1,21 @@ #ifndef ULTRA64_H #define ULTRA64_H -#include "ultra64/ultratypes.h" -#include "unk.h" - +#include "libc/assert.h" +#include "libc/math.h" #include "libc/stdarg.h" #include "libc/stdbool.h" #include "libc/stddef.h" #include "libc/stdint.h" +#include "libc/stdio.h" #include "libc/stdlib.h" -#include "libc/math.h" +#include "libc/string.h" +#include "ultra64/ultratypes.h" +#include "unk.h" + +#include "ultra64/libc.h" +#include "ultra64/xstdio.h" #include "ultra64/exception.h" #include "ultra64/rcp.h" #include "ultra64/thread.h" @@ -22,7 +27,6 @@ #include "ultra64/vi.h" #include "ultra64/pi.h" #include "ultra64/controller.h" -#include "ultra64/printf.h" #include "ultra64/mbi.h" #include "ultra64/pfs.h" #include "ultra64/motor.h" diff --git a/include/ultra64/gu.h b/include/ultra64/gu.h index 8fc9e0291e..429d12352e 100644 --- a/include/ultra64/gu.h +++ b/include/ultra64/gu.h @@ -1,8 +1,26 @@ #ifndef ULTRA64_GU_H #define ULTRA64_GU_H +#include "ultratypes.h" + #define GU_PI 3.1415926 #define ROUND(x) (s32)(((x) >= 0.0) ? ((x) + 0.5) : ((x) - 0.5)) +typedef union { + struct { + u32 hi; + u32 lo; + } word; + + f64 d; +} du; + +typedef union { + u32 i; + f32 f; +} fu; + +extern f32 __libm_qnan_f; + #endif diff --git a/include/ultra64/libc.h b/include/ultra64/libc.h new file mode 100644 index 0000000000..31898a9671 --- /dev/null +++ b/include/ultra64/libc.h @@ -0,0 +1,12 @@ +#ifndef ULTRA64_LIBC_H +#define ULTRA64_LIBC_H + +#include "stddef.h" + +void osSyncPrintf(const char* fmt, ...); + +void bzero(void* __s, size_t __n); +int bcmp(const void* __sl, const void* __s2, size_t __n); +void bcopy(const void* __src, void* __dest, size_t __n); + +#endif diff --git a/include/ultra64/printf.h b/include/ultra64/printf.h deleted file mode 100644 index 4f2e29730a..0000000000 --- a/include/ultra64/printf.h +++ /dev/null @@ -1,33 +0,0 @@ -#ifndef ULTRA64_PRINTF_H -#define ULTRA64_PRINTF_H - -#include "ultratypes.h" - -typedef struct { - /* 0x0 */ union { - /* 0x0 */ s64 ll; - /* 0x0 */ f64 ld; - } v; - /* 0x8 */ char* s; - /* 0xC */ s32 n0; - /* 0x10 */ s32 nz0; - /* 0x14 */ s32 n1; - /* 0x18 */ s32 nz1; - /* 0x1C */ s32 n2; - /* 0x20 */ s32 nz2; - /* 0x24 */ s32 prec; - /* 0x28 */ s32 width; - /* 0x2C */ u32 nchar; - /* 0x30 */ u32 flags; - /* 0x34 */ u8 qual; -} _Pft; // size = 0x38 - -typedef void* (*PrintCallback)(void*, const char*, u32); - -#define FLAGS_SPACE 1 -#define FLAGS_PLUS 2 -#define FLAGS_MINUS 4 -#define FLAGS_HASH 8 -#define FLAGS_ZERO 16 - -#endif diff --git a/include/ultra64/xstdio.h b/include/ultra64/xstdio.h new file mode 100644 index 0000000000..27c44a56be --- /dev/null +++ b/include/ultra64/xstdio.h @@ -0,0 +1,44 @@ +#ifndef ULTRA64_PRINTF_H +#define ULTRA64_PRINTF_H + +#include "stdarg.h" + +// IDO doesn't support long double types, improve portability for compilers supporting them +#ifdef __sgi +#define LONG_DOUBLE_TYPE double +#else +#define LONG_DOUBLE_TYPE long double +#endif + +typedef struct { + /* 0x00 */ union { + long long ll; + LONG_DOUBLE_TYPE ld; + } v; + /* 0x08 */ char* s; + /* 0x0C */ int n0; + /* 0x10 */ int nz0; + /* 0x14 */ int n1; + /* 0x18 */ int nz1; + /* 0x1C */ int n2; + /* 0x20 */ int nz2; + /* 0x24 */ int prec; + /* 0x28 */ int width; + /* 0x2C */ size_t nchar; + /* 0x30 */ unsigned int flags; + /* 0x34 */ char qual; +} _Pft; // size = 0x38 + +typedef void* (*PrintCallback)(void*, const char*, size_t); + +int _Printf(PrintCallback, void* arg, const char* fmt, va_list ap); +void _Litob(_Pft* args, char code); +void _Ldtob(_Pft* args, char code); + +#define FLAGS_SPACE (1 << 0) +#define FLAGS_PLUS (1 << 1) +#define FLAGS_MINUS (1 << 2) +#define FLAGS_HASH (1 << 3) +#define FLAGS_ZERO (1 << 4) + +#endif diff --git a/spec b/spec index f4a3bffc3e..7a02ebd18c 100644 --- a/spec +++ b/spec @@ -26,7 +26,7 @@ beginseg include "build/src/boot/mio0.o" include "build/src/boot/stackcheck.o" include "build/src/boot/logutils.o" - include "build/src/libultra/rmon/sprintf.o" + include "build/src/libultra/libc/sprintf.o" include "build/src/libultra/io/piacs.o" include "build/src/libultra/os/sendmesg.o" include "build/src/libultra/os/stopthread.o" @@ -57,7 +57,7 @@ beginseg include "build/src/libultra/os/probetlb.o" include "build/src/libultra/os/getmemsize.o" include "build/src/libultra/os/seteventmesg.o" - include "build/src/libultra/rmon/xprintf.o" + include "build/src/libultra/libc/xprintf.o" include "build/src/libultra/os/unmaptlball.o" include "build/src/libultra/io/epidma.o" include "build/src/libultra/libc/string.o" @@ -96,9 +96,9 @@ beginseg include "build/src/libultra/os/yieldthread.o" include "build/src/libultra/os/getcause.o" include "build/src/libultra/io/epirawwrite.o" - include "build/src/libultra/rmon/xlitob.o" + include "build/src/libultra/libc/xlitob.o" include "build/src/libultra/libc/ldiv.o" - include "build/src/libultra/rmon/xldtob.o" + include "build/src/libultra/libc/xldtob.o" include "build/src/boot/build.o" include "build/src/libultra/io/sirawwrite.o" include "build/src/libultra/io/vimgr.o" diff --git a/src/boot/assert.c b/src/boot/assert.c index 438432d423..fa206fc360 100644 --- a/src/boot/assert.c +++ b/src/boot/assert.c @@ -1,9 +1,9 @@ #include "global.h" -NORETURN void __assert(const char* exp, const char* file, s32 line) { +NORETURN void __assert(const char* assertion, const char* file, int line) { char msg[256]; - osSyncPrintf("Assertion failed: %s, file %s, line %d, thread %d\n", exp, file, line, osGetThreadId(NULL)); + osSyncPrintf("Assertion failed: %s, file %s, line %d, thread %d\n", assertion, file, line, osGetThreadId(NULL)); sprintf(msg, "ASSERT: %s:%d(%d)", file, line, osGetThreadId(NULL)); - Fault_AddHungupAndCrashImpl(msg, exp); + Fault_AddHungupAndCrashImpl(msg, assertion); } diff --git a/src/boot/is_debug.c b/src/boot/is_debug.c index 5e501f3af7..a47daecd2b 100644 --- a/src/boot/is_debug.c +++ b/src/boot/is_debug.c @@ -40,7 +40,7 @@ void rmonPrintf(const char* fmt, ...) { va_end(args); } -void* is_proutSyncPrintf(void* arg, const char* str, u32 count) { +void* is_proutSyncPrintf(void* arg, const char* str, size_t count) { u32 data; s32 pos; s32 start; diff --git a/src/code/code_800FCE80.c b/src/code/code_800FCE80.c index 3d73123da0..17b2bc4e57 100644 --- a/src/code/code_800FCE80.c +++ b/src/code/code_800FCE80.c @@ -1,5 +1,4 @@ #include "global.h" -#include "fp.h" s32 gUseAtanContFrac; diff --git a/src/code/fault_drawer.c b/src/code/fault_drawer.c index 121b7d29b0..181e682691 100644 --- a/src/code/fault_drawer.c +++ b/src/code/fault_drawer.c @@ -242,7 +242,7 @@ void FaultDrawer_FillScreen(void) { FaultDrawer_SetCursor(sFaultDrawer.xStart, sFaultDrawer.yStart); } -void* FaultDrawer_PrintCallback(void* arg, const char* str, u32 count) { +void* FaultDrawer_PrintCallback(void* arg, const char* str, size_t count) { for (; count != 0; count--, str++) { s32 curXStart; s32 curXEnd; diff --git a/src/code/gfxprint.c b/src/code/gfxprint.c index 7cd7a2a243..93757234d3 100644 --- a/src/code/gfxprint.c +++ b/src/code/gfxprint.c @@ -301,7 +301,7 @@ void GfxPrint_PrintString(GfxPrint* this, const char* str) { } } -void* GfxPrint_Callback(void* arg, const char* str, u32 size) { +void* GfxPrint_Callback(void* arg, const char* str, size_t size) { GfxPrint* this = arg; GfxPrint_PrintStringWithSize(this, str, sizeof(char), size); diff --git a/src/code/load.c b/src/code/load.c index 570a968d01..ac9f76d5cf 100644 --- a/src/code/load.c +++ b/src/code/load.c @@ -46,7 +46,7 @@ s32 Overlay_Load(uintptr_t vromStart, uintptr_t vromEnd, void* vramStart, void* // "Clear BSS area (% 08x-% 08x)" osSyncPrintf("BSS領域をクリアします(%08x-%08x)\n", end, end + ovlRelocs->bssSize); } - bzero((void*)end, ovlRelocs->bssSize); + bzero((void*)end, (s32)ovlRelocs->bssSize); } size = (uintptr_t)&ovlRelocs->relocations[ovlRelocs->nRelocations] - (uintptr_t)ovlRelocs; diff --git a/src/code/z_actor.c b/src/code/z_actor.c index bfae518bc5..fcb6387d54 100644 --- a/src/code/z_actor.c +++ b/src/code/z_actor.c @@ -810,7 +810,7 @@ void Actor_Init(Actor* actor, PlayState* play) { Actor_SetScale(actor, 0.01f); actor->targetMode = 3; actor->minVelocityY = -20.0f; - actor->xyzDistToPlayerSq = FLT_MAX; + actor->xyzDistToPlayerSq = MAXFLOAT; actor->naviEnemyId = NAVI_ENEMY_NONE; actor->uncullZoneForward = 1000.0f; actor->uncullZoneScale = 350.0f; @@ -1468,7 +1468,7 @@ f32 func_8002EFC0(Actor* actor, Player* player, s16 arg2) { if (player->unk_664 != NULL) { if ((yawTempAbs > 0x4000) || (actor->flags & ACTOR_FLAG_27)) { - return FLT_MAX; + return MAXFLOAT; } else { f32 ret = actor->xyzDistToPlayerSq - actor->xyzDistToPlayerSq * 0.8f * ((0x4000 - yawTempAbs) * (1.0f / 0x8000)); @@ -1478,7 +1478,7 @@ f32 func_8002EFC0(Actor* actor, Player* player, s16 arg2) { } if (yawTempAbs > 0x2AAA) { - return FLT_MAX; + return MAXFLOAT; } return actor->xyzDistToPlayerSq; @@ -1513,7 +1513,7 @@ s32 func_8002F0C8(Actor* actor, Player* player, s32 flag) { f32 dist; if ((player->unk_664 == NULL) && (abs_var > 0x2AAA)) { - dist = FLT_MAX; + dist = MAXFLOAT; } else { dist = actor->xyzDistToPlayerSq; } @@ -3067,7 +3067,7 @@ Actor* func_80032AF0(PlayState* play, ActorContext* actorCtx, Actor** actorPtr, u8* entry; D_8015BBE8 = D_8015BBEC = NULL; - D_8015BBF0 = sbgmEnemyDistSq = FLT_MAX; + D_8015BBF0 = sbgmEnemyDistSq = MAXFLOAT; D_8015BBF8 = 0x7FFFFFFF; if (!Player_InCsMode(play)) { diff --git a/src/code/z_collision_check.c b/src/code/z_collision_check.c index 6178e6efcd..bdf0078893 100644 --- a/src/code/z_collision_check.c +++ b/src/code/z_collision_check.c @@ -3227,8 +3227,6 @@ void Collider_SetTrisDim(PlayState* play, ColliderTris* collider, s32 index, Col // by the compiler between structs like TriNorm and/or Vec3f, so they don't take space in bss. static s8 sBssDummy11; static s8 sBssDummy12; -static s8 sBssDummy13; -static s8 sBssDummy14; /** * Updates the world spheres for all of the collider's JntSph elements attached to the specified limb diff --git a/src/libultra/libc/absf.c b/src/libultra/libc/absf.c index ebdbb72c08..73c99f4602 100644 --- a/src/libultra/libc/absf.c +++ b/src/libultra/libc/absf.c @@ -1,5 +1,9 @@ #include "global.h" -f32 absf(f32 a) { - return fabsf(a); +float absf(float n) { +#ifndef __GNUC__ + return fabsf(n); +#else + return __builtin_fabsf(n); +#endif } diff --git a/src/libultra/libc/ldiv.c b/src/libultra/libc/ldiv.c index 8c53d3d4cc..10edd00a0c 100644 --- a/src/libultra/libc/ldiv.c +++ b/src/libultra/libc/ldiv.c @@ -1,6 +1,6 @@ -#include "global.h" +#include "stdlib.h" -ldiv_t ldiv(s32 num, s32 denom) { +ldiv_t ldiv(long num, long denom) { ldiv_t ret; ret.quot = num / denom; @@ -13,7 +13,7 @@ ldiv_t ldiv(s32 num, s32 denom) { return ret; } -lldiv_t lldiv(s64 num, s64 denom) { +lldiv_t lldiv(long long num, long long denom) { lldiv_t ret; ret.quot = num / denom; diff --git a/src/libultra/libc/ll.c b/src/libultra/libc/ll.c index 9d87204d1e..df56fb3f33 100644 --- a/src/libultra/libc/ll.c +++ b/src/libultra/libc/ll.c @@ -1,47 +1,48 @@ -#include "global.h" +// IDO Compiler Intrinsics for 64-bit arithmetic -s64 __ull_rshift(u64 l, s64 r) { - return l >> r; +long long __ull_rshift(unsigned long long left, long long right) { + return left >> right; } -u64 __ull_rem(u64 l, u64 r) { - return l % r; +unsigned long long __ull_rem(unsigned long long left, unsigned long long right) { + return left % right; } -u64 __ull_div(u64 l, u64 r) { - return l / r; +unsigned long long __ull_div(unsigned long long left, unsigned long long right) { + return left / right; } -s64 __ll_lshift(s64 l, s64 r) { - return l << r; +long long __ll_lshift(long long left, long long right) { + return left << right; } -s64 __ll_rem(s64 l, u64 r) { - return l % r; +long long __ll_rem(long long left, unsigned long long right) { + return left % right; } -s64 __ll_div(s64 l, s64 r) { - return l / r; +long long __ll_div(long long left, long long right) { + return left / right; } -s64 __ll_mul(s64 l, s64 r) { - return l * r; +long long __ll_mul(long long left, long long right) { + return left * right; } -void __ull_divremi(u64* quotient, u64* remainder, u64 dividend, u16 divisor) { +void __ull_divremi(unsigned long long int* quotient, unsigned long long int* remainder, + unsigned long long dividend, unsigned short divisor) { *quotient = dividend / divisor; *remainder = dividend % divisor; } -s64 __ll_mod(s64 l, s64 r) { - s64 remainder = l % r; +long long __ll_mod(long long left, long long right) { + long long rem = left % right; - if (((remainder < 0) && (r > 0)) || ((remainder > 0) && (r < 0))) { - remainder += r; + if ((rem < 0 && right > 0) || (rem > 0 && right < 0)) { + rem += right; } - return remainder; + return rem; } -s64 __ll_rshift(s64 l, s64 r) { - return l >> r; +long long __ll_rshift(long long left, long long right) { + return left >> right; } diff --git a/src/libultra/libc/llcvt.c b/src/libultra/libc/llcvt.c index c88d6f04fd..02a01074d2 100644 --- a/src/libultra/libc/llcvt.c +++ b/src/libultra/libc/llcvt.c @@ -1,33 +1,33 @@ -#include "global.h" +// IDO Compiler Intrinsics for 64-bit conversion -s64 __d_to_ll(f64 d) { +long long __d_to_ll(double d) { return d; } -s64 __f_to_ll(f32 f) { +long long __f_to_ll(float f) { return f; } -u64 __d_to_ull(f64 d) { +unsigned long long __d_to_ull(double d) { return d; } -u64 __f_to_ull(f32 f) { +unsigned long long __f_to_ull(float f) { return f; } -f64 __ll_to_d(s64 l) { +double __ll_to_d(long long l) { return l; } -f32 __ll_to_f(s64 l) { +float __ll_to_f(long long l) { return l; } -f64 __ull_to_d(u64 l) { +double __ull_to_d(unsigned long long l) { return l; } -f32 __ull_to_f(u64 l) { +float __ull_to_f(unsigned long long l) { return l; } diff --git a/src/libultra/libc/sprintf.c b/src/libultra/libc/sprintf.c new file mode 100644 index 0000000000..cb80fe39a9 --- /dev/null +++ b/src/libultra/libc/sprintf.c @@ -0,0 +1,32 @@ +#include "stdarg.h" +#include "stdio.h" +#include "string.h" +#include "ultra64/xstdio.h" + +void* proutSprintf(void* dst, const char* fmt, size_t size) { + return (char*)memcpy(dst, fmt, size) + size; +} + +int vsprintf(char* dst, const char* fmt, va_list args) { + int ret = _Printf(proutSprintf, dst, fmt, args); + + if (ret > -1) { + dst[ret] = '\0'; + } + return ret; +} + +int sprintf(char* dst, const char* fmt, ...) { + int ret; + va_list args; + va_start(args, fmt); + + ret = _Printf(proutSprintf, dst, fmt, args); + if (ret > -1) { + dst[ret] = '\0'; + } + + va_end(args); + + return ret; +} diff --git a/src/libultra/libc/sqrt.c b/src/libultra/libc/sqrt.c index 0e8cc95d51..a9a4403a33 100644 --- a/src/libultra/libc/sqrt.c +++ b/src/libultra/libc/sqrt.c @@ -1,9 +1,9 @@ #include "global.h" +double sqrt(double f) { #ifndef __GNUC__ -#define __builtin_sqrt sqrt -#endif - -f64 sqrt(f64 f) { + return sqrt(f); +#else return __builtin_sqrt(f); +#endif } diff --git a/src/libultra/libc/string.c b/src/libultra/libc/string.c index 37091ab83a..87e7c4c737 100644 --- a/src/libultra/libc/string.c +++ b/src/libultra/libc/string.c @@ -1,18 +1,18 @@ -#include "global.h" +#include "string.h" -const char* strchr(const char* str, s32 ch) { - u8 c = ch; +char* strchr(const char* str, int c) { + char ch = c; - while (*str != c) { + while (*str != ch) { if (*str == 0) { return NULL; } str++; } - return str; + return (char*)str; } -u32 strlen(const char* str) { +size_t strlen(const char* str) { const char* ptr = str; while (*ptr) { @@ -21,13 +21,13 @@ u32 strlen(const char* str) { return ptr - str; } -void* memcpy(void* dst, const void* src, size_t size) { - u8* _dst = dst; - const u8* _src = src; +void* memcpy(void* dst, const void* src, size_t n) { + char* _dst = dst; + const char* _src = src; - while (size > 0) { + while (n > 0) { *_dst++ = *_src++; - size--; + n--; } return dst; } diff --git a/src/libultra/rmon/xldtob.c b/src/libultra/libc/xldtob.c similarity index 79% rename from src/libultra/rmon/xldtob.c rename to src/libultra/libc/xldtob.c index cc518a44b2..662561b4bf 100644 --- a/src/libultra/rmon/xldtob.c +++ b/src/libultra/libc/xldtob.c @@ -1,13 +1,15 @@ -#include "global.h" +#include "stdlib.h" +#include "string.h" +#include "ultra64/xstdio.h" #define BUFF_LEN 0x20 -s16 _Ldunscale(s16*, _Pft*); -void _Genld(_Pft*, u8, u8*, s16, s16); +short _Ldunscale(short*, _Pft*); +void _Genld(_Pft*, char, char*, short, short); -const f64 D_800122E0[] = { 10e0L, 10e1L, 10e3L, 10e7L, 10e15L, 10e31L, 10e63L, 10e127L, 10e255L }; +static const double pows[] = { 10e0L, 10e1L, 10e3L, 10e7L, 10e15L, 10e31L, 10e63L, 10e127L, 10e255L }; -/* float properties */ +// float properties #define _D0 0 #define _DBIAS 0x3FF #define _DLONG 1 @@ -17,7 +19,8 @@ const f64 D_800122E0[] = { 10e0L, 10e1L, 10e3L, 10e7L, 10e15L, 10e31L, 10e63L, 1 #define _FRND 1 #define _LBIAS 0x3FFE #define _LOFF 15 -/* integer properties */ + +// integer properties #define _C2 1 #define _CSIGN 1 #define _ILONG 0 @@ -31,38 +34,26 @@ const f64 D_800122E0[] = { 10e0L, 10e1L, 10e3L, 10e7L, 10e15L, 10e31L, 10e63L, 1 #define _DNAN (0x8000 | _DMAX << _DOFF | 1 << (_DOFF - 1)) #define _DSIGN 0x8000 #if _D0 == 3 -#define _D1 2 /* little-endian order */ +#define _D1 2 // little-endian order #define _D2 1 #define _D3 0 #else -#define _D1 1 /* big-endian order */ +#define _D1 1 // big-endian order #define _D2 2 #define _D3 3 #endif -void _Ldtob(_Pft* args, u8 type) { - u8 buff[BUFF_LEN]; - u8* ptr = buff; - u32 sp70; - f64 val = args->v.ld; - /* maybe struct? */ - s16 err; - s16 nsig; - s16 exp; - - s32 i; - s32 n; - f64 factor; - s32 gen; - s32 j; - s32 lo; - ldiv_t qr; - u8 drop; - s32 n2; +void _Ldtob(_Pft* args, char code) { + char buff[BUFF_LEN]; + char* ptr = buff; + LONG_DOUBLE_TYPE val = args->v.ld; + short err; + short nsig; + short exp; if (args->prec < 0) { args->prec = 6; - } else if (args->prec == 0 && (type == 'g' || type == 'G')) { + } else if (args->prec == 0 && (code == 'g' || code == 'G')) { args->prec = 1; } err = _Ldunscale(&exp, (_Pft*)args); @@ -74,16 +65,22 @@ void _Ldtob(_Pft* args, u8 type) { nsig = 0; exp = 0; } else { + int i; + int n; + double factor; + int gen; + if (val < 0) { val = -val; } - exp = exp * 30103 / 0x000186A0 - 4; + + exp = exp * 30103 / 100000 - 4; if (exp < 0) { n = (3 - exp) & ~3; exp = -n; for (i = 0; n > 0; n >>= 1, i++) { if ((n & 1) != 0) { - val *= D_800122E0[i]; + val *= pows[i]; } } } else if (exp > 0) { @@ -92,27 +89,33 @@ void _Ldtob(_Pft* args, u8 type) { for (n = exp, i = 0; n > 0; n >>= 1, i++) { if ((n & 1) != 0) { - factor *= D_800122E0[i]; + factor *= pows[i]; } } val /= factor; } - gen = ((type == 'f') ? exp + 10 : 6) + args->prec; + + gen = ((code == 'f') ? exp + 10 : 6) + args->prec; if (gen > 0x13) { gen = 0x13; } + *ptr++ = '0'; while (gen > 0 && 0 < val) { - lo = val; + int j; + int lo = val; + if ((gen -= 8) > 0) { val = (val - lo) * 1.0e8; } - ptr = ptr + 8; + ptr += 8; + for (j = 8; lo > 0 && --j >= 0;) { - qr = ldiv(lo, 10); + ldiv_t qr = ldiv(lo, 10); *--ptr = qr.rem + '0'; lo = qr.quot; } + while (--j >= 0) { ptr--; *ptr = '0'; @@ -125,11 +128,14 @@ void _Ldtob(_Pft* args, u8 type) { --gen, --exp; } - nsig = ((type == 'f') ? exp + 1 : ((type == 'e' || type == 'E') ? 1 : 0)) + args->prec; + nsig = ((code == 'f') ? exp + 1 : ((code == 'e' || code == 'E') ? 1 : 0)) + args->prec; if (gen < nsig) { nsig = gen; } if (nsig > 0) { + char drop; + int n2; + if (nsig < gen && ptr[nsig] > '4') { drop = '9'; } else { @@ -147,16 +153,16 @@ void _Ldtob(_Pft* args, u8 type) { } } } - _Genld((_Pft*)args, type, ptr, nsig, exp); + _Genld((_Pft*)args, code, ptr, nsig, exp); } -s16 _Ldunscale(s16* pex, _Pft* px) { - u16* ps = (u16*)px; - s16 xchar = (ps[_D0] & _DMASK) >> _DOFF; +short _Ldunscale(short* pex, _Pft* px) { + unsigned short* ps = (unsigned short*)px; + short xchar = (ps[_D0] & _DMASK) >> _DOFF; if (xchar == _DMAX) { /* NaN or INF */ *pex = 0; - return (s16)(ps[_D0] & _DFRAC || ps[_D1] || ps[_D2] || ps[_D3] ? NAN : INF); + return (short)(ps[_D0] & _DFRAC || ps[_D1] || ps[_D2] || ps[_D3] ? NAN : INF); } else if (0 < xchar) { ps[_D0] = (ps[_D0] & ~_DMASK) | (_DBIAS << _DOFF); *pex = xchar - (_DBIAS - 1); @@ -170,13 +176,13 @@ s16 _Ldunscale(s16* pex, _Pft* px) { } } -void _Genld(_Pft* px, u8 code, u8* p, s16 nsig, s16 xexp) { - u8 point = '.'; +void _Genld(_Pft* px, char code, char* p, short nsig, short xexp) { + const char point = '.'; if (nsig <= 0) { nsig = 1, - p = (u8*)"0"; + p = (char*)"0"; } if (code == 'f' || ((code == 'g' || code == 'G') && (-4 <= xexp) && (xexp < px->prec))) { /* 'f' format */ @@ -248,7 +254,7 @@ void _Genld(_Pft* px, u8 code, u8* p, s16 nsig, s16 xexp) { px->n1 += nsig; px->nz1 = px->prec - nsig; } - p = (u8*)&px->s[px->n1]; /* put exponent */ + p = &px->s[px->n1]; /* put exponent */ *p++ = code; if (0 <= xexp) { *p++ = '+'; @@ -264,10 +270,10 @@ void _Genld(_Pft* px, u8 code, u8* p, s16 nsig, s16 xexp) { } *p++ = xexp / 10 + '0', xexp %= 10; *p++ = xexp + '0'; - px->n2 = p - (u8*)&px->s[px->n1]; + px->n2 = p - &px->s[px->n1]; } if ((px->flags & (FLAGS_ZERO | FLAGS_MINUS)) == FLAGS_ZERO) { /* pad with leading zeros */ - s32 n = px->n0 + px->n1 + px->nz1 + px->n2 + px->nz2; + int n = px->n0 + px->n1 + px->nz1 + px->n2 + px->nz2; if (n < px->width) { px->nz0 = px->width - n; diff --git a/src/libultra/libc/xlitob.c b/src/libultra/libc/xlitob.c new file mode 100644 index 0000000000..32e769b160 --- /dev/null +++ b/src/libultra/libc/xlitob.c @@ -0,0 +1,58 @@ +#include "stdlib.h" +#include "string.h" +#include "ultra64/xstdio.h" + +#define BUFF_LEN 0x18 + +static char ldigs[] = "0123456789abcdef"; +static char udigs[] = "0123456789ABCDEF"; + +void _Litob(_Pft* args, char type) { + char buff[BUFF_LEN]; + const char* digs; + int base; + int i; + unsigned long long num; + + if (type == 'X') { + digs = udigs; + } else { + digs = ldigs; + } + + base = (type == 'o') ? 8 : ((type != 'x' && type != 'X') ? 10 : 16); + i = BUFF_LEN; + num = args->v.ll; + + if ((type == 'd' || type == 'i') && args->v.ll < 0) { + num = -num; + } + + if (num != 0 || args->prec != 0) { + buff[--i] = digs[num % base]; + } + + args->v.ll = num / base; + + while (args->v.ll > 0 && i > 0) { + lldiv_t quotrem = lldiv(args->v.ll, base); + + args->v.ll = quotrem.quot; + buff[--i] = digs[quotrem.rem]; + } + + args->n1 = BUFF_LEN - i; + + memcpy(args->s, buff + i, args->n1); + + if (args->n1 < args->prec) { + args->nz0 = args->prec - args->n1; + } + + if (args->prec < 0 && (args->flags & (FLAGS_ZERO | FLAGS_MINUS)) == FLAGS_ZERO) { + i = args->width - args->n0 - args->nz0 - args->n1; + if (i > 0) { + args->nz0 += i; + } + } +} diff --git a/src/libultra/rmon/xprintf.c b/src/libultra/libc/xprintf.c similarity index 51% rename from src/libultra/rmon/xprintf.c rename to src/libultra/libc/xprintf.c index 36fc00ad51..a838c7173f 100644 --- a/src/libultra/rmon/xprintf.c +++ b/src/libultra/libc/xprintf.c @@ -1,11 +1,19 @@ -#include "global.h" +#include "stdarg.h" +#include "stdbool.h" +#include "stdint.h" +#include "stdlib.h" +#include "string.h" +#include "ultra64/xstdio.h" -#define ATOI(i, a) \ - for (i = 0; *a >= '0' && *a <= '9'; a++) \ - if (i < 999) \ +#define isdigit(x) (((x) >= '0' && (x) <= '9')) +#define LDSIGN(x) (((unsigned short*)&(x))[0] & 0x8000) + +#define ATOI(i, a) \ + for (i = 0; isdigit(*a); a++) \ + if (i < 999) \ i = *a + i * 10 - '0'; -#define _PROUT(fmt, _size) \ +#define PUT(fmt, _size) \ if (_size > 0) { \ arg = pfn(arg, fmt, _size); \ if (arg != NULL) \ @@ -13,51 +21,57 @@ else \ return x.nchar; \ } -#define _PAD(m, src, extracond) \ - if (extracond && m > 0) { \ - s32 i; \ - s32 j; \ - for (j = m; j > 0; j -= i) { \ - if ((u32)j > 32) \ - i = 32; \ - else \ - i = j; \ - _PROUT(src, i); \ - } \ + +#define MAX_PAD ((int)sizeof(spaces) - 1) + +#define PAD(src, m) \ + if (m > 0) { \ + int i; \ + int j; \ + for (j = m; j > 0; j -= i) { \ + if ((unsigned)j > MAX_PAD) \ + i = MAX_PAD; \ + else \ + i = j; \ + PUT(src, i); \ + } \ } char spaces[] = " "; char zeroes[] = "00000000000000000000000000000000"; -void _Putfld(_Pft*, va_list*, u8, u8*); +void _Putfld(_Pft*, va_list*, char, char*); -s32 _Printf(PrintCallback pfn, void* arg, const char* fmt, va_list ap) { +int _Printf(PrintCallback pfn, void* arg, const char* fmt, va_list ap) { _Pft x; x.nchar = 0; while (true) { static const char fchar[] = " +-#0"; - static const u32 fbit[] = { FLAGS_SPACE, FLAGS_PLUS, FLAGS_MINUS, FLAGS_HASH, FLAGS_ZERO, 0 }; + static const unsigned int fbit[] = { FLAGS_SPACE, FLAGS_PLUS, FLAGS_MINUS, FLAGS_HASH, FLAGS_ZERO, 0 }; - const u8* s = (u8*)fmt; - u8 c; + const char* s = fmt; + char c; const char* t; - u8 ac[0x20]; + char ac[0x20]; while ((c = *s) != 0 && c != '%') { s++; } - _PROUT(fmt, s - (u8*)fmt); + + PUT(fmt, s - fmt); if (c == 0) { return x.nchar; } - fmt = (char*)++s; - x.flags = 0; - for (; (t = strchr(fchar, *s)) != NULL; s++) { + + fmt = ++s; + + for (x.flags = 0; (t = strchr(fchar, *s)) != NULL; s++) { x.flags |= fbit[t - fchar]; } + if (*s == '*') { - x.width = va_arg(ap, s32); + x.width = va_arg(ap, int); if (x.width < 0) { x.width = -x.width; x.flags |= FLAGS_MINUS; @@ -66,21 +80,23 @@ s32 _Printf(PrintCallback pfn, void* arg, const char* fmt, va_list ap) { } else { ATOI(x.width, s); } + if (*s != '.') { x.prec = -1; } else { s++; if (*s == '*') { - x.prec = va_arg(ap, s32); + x.prec = va_arg(ap, int); s++; } else { ATOI(x.prec, s); } } + if (strchr("hlL", *s) != NULL) { x.qual = *s++; } else { - x.qual = 0; + x.qual = '\0'; } if (x.qual == 'l' && *s == 'l') { @@ -89,38 +105,42 @@ s32 _Printf(PrintCallback pfn, void* arg, const char* fmt, va_list ap) { } _Putfld(&x, &ap, *s, ac); x.width -= x.n0 + x.nz0 + x.n1 + x.nz1 + x.n2 + x.nz2; - _PAD(x.width, spaces, !(x.flags & FLAGS_MINUS)); - _PROUT((char*)ac, x.n0); - _PAD(x.nz0, zeroes, 1); - _PROUT(x.s, x.n1); - _PAD(x.nz1, zeroes, 1); - _PROUT((char*)(&x.s[x.n1]), x.n2) - _PAD(x.nz2, zeroes, 1); - _PAD(x.width, spaces, x.flags & FLAGS_MINUS); - fmt = (char*)s + 1; + if (!(x.flags & FLAGS_MINUS)) { + PAD(spaces, x.width); + } + PUT(ac, x.n0); + PAD(zeroes, x.nz0); + PUT(x.s, x.n1); + PAD(zeroes, x.nz1); + PUT(&x.s[x.n1], x.n2) + PAD(zeroes, x.nz2); + if (x.flags & FLAGS_MINUS) { + PAD(spaces, x.width); + } + fmt = s + 1; } } -void _Putfld(_Pft* px, va_list* pap, u8 code, u8* ac) { +void _Putfld(_Pft* px, va_list* pap, char code, char* ac) { px->n0 = px->nz0 = px->n1 = px->nz1 = px->n2 = px->nz2 = 0; switch (code) { case 'c': - ac[px->n0++] = va_arg(*pap, u32); + ac[px->n0++] = va_arg(*pap, unsigned int); break; case 'd': case 'i': if (px->qual == 'l') { - px->v.ll = va_arg(*pap, s32); + px->v.ll = va_arg(*pap, long); } else if (px->qual == 'L') { - px->v.ll = va_arg(*pap, s64); + px->v.ll = va_arg(*pap, long long); } else { - px->v.ll = va_arg(*pap, s32); + px->v.ll = va_arg(*pap, int); } if (px->qual == 'h') { - px->v.ll = (s16)px->v.ll; + px->v.ll = (short)px->v.ll; } if (px->v.ll < 0) { @@ -131,75 +151,76 @@ void _Putfld(_Pft* px, va_list* pap, u8 code, u8* ac) { ac[px->n0++] = ' '; } - px->s = (char*)&ac[px->n0]; + px->s = &ac[px->n0]; _Litob(px, code); break; + case 'x': case 'X': case 'u': case 'o': if (px->qual == 'l') { - px->v.ll = va_arg(*pap, s32); + px->v.ll = va_arg(*pap, long); } else if (px->qual == 'L') { - px->v.ll = va_arg(*pap, s64); + px->v.ll = va_arg(*pap, long long); } else { - px->v.ll = va_arg(*pap, s32); + px->v.ll = va_arg(*pap, int); } if (px->qual == 'h') { - px->v.ll = (u16)px->v.ll; - } else if (px->qual == 0) { - px->v.ll = (u32)px->v.ll; + px->v.ll = (unsigned short)px->v.ll; + } else if (px->qual == '\0') { + px->v.ll = (unsigned int)px->v.ll; } if (px->flags & FLAGS_HASH) { ac[px->n0++] = '0'; if (code == 'x' || code == 'X') { - ac[px->n0++] = code; } } - px->s = (char*)&ac[px->n0]; + px->s = &ac[px->n0]; _Litob(px, code); break; + case 'e': case 'f': case 'g': case 'E': case 'G': - px->v.ld = px->qual == 'L' ? va_arg(*pap, f64) : va_arg(*pap, f64); + px->v.ld = px->qual == 'L' ? va_arg(*pap, LONG_DOUBLE_TYPE) : va_arg(*pap, double); - if (*(u16*)&px->v.ll & 0x8000) { + if (LDSIGN(px->v.ld)) { ac[px->n0++] = '-'; - } else { - if (px->flags & FLAGS_PLUS) { - ac[px->n0++] = '+'; - } else if (px->flags & FLAGS_SPACE) { - ac[px->n0++] = ' '; - } + } else if (px->flags & FLAGS_PLUS) { + ac[px->n0++] = '+'; + } else if (px->flags & FLAGS_SPACE) { + ac[px->n0++] = ' '; } - px->s = (char*)&ac[px->n0]; + px->s = &ac[px->n0]; _Ldtob(px, code); break; + case 'n': if (px->qual == 'h') { - *(va_arg(*pap, u16*)) = px->nchar; + *(va_arg(*pap, unsigned short*)) = px->nchar; } else if (px->qual == 'l') { - *va_arg(*pap, u32*) = px->nchar; + *va_arg(*pap, unsigned long*) = px->nchar; } else if (px->qual == 'L') { - *va_arg(*pap, u64*) = px->nchar; + *va_arg(*pap, unsigned long long*) = px->nchar; } else { - *va_arg(*pap, u32*) = px->nchar; + *va_arg(*pap, unsigned int*) = px->nchar; } break; case 'p': - px->v.ll = (s32)va_arg(*pap, void*); - px->s = (char*)&ac[px->n0]; + px->v.ll = (intptr_t)va_arg(*pap, void*); + px->s = &ac[px->n0]; _Litob(px, 'x'); break; + case 's': px->s = va_arg(*pap, char*); px->n1 = strlen(px->s); @@ -207,9 +228,11 @@ void _Putfld(_Pft* px, va_list* pap, u8 code, u8* ac) { px->n1 = px->prec; } break; + case '%': ac[px->n0++] = '%'; break; + default: ac[px->n0++] = code; break; diff --git a/src/libultra/rmon/sprintf.c b/src/libultra/rmon/sprintf.c deleted file mode 100644 index a149a1eafa..0000000000 --- a/src/libultra/rmon/sprintf.c +++ /dev/null @@ -1,28 +0,0 @@ -#include "global.h" - -void* proutSprintf(void* dst, const char* fmt, u32 size) { - return (void*)((u32)memcpy(dst, fmt, size) + size); -} - -s32 vsprintf(char* dst, const char* fmt, va_list args) { - s32 ret = _Printf(proutSprintf, dst, fmt, args); - if (ret > -1) { - dst[ret] = '\0'; - } - return ret; -} - -s32 sprintf(char* dst, const char* fmt, ...) { - s32 ret; - va_list args; - va_start(args, fmt); - - ret = _Printf(proutSprintf, dst, fmt, args); - if (ret > -1) { - dst[ret] = '\0'; - } - - va_end(args); - - return ret; -} diff --git a/src/libultra/rmon/xlitob.c b/src/libultra/rmon/xlitob.c deleted file mode 100644 index 2f8152a109..0000000000 --- a/src/libultra/rmon/xlitob.c +++ /dev/null @@ -1,56 +0,0 @@ -#include "global.h" - -#define BUFF_LEN 0x18 - -u8 D_8000AF70[] = "0123456789abcdef"; -u8 D_8000AF84[] = "0123456789ABCDEF"; - -void _Litob(_Pft* args, u8 type) { - u8 buff[BUFF_LEN]; - const u8* numMap; - s32 base; - s32 idx; - u64 num; - lldiv_t quotrem; - - if (type == 'X') { - numMap = D_8000AF84; - } else { - numMap = D_8000AF70; - } - - base = (type == 'o') ? 8 : ((type != 'x' && type != 'X') ? 10 : 16); - idx = BUFF_LEN; - num = args->v.ll; - - if ((type == 'd' || type == 'i') && args->v.ll < 0) { - num = -num; - } - - if (num != 0 || args->prec != 0) { - buff[--idx] = numMap[num % base]; - } - - args->v.ll = num / base; - - while (args->v.ll > 0 && idx > 0) { - quotrem = lldiv(args->v.ll, base); - args->v.ll = quotrem.quot; - buff[--idx] = numMap[quotrem.rem]; - } - - args->n1 = BUFF_LEN - idx; - - memcpy(args->s, buff + idx, args->n1); - - if (args->n1 < args->prec) { - args->nz0 = args->prec - args->n1; - } - - if (args->prec < 0 && (args->flags & (FLAGS_ZERO | FLAGS_MINUS)) == FLAGS_ZERO) { - idx = args->width - args->n0 - args->nz0 - args->n1; - if (idx > 0) { - args->nz0 += idx; - } - } -} diff --git a/src/overlays/actors/ovl_Door_Gerudo/z_door_gerudo.c b/src/overlays/actors/ovl_Door_Gerudo/z_door_gerudo.c index f3f92488de..f5c8ede1c8 100644 --- a/src/overlays/actors/ovl_Door_Gerudo/z_door_gerudo.c +++ b/src/overlays/actors/ovl_Door_Gerudo/z_door_gerudo.c @@ -70,7 +70,7 @@ f32 func_809946BC(PlayState* play, DoorGerudo* this, f32 arg2, f32 arg3, f32 arg func_8002DBD0(&this->dyna.actor, &sp1C, &playerPos); if ((arg3 < fabsf(sp1C.x)) || (arg4 < fabsf(sp1C.y))) { - return FLT_MAX; + return MAXFLOAT; } else { return sp1C.z; } diff --git a/src/overlays/actors/ovl_Door_Shutter/z_door_shutter.c b/src/overlays/actors/ovl_Door_Shutter/z_door_shutter.c index 67372227bb..8171d34fe1 100644 --- a/src/overlays/actors/ovl_Door_Shutter/z_door_shutter.c +++ b/src/overlays/actors/ovl_Door_Shutter/z_door_shutter.c @@ -511,7 +511,7 @@ f32 DoorShutter_GetPlayerDistance(PlayState* play, DoorShutter* this, f32 offset func_8002DBD0(&this->dyna.actor, &relPlayerPos, &playerPos); if (fabsf(relPlayerPos.x) > maxDistSides || fabsf(relPlayerPos.y) > maxDistY) { - return FLT_MAX; + return MAXFLOAT; } else { return relPlayerPos.z; } diff --git a/src/overlays/actors/ovl_player_actor/z_player.c b/src/overlays/actors/ovl_player_actor/z_player.c index 1655eeea52..2ed5e048ac 100644 --- a/src/overlays/actors/ovl_player_actor/z_player.c +++ b/src/overlays/actors/ovl_player_actor/z_player.c @@ -11214,7 +11214,7 @@ void Player_UpdateCommon(Player* this, PlayState* play, Input* input) { this->targetActorDistance = 0.0f; } else { this->targetActor = NULL; - this->targetActorDistance = FLT_MAX; + this->targetActorDistance = MAXFLOAT; this->exchangeItemId = EXCH_ITEM_NONE; } @@ -11234,7 +11234,7 @@ void Player_UpdateCommon(Player* this, PlayState* play, Input* input) { } this->stateFlags2 &= ~PLAYER_STATE2_23; - this->closestSecretDistSq = FLT_MAX; + this->closestSecretDistSq = MAXFLOAT; temp_f0 = this->actor.world.pos.y - this->actor.prevPos.y;