#include #include #include #include "vga.h" #include "map.h" #include "data.h" #include "entities.h" #include "player.h" #include "effect.h" #define MAX_ENTITY 16 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 == USED_FREE) { memset(&entities[i], 0, sizeof(Entity)); entities[i].used = USED_FG; if (i >= last) last = i + 1; return &entities[i]; } } return NULL; } void entities_update() { for (uint8_t i = 0; i < last; i++) if (entities[i].used) { 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 }; player_erase(); for (uint8_t i = 0; i < last; i++) { if (entities[i].erase) { dst.x = entities[i].ox; dst.y = entities[i].oy + MAP_OFFS_Y; blit_copy16(&dst); entities[i].erase = 0; } } /* draw in order to avoid flickering */ for (uint8_t i = 0; i < sort_cnt; i++) switch (sort[i]->used) { 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; } } void entities_warp_out_all() { Entity *e = entities; for (uint8_t i = 0; i < last; i++, e++) if (e->used) effect_out_init(e); }