From 56dbf9dbb423dc70839c353f63355df56b27a32d Mon Sep 17 00:00:00 2001 From: Camden Dixie O'Brien Date: Sat, 4 Jan 2025 09:26:42 +0000 Subject: [PATCH] Construct drawlist at end of game_init() --- game/main.c | 77 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 77 insertions(+) diff --git a/game/main.c b/game/main.c index a033d6e..5cdf643 100644 --- a/game/main.c +++ b/game/main.c @@ -51,6 +51,9 @@ #define MAXOBJTYPES 8 #define INITOBJCOLCAP 16 +#define MAXENTITIES 32 + +#define QSORT_STACKSIZE 64 #define NELEMS(a) (sizeof(a) / sizeof(a[0])) @@ -128,8 +131,14 @@ typedef struct { objtype_t objtypes[MAXOBJTYPES]; objcol_t objcol; dynentity_t p; + entity_t *drawlist; } gamestate_t; +typedef struct { + int y; + entity_t *e; +} y_entity_ref_t; + const engineconf_t game_conf = { .win = { .title = "2D Game", @@ -339,6 +348,72 @@ load_map(gamestate_t *state, const char *path, SDL_Renderer *renderer) xmlFreeDoc(doc); } +static void y_entity_ref_swap(y_entity_ref_t *a, y_entity_ref_t *b) +{ + y_entity_ref_t tmp = *a; + *a = *b; + *b = tmp; +} + +void init_drawlist(gamestate_t *state) +{ + y_entity_ref_t buf[MAXENTITIES]; + int n = 0; + + // Populate buffer with player and objects + buf[n].y = (int)rint(state->p.pos.y) + state->p.ext.y / 2; + buf[n++].e = (entity_t *)&state->p; + for (unsigned i = 0; i < state->objcol.n; ++i) { + assert(n < MAXENTITIES); + objentity_t *obj = state->objcol.buf + i; + buf[n].y = obj->pos.y; + buf[n++].e = (entity_t *)obj; + } + + // Quicksort on y value + int stack[QSORT_STACKSIZE], *sp = stack; + int l = 0, h = n; + assert(n != 0); + while (1) { + int pivot = buf[l].y; + int i = l, j = h; + do { + for (++i; buf[i].y <= pivot; ++i) + ; + for (--j; buf[j].y > pivot; --j) + ; + if (i < j) + y_entity_ref_swap(buf + i, buf + j); + } while (i < j); + y_entity_ref_swap(buf + l, buf + j); + assert(sp + 2 <= stack + QSORT_STACKSIZE); + if (j + 2 < h) { + *sp++ = j + 1; + *sp++ = h; + } + if (l + 1 < j) { + h = j; + } else if (sp != stack) { + h = *(--sp); + l = *(--sp); + } else { + break; + } + } + + // Set up drawlist from buffer + state->drawlist = buf[0].e; + int i = 0; + buf[i].e->prev = NULL; + buf[i].e->next = buf[i + 1].e; + for (++i; i < n - 1; ++i) { + buf[i].e->prev = buf[i - 1].e; + buf[i].e->next = buf[i + 1].e; + } + buf[i].e->prev = buf[i - 1].e; + buf[i].e->next = NULL; +} + void game_init(int argc, char *argv[], void *mem, SDL_Renderer *renderer) { char path[MAX_PATH_LEN]; @@ -389,6 +464,8 @@ void game_init(int argc, char *argv[], void *mem, SDL_Renderer *renderer) state->p.ext.x = PWIDTH; state->p.ext.y = PHEIGHT; state->p.tex = state->pidle; + + init_drawlist(state); } void game_teardown(void *mem)