Implement drawlist updating for increasing y
This commit is contained in:
parent
9325563991
commit
f3c9d6ac30
92
game/main.c
92
game/main.c
@ -87,6 +87,15 @@ typedef enum {
|
||||
ENTITY_OBJ,
|
||||
} entitytag_t;
|
||||
|
||||
/*
|
||||
* Common entity header -- this must be at the start of each type of
|
||||
* entity structure.
|
||||
*
|
||||
* The tag is used to distinguish different types of entity when
|
||||
* accessing them through the drawlist. The prev and next pointers
|
||||
* allow the drawlist to be threaded through all entities as a
|
||||
* doubly-linked list.
|
||||
*/
|
||||
typedef struct entity {
|
||||
entitytag_t tag;
|
||||
struct entity *prev;
|
||||
@ -559,6 +568,87 @@ static inline bool tile_passable(const map_t map, int x, int y)
|
||||
return true;
|
||||
}
|
||||
|
||||
static inline int dynentity_bottom(dynentity_t *e)
|
||||
{
|
||||
return e->pos.y + e->ext.y / 2;
|
||||
}
|
||||
|
||||
static inline int objentity_bottom(objentity_t *e)
|
||||
{
|
||||
return e->pos.y;
|
||||
}
|
||||
|
||||
static inline int entity_bottom(entity_t *e)
|
||||
{
|
||||
switch (e->tag) {
|
||||
case ENTITY_DYN:
|
||||
return dynentity_bottom((dynentity_t *)e);
|
||||
case ENTITY_OBJ:
|
||||
return objentity_bottom((objentity_t *)e);
|
||||
}
|
||||
}
|
||||
|
||||
static void update_drawlist(dynentity_t *e, entity_t **drawlist)
|
||||
{
|
||||
if (e->dir.y == 0)
|
||||
return;
|
||||
|
||||
if (e->dir.y > 0) {
|
||||
// The entity moved down -- check if it needs to be moved
|
||||
// along in the drawlist.
|
||||
|
||||
entity_t *n = e->e.next;
|
||||
if (n == NULL)
|
||||
// The entity is already at the end -- no update required.
|
||||
return;
|
||||
|
||||
const int y = dynentity_bottom(e);
|
||||
int nexty = entity_bottom(n);
|
||||
if (y <= nexty)
|
||||
// The entity is still behind the next entity -- no update
|
||||
// required.
|
||||
return;
|
||||
|
||||
// Update required -- find the earliest entity that is in
|
||||
// front of e, or the end of the list.
|
||||
while (n->next != NULL && y > nexty) {
|
||||
n = n->next;
|
||||
nexty = entity_bottom(n);
|
||||
}
|
||||
assert(n != NULL);
|
||||
|
||||
if (y > nexty) {
|
||||
// The end of the list was reached without finding a
|
||||
// larger or equal y -- move the entity to the end of the
|
||||
// list (after n).
|
||||
e->e.prev->next = e->e.next;
|
||||
e->e.next->prev = e->e.prev;
|
||||
|
||||
e->e.prev = n;
|
||||
e->e.next = NULL;
|
||||
n->next = (entity_t *)e;
|
||||
} else {
|
||||
// An entity with greater or equal y was found -- move the
|
||||
// entity to just before n.
|
||||
|
||||
if (e->e.prev == NULL) {
|
||||
// The entity is at the beginning of the list, we need
|
||||
// to update the drawlist pointer.
|
||||
*drawlist = e->e.next;
|
||||
e->e.next->prev = NULL;
|
||||
} else {
|
||||
e->e.prev->next = e->e.next;
|
||||
e->e.next->prev = e->e.prev;
|
||||
}
|
||||
|
||||
e->e.prev = n->prev;
|
||||
e->e.next = n;
|
||||
n->prev->next = (entity_t *)e;
|
||||
n->prev = (entity_t *)e;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void update_dynentity(gamestate_t *state, dynentity_t *e, double dt)
|
||||
{
|
||||
if (0 == e->speed) {
|
||||
@ -602,6 +692,8 @@ static void update_dynentity(gamestate_t *state, dynentity_t *e, double dt)
|
||||
if (valid) {
|
||||
e->pos.x = nextx;
|
||||
e->pos.y = nexty;
|
||||
|
||||
update_drawlist(e);
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user