diff --git a/common.h b/common.h index 3bdbc3c..8470319 100644 --- a/common.h +++ b/common.h @@ -8,6 +8,7 @@ #include #include +#include "memory.h" #include "qmath.h" extern VECTOR cam_pos; diff --git a/display.c b/display.c index c101479..9d55a46 100644 --- a/display.c +++ b/display.c @@ -8,13 +8,7 @@ static DISPENV disp[2]; static DRAWENV draw[2]; static int db; -#define PRIMBUFLEN 131072 - static u_long ot[2][OTLEN]; // Ordering tables, two arrays for double buffering. These are basically the buckets for bucket sorting of polygons. - // You can also see them as "layers" in the modern 3D graphics sense, but they serve a more immediate role for polygon ordering. - // Layer 0 is free for overlays, as polygons at depth 0 will be clipped. -static char primbuff[2][PRIMBUFLEN]; // Primitive buffer, just a raw buffer of bytes to use as a pool for primitives -static char *nextpri; const MATRIX identity = { ONE, 0, 0, @@ -151,7 +145,7 @@ void display_start() curOT = ot[db]; ClearOTagR(curOT, OTLEN); - nextpri = primbuff[db]; + mem_prim_reset(db); gte_SetBackColor(48, 48, 48); // Ambient light color gte_SetColorMatrix(&light_cols); // Light color (up to three different lights) @@ -192,13 +186,3 @@ void display_finish() DrawOTag(curOT + OTLEN - 1); // This performs a DMA transfer to quickly send all the primitives off to the GPU } - -void *display_allocPrim(size_t size) -{ - if (nextpri + size > primbuff[db] + PRIMBUFLEN) - return NULL; - - void *prim = nextpri; - nextpri += size; - return prim; -} diff --git a/memory.c b/memory.c new file mode 100644 index 0000000..2e1ac8c --- /dev/null +++ b/memory.c @@ -0,0 +1,46 @@ +#include "common.h" +#include "memory.h" + +#define PRIMBUFLEN 131072 // TODO: optimize this for a typical scene + +static char primbuff[2][PRIMBUFLEN]; // Primitive buffer, just a raw buffer of bytes to use as a pool for primitives +static char *nextpri; +static char *primbuff_bounds; + +static char* const scratch_start = (char*)0x1F800000; +static char *scratch = scratch_start; + +void mem_scratch_reset() +{ + scratch = scratch_start; +} + +char *mem_scratch(unsigned short size) +{ +#if _DEBUG + if (scratch + size > scratch_start + 1024) + return NULL; +#endif + + char *result = scratch; + scratch += size; + return result; +} + +void mem_prim_reset(int db) +{ + nextpri = primbuff[db]; + primbuff_bounds = nextpri + PRIMBUFLEN; +} + +void *mem_prim(size_t size) +{ +#if _DEBUG + if (nextpri + size > primbuff_bounds) + return NULL; // TODO: report error +#endif + + void *prim = nextpri; + nextpri += size; + return prim; +} diff --git a/memory.h b/memory.h new file mode 100644 index 0000000..8afcddc --- /dev/null +++ b/memory.h @@ -0,0 +1,24 @@ +#ifndef __MEMORY_H__ +#define __MEMORY_H__ + +/** + * @brief Allocate memory in the fast scratchpad RAM buffer. + * + * @param size The number of bytes to allocate. Be aware that the scratchpad memory only has 1024 bytes available. + * @return Pointer to the allocated buffer in scratchpad memory. + */ +char *mem_scratch(unsigned short size); + +void mem_scratch_reset(); + +/** + * @brief Allocate a single primitive in the primitive buffer. + * + * @param size Size of the primitive struct to allocate. + * @return Pointer to the allocated struct in memory. + */ +void *mem_prim(size_t size); + +void mem_prim_reset(int db); + +#endif // __MEMORY_H__ diff --git a/world.c b/world.c index ebc2f17..66916a9 100644 --- a/world.c +++ b/world.c @@ -89,7 +89,7 @@ void world_draw(const world_t *world) continue; // Draw a flat-shaded untextured colored triangle - POLY_F3 *poly = (POLY_F3*)display_allocPrim(sizeof(POLY_F3)); + POLY_F3 *poly = (POLY_F3*)mem_prim(sizeof(POLY_F3)); if (poly == NULL) break;