diff options
author | Juan J. Martinez <jjm@usebox.net> | 2023-07-10 23:06:59 +0100 |
---|---|---|
committer | Juan J. Martinez <jjm@usebox.net> | 2023-07-10 23:06:59 +0100 |
commit | 1ae6a63f79edd72aa39c7f7e2bca5182a68592b4 (patch) | |
tree | 5c928964bd367019bdbd76db27841211680f7f0d /src/entities.c | |
parent | acb17f540cd8bc3a1e50ae4ab22b97620b55673b (diff) | |
download | gold-mine-run-1ae6a63f79edd72aa39c7f7e2bca5182a68592b4.tar.gz gold-mine-run-1ae6a63f79edd72aa39c7f7e2bca5182a68592b4.zip |
Draw entities in order
This makes a difference on the less powerful machines and helps avoiding
flickering.
Diffstat (limited to 'src/entities.c')
-rw-r--r-- | src/entities.c | 86 |
1 files changed, 63 insertions, 23 deletions
diff --git a/src/entities.c b/src/entities.c index b2ee7fd..65c0bfd 100644 --- a/src/entities.c +++ b/src/entities.c @@ -1,10 +1,12 @@ #include <stdint.h> #include <string.h> +#include <stdlib.h> #include "vga.h" #include "map.h" #include "data.h" #include "entities.h" +#include "player.h" #include "effect.h" @@ -13,20 +15,28 @@ static Entity entities[MAX_ENTITY]; static uint8_t last; +static uint8_t sort_cnt; +static Entity *sort[MAX_ENTITY + 1]; +static Entity player_ent; + void entities_init() { memset(entities, 0, sizeof(Entity) * MAX_ENTITY); last = 0; + + memset(&player_ent, 0, sizeof(Entity)); + player_ent.used = USED_PLAYER; + sort_cnt = 0; } Entity *entities_new() { for (uint8_t i = 0; i < MAX_ENTITY; i++) { - if (entities[i].used == 0) + if (entities[i].used == USED_FREE) { memset(&entities[i], 0, sizeof(Entity)); - entities[i].used = 1; + entities[i].used = USED_FG; if (i >= last) last = i + 1; @@ -40,40 +50,70 @@ Entity *entities_new() void entities_update() { - Entity *e = entities; - - for (uint8_t i = 0; i < last; i++, e++) - if (e->used) + for (uint8_t i = 0; i < last; i++) + if (entities[i].used) { - e->ox = e->x; - e->oy = e->y; - e->update(e); + entities[i].ox = entities[i].x; + entities[i].oy = entities[i].y; + entities[i].update(&entities[i]); } } +static int cmp_entities(const void *a, const void *b) +{ + const Entity *ea = (const Entity *) a; + const Entity *eb = (const Entity *) b; + + return (ea->y << ea->used) - (eb->y << eb->used); +} + +void entities_sort() +{ + sort_cnt = 0; + + for (uint8_t i = 0; i < last; i++) + if (entities[i].used) + sort[sort_cnt++] = &entities[i]; + + player_ent.y = player_y(); + sort[sort_cnt++] = &player_ent; + + qsort(sort, sort_cnt, sizeof(Entity *), cmp_entities); +} + void entities_draw() { Rect dst = { 0, 0, 16, 16 }; - Entity *e = entities; - for (uint8_t i = 0; i < last; i++, e++) - if (e->erase) + player_erase(); + + for (uint8_t i = 0; i < last; i++) + { + if (entities[i].erase) { - dst.x = e->ox; - dst.y = e->oy + MAP_OFFS_Y; + dst.x = entities[i].ox; + dst.y = entities[i].oy + MAP_OFFS_Y; blit_copy16(&dst); - e->erase = 0; + entities[i].erase = 0; } + } - e = entities; - - for (uint8_t i = 0; i < last; i++, e++) - if (e->used) + /* draw in order to avoid flickering */ + for (uint8_t i = 0; i < sort_cnt; i++) + switch (sort[i]->used) { - dst.x = e->x; - dst.y = e->y + MAP_OFFS_Y; - blitrc(binary_sprites_start, &e->frames[e->dir * 4 + e->frame], &dst); - e->erase = 1; + case USED_FREE: + break; + case USED_FG: + case USED_BG: + dst.x = sort[i]->x; + dst.y = sort[i]->y + MAP_OFFS_Y; + blitrc(binary_sprites_start, &sort[i]->frames[sort[i]->dir * 4 + sort[i]->frame], &dst); + sort[i]->erase = 1; + break; + case USED_PLAYER: + player_draw(); + break; } } |