Poke_Transporter_GB/source/libstd_replacements.cpp
easyaspi314 750641c78f Prepare for trouble... and make it.... fixed point?
To protect the world from the soft float library...
To unite all arithmetic within our binary...
To denounce the evils of floating point precision...
To save more kilobytes - that's our vision....

(god this is cringe)

All floating point math has been eliminated, and replaced with
equivalent or near-equivalent fixed-point math.

sprite_data.cpp uses Q16, and get_rand_range uses a full Q32 to
ensure that the exact same results are generated as before, at
the cost of some inline assembly to do a umull (__aeabi_lmul is a
little excessive when the lower 32 bits are discarded)

This eliminates all of the expensive double precision float library,
saving a few kilobytes.

Additionally, the unneccessary parts of nanoprintf have been
disabled. There is no need for precision specifiers, long longs, or
floats.
2025-06-30 13:05:32 -04:00

67 lines
2.0 KiB
C++

#define NANOPRINTF_IMPLEMENTATION 1
// Remove what we don't need
#define NANOPRINTF_USE_FIELD_WIDTH_FORMAT_SPECIFIERS 0
#define NANOPRINTF_USE_PRECISION_FORMAT_SPECIFIERS 0
#define NANOPRINTF_USE_LARGE_FORMAT_SPECIFIERS 0
#define NANOPRINTF_USE_FLOAT_FORMAT_SPECIFIERS 0
#define NANOPRINTF_USE_BINARY_FORMAT_SPECIFIERS 0
#define NANOPRINTF_USE_WRITEBACK_FORMAT_SPECIFIERS 0
#include "libstd_replacements.h"
#include "libraries/nanoprintf/nanoprintf.h"
#include <cstdlib>
#include <stdarg.h>
#include <ctype.h>
#include "custom_malloc.h"
// recommended for a 32 bit system to have at least 33 bytes available
// source: https://cplusplus.com/reference/cstdlib/itoa/
// unfortunately itoa is not standardized, so we'll have to make do with snprintf
static char conversion_buffer[33];
const char* ptgb::to_string(int intVal)
{
npf_snprintf(conversion_buffer, sizeof(conversion_buffer), "%d", intVal);
return conversion_buffer;
}
const char* ptgb::to_string(unsigned int wordVal)
{
npf_snprintf(conversion_buffer, sizeof(conversion_buffer), "%u", wordVal);
return conversion_buffer;
}
// when compiling with -nostdlib++, we need to provide our own operator new and delete implementations
// Regular operator new
void* operator new(std::size_t size) {
void* ptr = malloc(size);
if (!ptr) {
// mimic standard behavior: throw std::bad_alloc
// but we can't use std::bad_alloc without libstdc++
// so instead we can abort or return nullptr
// You can also implement a custom exception if needed
return NULL;
}
return ptr;
}
// nothrow version
void* operator new(std::size_t size, const std::nothrow_t&) noexcept {
return malloc(size);
}
// operator delete
void operator delete(void* ptr) noexcept {
free(ptr);
}
// nothrow delete
void operator delete(void* ptr, const std::nothrow_t&) noexcept {
free(ptr);
}
// sized delete (optional, for C++14 and newer)
void operator delete(void* ptr, std::size_t size) noexcept {
(void)size;
free(ptr);
}