diff --git a/memory.c b/memory.c index 4777157..c90eb47 100644 --- a/memory.c +++ b/memory.c @@ -1,38 +1,14 @@ #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; +char *nextprim; +char *primbuf_bounds; u_char* const scratchpad = (char*)0x1F800000; -void *mem_scratch(char **scratch_offset, unsigned short size) -{ -#if _DEBUG - if (*scratch_offset + size > scratchpad + 1024) - return NULL; -#endif - - void *result = *scratch_offset; - *scratch_offset += size; - return result; -} - void mem_prim_reset(int db) { - nextpri = primbuff[db]; - primbuff_bounds = nextpri + PRIMBUFLEN; -} - -void *mem_prim(size_t size) -{ - if (nextpri + size > primbuff_bounds) - return NULL; // TODO: report error - - void *prim = nextpri; - nextpri += size; - return prim; + nextprim = primbuff[db]; + primbuf_bounds = nextprim + PRIMBUFLEN; } diff --git a/memory.h b/memory.h index 4b03443..820c6d1 100644 --- a/memory.h +++ b/memory.h @@ -1,16 +1,12 @@ #ifndef __MEMORY_H__ #define __MEMORY_H__ -extern u_char* const scratchpad; // Starting address of scratchpad memory +#define SCRATCHLEN 1024 +extern u_char* const scratchpad; // Starting address of scratchpad memory, i.e. the 1kB of data cache usable as fast RAM -/** - * @brief Allocate memory in the fast scratchpad RAM buffer. - * - * @param scratch_offset Pointer to a variable holding the current offset position in scratch memory. - * @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. - */ -void *mem_scratch(char **scratch_offset, unsigned short size); +#define PRIMBUFLEN 65536 // TODO: reduce this to what's needed for a typical scene +extern char *nextprim; +extern char *primbuf_bounds; /** * @brief Allocate a single primitive in the primitive buffer. @@ -18,7 +14,24 @@ void *mem_scratch(char **scratch_offset, unsigned short size); * @param size Size of the primitive struct to allocate. * @return Pointer to the allocated struct in memory. */ -void *mem_prim(size_t size); +INLINE void *mem_prim(size_t size) +{ + void *prim = nextprim; + nextprim += size; + return prim; +} + +/** + * @brief Check if it's safe to allocate the given number of primitives of the given size. + * + * @param size The size of each primitive to allocate. + * @param count The number of primitives to allocate. + * @return Whether the number of primitives can be allocated without exceeding the primitive buffer bounds. + */ +INLINE char mem_checkprim(size_t size, u_short count) +{ + return nextprim + size * count < primbuf_bounds; +} void mem_prim_reset(int db); diff --git a/world.c b/world.c index 0386c0f..379a1c5 100644 --- a/world.c +++ b/world.c @@ -53,6 +53,9 @@ static INLINE void drawface_triangle_fan(const ps1bsp_face_t *face, SVECTOR *vec { int p; + if (!mem_checkprim(sizeof(POLY_G3), face->numFaceVertices)) + return; + // Draw the face as a triangle fan u_char maxVert = face->numFaceVertices - 1; for (int vertIdx = 1; vertIdx < maxVert; ++vertIdx) @@ -74,9 +77,6 @@ static INLINE void drawface_triangle_fan(const ps1bsp_face_t *face, SVECTOR *vec // Draw a flat-shaded untextured colored triangle POLY_G3 *poly = (POLY_G3*)mem_prim(sizeof(POLY_G3)); - if (poly == NULL) - break; - setPolyG3(poly); gte_stsxy3_g3(poly); @@ -93,6 +93,9 @@ static INLINE void drawface_triangle_strip(const ps1bsp_face_t *face, SVECTOR *v { int p; + if (!mem_checkprim(sizeof(POLY_G3), face->numFaceVertices)) + return; + // Draw the face as a triangle strip const SVECTOR *v0, *v1, *v2; const SVECTOR *head = vecs; @@ -130,9 +133,6 @@ static INLINE void drawface_triangle_strip(const ps1bsp_face_t *face, SVECTOR *v // Draw a flat-shaded untextured colored triangle POLY_G3 *poly = (POLY_G3*)mem_prim(sizeof(POLY_G3)); - if (poly == NULL) - break; - setPolyG3(poly); gte_stsxy3_g3(poly); @@ -149,6 +149,9 @@ static INLINE void drawface_quad_strip(const ps1bsp_face_t *face, SVECTOR *vecs) { int p; + if (!mem_checkprim(sizeof(POLY_G4), face->numFaceVertices)) + return; + // Draw the face as a quad strip const SVECTOR *v0, *v1, *v2, *v3; const SVECTOR *head = vecs; @@ -180,9 +183,6 @@ static INLINE void drawface_quad_strip(const ps1bsp_face_t *face, SVECTOR *vecs) // Draw a flat-shaded untextured colored quad POLY_G4 *poly = (POLY_G4*)mem_prim(sizeof(POLY_G4)); - if (poly == NULL) - break; - setPolyG4(poly); gte_stsxy0(&poly->x0); gte_stsxy1(&poly->x1);