From ff4bd68c0b27406cdec321b2eff424fa7bc7c5a6 Mon Sep 17 00:00:00 2001 From: dwsJason Date: Thu, 20 Sep 2018 19:57:09 -0400 Subject: [PATCH] Optimize, pass entity pointer around instead of index, this avoids expensive multiplies to index into the entity array --- include/e_bomb.h | 4 +- include/e_bonus.h | 2 +- include/e_box.h | 2 +- include/e_bullet.h | 2 +- include/e_rick.h | 4 +- include/e_sbonus.h | 4 +- include/e_them.h | 10 +- include/util.h | 8 +- src/e_bomb.c | 16 +- src/e_bonus.c | 24 +-- src/e_box.c | 40 ++--- src/e_bullet.c | 2 +- src/e_rick.c | 12 +- src/e_sbonus.c | 18 +-- src/e_them.c | 368 ++++++++++++++++++++++----------------------- src/ents.c | 2 +- src/game.c | 4 +- src/util.c | 38 ++--- 18 files changed, 281 insertions(+), 279 deletions(-) diff --git a/include/e_bomb.h b/include/e_bomb.h index b959a76..cde659d 100644 --- a/include/e_bomb.h +++ b/include/e_bomb.h @@ -25,9 +25,9 @@ extern U8 e_bomb_ticker; extern U8 e_bomb_xc; extern U16 e_bomb_yc; -extern U8 e_bomb_hit(U8); +extern U8 e_bomb_hit(ent_t* pEnt); extern void e_bomb_init(U16, U16); -extern void e_bomb_action(U8); +extern void e_bomb_action(ent_t* pEnt); #endif diff --git a/include/e_bonus.h b/include/e_bonus.h index a24a3d0..e4a2f45 100644 --- a/include/e_bonus.h +++ b/include/e_bonus.h @@ -16,7 +16,7 @@ #include "system.h" -extern void e_bonus_action(U8); +extern void e_bonus_action(ent_t*); #endif diff --git a/include/e_box.h b/include/e_box.h index 07f4127..0cb1d6e 100644 --- a/include/e_box.h +++ b/include/e_box.h @@ -16,7 +16,7 @@ #include "system.h" -extern void e_box_action(U8); +extern void e_box_action(ent_t*); #endif diff --git a/include/e_bullet.h b/include/e_bullet.h index 3896486..2987e0b 100644 --- a/include/e_bullet.h +++ b/include/e_bullet.h @@ -23,7 +23,7 @@ extern S16 e_bullet_offsx; extern S16 e_bullet_xc, e_bullet_yc; extern void e_bullet_init(U16, U16); -extern void e_bullet_action(U8); +extern void e_bullet_action(ent_t*); #endif diff --git a/include/e_rick.h b/include/e_rick.h index 255a928..6455baf 100644 --- a/include/e_rick.h +++ b/include/e_rick.h @@ -36,9 +36,9 @@ extern S16 e_rick_stop_x, e_rick_stop_y; extern void e_rick_save(void); extern void e_rick_restore(void); -extern void e_rick_action(U8); +extern void e_rick_action(ent_t*); extern void e_rick_gozombie(void); -extern U8 e_rick_boxtest(U8); +extern U8 e_rick_boxtest(ent_t*); #endif diff --git a/include/e_sbonus.h b/include/e_sbonus.h index ec22035..87c5946 100644 --- a/include/e_sbonus.h +++ b/include/e_sbonus.h @@ -20,8 +20,8 @@ extern U8 e_sbonus_counting; extern U8 e_sbonus_counter; extern U16 e_sbonus_bonus; -extern void e_sbonus_start(U8); -extern void e_sbonus_stop(U8); +extern void e_sbonus_start(ent_t*); +extern void e_sbonus_stop(ent_t*); #endif diff --git a/include/e_them.h b/include/e_them.h index 72e6903..b627c9d 100644 --- a/include/e_them.h +++ b/include/e_them.h @@ -18,11 +18,11 @@ extern U32 e_them_rndseed; -extern void e_them_t1a_action(U8); -extern void e_them_t1b_action(U8); -extern void e_them_t2_action(U8); -extern void e_them_t3_action(U8); -extern void e_them_z_action(U8); +extern void e_them_t1a_action(ent_t*); +extern void e_them_t1b_action(ent_t*); +extern void e_them_t2_action(ent_t*); +extern void e_them_t3_action(ent_t*); +extern void e_them_z_action(ent_t*); #endif diff --git a/include/util.h b/include/util.h index 244eb84..fa9dc67 100644 --- a/include/util.h +++ b/include/util.h @@ -14,10 +14,12 @@ #ifndef _UTIL_H #define _UTIL_H +#include "ents.h" + extern void u_envtest(S16, S16, U8, U8 *, U8 *); -extern U8 u_boxtest(U8, U8); -extern U8 u_fboxtest(U8, S16, S16); -extern U8 u_trigbox(U8, S16, S16); +extern U8 u_boxtest(ent_t*, ent_t*); +extern U8 u_fboxtest(ent_t*, S16, S16); +extern U8 u_trigbox(ent_t* pEnt, S16, S16); #endif diff --git a/src/e_bomb.c b/src/e_bomb.c index cb8e5b8..bb3e8b7 100644 --- a/src/e_bomb.c +++ b/src/e_bomb.c @@ -41,15 +41,15 @@ U8 e_bomb_ticker; * ASM 11CD * returns: TRUE/hit, FALSE/not */ -U8 e_bomb_hit(U8 e) +U8 e_bomb_hit(ent_t *pEnt) { - if (ent_ents[e].x > (E_BOMB_ENT.x >= 0xE0 ? 0xFF : E_BOMB_ENT.x + 0x20)) + if (pEnt->x > (E_BOMB_ENT.x >= 0xE0 ? 0xFF : E_BOMB_ENT.x + 0x20)) return FALSE; - if (ent_ents[e].x + ent_ents[e].w < (E_BOMB_ENT.x > 0x04 ? E_BOMB_ENT.x - 0x04 : 0)) + if (pEnt->x + pEnt->w < (E_BOMB_ENT.x > 0x04 ? E_BOMB_ENT.x - 0x04 : 0)) return FALSE; - if (ent_ents[e].y > (E_BOMB_ENT.y + 0x1D)) + if (pEnt->y > (E_BOMB_ENT.y + 0x1D)) return FALSE; - if (ent_ents[e].y + ent_ents[e].h < (E_BOMB_ENT.y > 0x0004 ? E_BOMB_ENT.y - 0x0004 : 0)) + if (pEnt->y + pEnt->h < (E_BOMB_ENT.y > 0x0004 ? E_BOMB_ENT.y - 0x0004 : 0)) return FALSE; return TRUE; } @@ -83,7 +83,7 @@ void e_bomb_init(U16 x, U16 y) * ASM 18CA */ void -e_bomb_action(UNUSED(U8 e)) +e_bomb_action(UNUSED(ent_t* pEnt)) { /* tick */ e_bomb_ticker--; @@ -133,7 +133,7 @@ e_bomb_action(UNUSED(U8 e)) e_bomb_xc = E_BOMB_ENT.x + 0x0C; e_bomb_yc = E_BOMB_ENT.y + 0x000A; e_bomb_lethal = TRUE; - if (e_bomb_hit(E_RICK_NO)) + if (e_bomb_hit(&ent_ents[E_RICK_NO])) e_rick_gozombie(); } else @@ -148,7 +148,7 @@ e_bomb_action(UNUSED(U8 e)) E_BOMB_ENT.sprite = 0xa8 + 4 - (e_bomb_ticker >> 1); #endif /* exploding, hence lethal */ - if (e_bomb_hit(E_RICK_NO)) + if (e_bomb_hit(&ent_ents[E_RICK_NO])) e_rick_gozombie(); } } diff --git a/src/e_bonus.c b/src/e_bonus.c index 5b9a0df..84ca476 100644 --- a/src/e_bonus.c +++ b/src/e_bonus.c @@ -30,31 +30,31 @@ segment "e"; * ASM 242C */ void -e_bonus_action(U8 e) +e_bonus_action(ent_t *pEnt) { #define seq c1 - if (ent_ents[e].seq == 0) { - if (e_rick_boxtest(e)) { + if (pEnt->seq == 0) { + if (e_rick_boxtest(pEnt)) { game_score += 500; #ifdef ENABLE_SOUND syssnd_play(WAV_BONUS, 1); #endif - map_marks[ent_ents[e].mark].ent |= MAP_MARK_NACT; - ent_ents[e].seq = 1; - ent_ents[e].sprite = 0xad; - ent_ents[e].front = TRUE; - ent_ents[e].y -= 0x08; + map_marks[pEnt->mark].ent |= MAP_MARK_NACT; + pEnt->seq = 1; + pEnt->sprite = 0xad; + pEnt->front = TRUE; + pEnt->y -= 0x08; } } - else if (ent_ents[e].seq > 0 && ent_ents[e].seq < 10) { - ent_ents[e].seq++; - ent_ents[e].y -= 2; + else if (pEnt->seq > 0 && pEnt->seq < 10) { + pEnt->seq++; + pEnt->y -= 2; } else { - ent_ents[e].n = 0; + pEnt->n = 0; } } diff --git a/src/e_box.c b/src/e_box.c index 67f11ec..671bc04 100644 --- a/src/e_box.c +++ b/src/e_box.c @@ -42,7 +42,7 @@ segment "e"; /* * Prototypes */ -static void explode(U8); +static void explode(ent_t*); /* * Entity action @@ -50,49 +50,49 @@ static void explode(U8); * ASM 245A */ void -e_box_action(U8 e) +e_box_action(ent_t* pEnt) { static U8 sp[] = {0x24, 0x25, 0x26, 0x27, 0x28}; /* explosion sprites sequence */ - if (ent_ents[e].n & ENT_LETHAL) { + if (pEnt->n & ENT_LETHAL) { /* * box is lethal i.e. exploding * play sprites sequence then stop */ - ent_ents[e].sprite = sp[ent_ents[e].cnt >> 1]; - if (--ent_ents[e].cnt == 0) { - ent_ents[e].n = 0; - map_marks[ent_ents[e].mark].ent |= MAP_MARK_NACT; + pEnt->sprite = sp[pEnt->cnt >> 1]; + if (--pEnt->cnt == 0) { + pEnt->n = 0; + map_marks[pEnt->mark].ent |= MAP_MARK_NACT; } } else { /* * not lethal: check to see if triggered */ - if (e_rick_boxtest(e)) { + if (e_rick_boxtest(pEnt)) { /* rick: collect bombs or bullets and stop */ #ifdef ENABLE_SOUND syssnd_play(WAV_BOX, 1); #endif - if (ent_ents[e].n == 0x10) + if (pEnt->n == 0x10) game_bombs = GAME_BOMBS_INIT; else /* 0x11 */ game_bullets = GAME_BULLETS_INIT; - ent_ents[e].n = 0; - map_marks[ent_ents[e].mark].ent |= MAP_MARK_NACT; + pEnt->n = 0; + map_marks[pEnt->mark].ent |= MAP_MARK_NACT; } else if (E_RICK_STTST(E_RICK_STSTOP) && - u_fboxtest(e, e_rick_stop_x, e_rick_stop_y)) { + u_fboxtest(pEnt, e_rick_stop_x, e_rick_stop_y)) { /* rick's stick: explode */ - explode(e); + explode(pEnt); } - else if (E_BULLET_ENT.n && u_fboxtest(e, e_bullet_xc, e_bullet_yc)) { + else if (E_BULLET_ENT.n && u_fboxtest(pEnt, e_bullet_xc, e_bullet_yc)) { /* bullet: explode (and stop bullet) */ E_BULLET_ENT.n = 0; - explode(e); + explode(pEnt); } - else if (e_bomb_lethal && e_bomb_hit(e)) { + else if (e_bomb_lethal && e_bomb_hit(pEnt)) { /* bomb: explode */ - explode(e); + explode(pEnt); } } } @@ -101,10 +101,10 @@ e_box_action(U8 e) /* * Explode when */ -static void explode(U8 e) +static void explode(ent_t* pEnt) { - ent_ents[e].cnt = SEQ_INIT; - ent_ents[e].n |= ENT_LETHAL; + pEnt->cnt = SEQ_INIT; + pEnt->n |= ENT_LETHAL; #ifdef ENABLE_SOUND syssnd_play(WAV_EXPLODE, 1); #endif diff --git a/src/e_bullet.c b/src/e_bullet.c index 1b27823..4bf7139 100644 --- a/src/e_bullet.c +++ b/src/e_bullet.c @@ -58,7 +58,7 @@ e_bullet_init(U16 x, U16 y) * ASM 1883, 0F97 */ void -e_bullet_action(UNUSED(U8 e)) +e_bullet_action(UNUSED(ent_t* pEnt)) { /* move bullet */ E_BULLET_ENT.x += e_bullet_offsx; diff --git a/src/e_rick.c b/src/e_rick.c index 44e0c48..3734571 100644 --- a/src/e_rick.c +++ b/src/e_rick.c @@ -62,17 +62,17 @@ static U16 save_x, save_y; * ret: TRUE/intersect, FALSE/not. */ U8 -e_rick_boxtest(U8 e) +e_rick_boxtest(ent_t* pEnt) { /* * rick: x+0x05 to x+0x11, y+[0x08 if rick's crawling] to y+0x14 * entity: x to x+w, y to y+h */ - if (E_RICK_ENT.x + 0x11 < ent_ents[e].x || - E_RICK_ENT.x + 0x05 > ent_ents[e].x + ent_ents[e].w || - E_RICK_ENT.y + 0x14 < ent_ents[e].y || - E_RICK_ENT.y + (E_RICK_STTST(E_RICK_STCRAWL) ? 0x08 : 0x00) > ent_ents[e].y + ent_ents[e].h - 1) + if (E_RICK_ENT.x + 0x11 < pEnt->x || + E_RICK_ENT.x + 0x05 > pEnt->x + pEnt->w || + E_RICK_ENT.y + 0x14 < pEnt->y || + E_RICK_ENT.y + (E_RICK_STTST(E_RICK_STCRAWL) ? 0x08 : 0x00) > pEnt->y + pEnt->h - 1) return FALSE; else return TRUE; @@ -449,7 +449,7 @@ e_rick_action2(void) * * ASM 12CA */ -void e_rick_action(UNUSED(U8 e)) +void e_rick_action(UNUSED(ent_t* pEnt)) { static U8 stopped = FALSE; /* is this the most elegant way? */ diff --git a/src/e_sbonus.c b/src/e_sbonus.c index 992d018..f59b0fb 100644 --- a/src/e_sbonus.c +++ b/src/e_sbonus.c @@ -39,12 +39,12 @@ U16 e_sbonus_bonus = 0; * ASM 2182 */ void -e_sbonus_start(U8 e) +e_sbonus_start(ent_t* pEnt) { - ent_ents[e].sprite = 0; /* invisible */ - if (u_trigbox(e, ENT_XRICK.x + 0x0C, ENT_XRICK.y + 0x0A)) { + pEnt->sprite = 0; /* invisible */ + if (u_trigbox(pEnt, ENT_XRICK.x + 0x0C, ENT_XRICK.y + 0x0A)) { /* rick is within trigger box */ - ent_ents[e].n = 0; + pEnt->n = 0; e_sbonus_counting = TRUE; /* 6DD5 */ e_sbonus_counter = 0x1e; /* 6DDB */ e_sbonus_bonus = 2000; /* 291A-291D */ @@ -61,23 +61,23 @@ e_sbonus_start(U8 e) * ASM 2143 */ void -e_sbonus_stop(U8 e) +e_sbonus_stop(ent_t* pEnt) { - ent_ents[e].sprite = 0; /* invisible */ + pEnt->sprite = 0; /* invisible */ if (!e_sbonus_counting) return; - if (u_trigbox(e, ENT_XRICK.x + 0x0C, ENT_XRICK.y + 0x0A)) { + if (u_trigbox(pEnt, ENT_XRICK.x + 0x0C, ENT_XRICK.y + 0x0A)) { /* rick is within trigger box */ e_sbonus_counting = FALSE; /* stop counting */ - ent_ents[e].n = 0; /* deactivate entity */ + pEnt->n = 0; /* deactivate entity */ game_score += e_sbonus_bonus; /* add bonus to score */ #ifdef ENABLE_SOUND syssnd_play(WAV_SBONUS2, 1); #endif /* make sure the entity won't be activated again */ - map_marks[ent_ents[e].mark].ent |= MAP_MARK_NACT; + map_marks[pEnt->mark].ent |= MAP_MARK_NACT; } else { /* keep counting */ diff --git a/src/e_them.c b/src/e_them.c index a370d55..9cc4146 100644 --- a/src/e_them.c +++ b/src/e_them.c @@ -50,15 +50,15 @@ segment "e"; * ret: TRUE/boxtests, FALSE/not */ U8 -u_themtest(U8 e) +u_themtest(ent_t* pEnt) { - U8 i; + ent_t* pI; - if ((ent_ents[0].n & ENT_LETHAL) && u_boxtest(e, 0)) + if ((ent_ents[0].n & ENT_LETHAL) && u_boxtest(pEnt, ent_ents)) return TRUE; - for (i = 4; i < 9; i++) - if ((ent_ents[i].n & ENT_LETHAL) && u_boxtest(e, i)) + for (pI = &ent_ents[4]; pI < &ent_ents[9]; pI++) + if ((pI->n & ENT_LETHAL) && u_boxtest(pEnt, pI)) return TRUE; return FALSE; @@ -71,21 +71,21 @@ u_themtest(U8 e) * ASM 237B */ void -e_them_gozombie(U8 e) +e_them_gozombie(ent_t* pEnt) { #define offsx c1 - ent_ents[e].n = 0x47; /* zombie entity */ - ent_ents[e].front = TRUE; - ent_ents[e].offsy = -0x0400; + pEnt->n = 0x47; /* zombie entity */ + pEnt->front = TRUE; + pEnt->offsy = -0x0400; #ifdef ENABLE_SOUND syssnd_play(WAV_DIE, 1); #endif game_score += 50; - if (ent_ents[e].flags & ENT_FLG_ONCE) { + if (pEnt->flags & ENT_FLG_ONCE) { /* make sure entity won't be activated again */ - map_marks[ent_ents[e].mark].ent |= MAP_MARK_NACT; + map_marks[pEnt->mark].ent |= MAP_MARK_NACT; } - ent_ents[e].offsx = (ent_ents[e].x >= 0x80 ? -0x02 : 0x02); + pEnt->offsx = (pEnt->x >= 0x80 ? -0x02 : 0x02); #undef offsx } @@ -101,7 +101,7 @@ e_them_gozombie(U8 e) * ASM 2242 */ void -e_them_t1_action2(U8 e, U8 type) +e_them_t1_action2(ent_t* pEnt, U8 type) { #define offsx c1 #define step_count c2 @@ -110,105 +110,105 @@ e_them_t1_action2(U8 e, U8 type) U8 env0, env1; /* by default, try vertical move. calculate new y */ - i = (((S32)ent_ents[e].y) << 8) + ((S32)ent_ents[e].offsy) + ((U32)ent_ents[e].ylow); + i = (((S32)pEnt->y) << 8) + ((S32)pEnt->offsy) + ((U32)pEnt->ylow); y = i >> 8; /* deactivate if outside vertical boundaries */ /* no need to test zero since e_them _t1a/b don't go up */ /* FIXME what if they got scrolled out ? */ if (y > 0x140) { - ent_ents[e].n = 0; + pEnt->n = 0; return; } /* test environment */ - u_envtest(ent_ents[e].x, y, FALSE, &env0, &env1); + u_envtest(pEnt->x, y, FALSE, &env0, &env1); if (!(env1 & (MAP_EFLG_VERT|MAP_EFLG_SOLID|MAP_EFLG_SPAD|MAP_EFLG_WAYUP))) { /* vertical move possible: falling */ if (env1 & MAP_EFLG_LETHAL) { /* lethal entities kill e_them */ - e_them_gozombie(e); + e_them_gozombie(pEnt); return; } /* save, cleanup and return */ - ent_ents[e].y = y; - ent_ents[e].ylow = i; - ent_ents[e].offsy += 0x0080; - if (ent_ents[e].offsy > 0x0800) - ent_ents[e].offsy = 0x0800; + pEnt->y = y; + pEnt->ylow = i; + pEnt->offsy += 0x0080; + if (pEnt->offsy > 0x0800) + pEnt->offsy = 0x0800; return; } /* vertical move not possible. calculate new sprite */ - ent_ents[e].sprite = ent_ents[e].sprbase - + ent_sprseq[(ent_ents[e].x & 0x1c) >> 3] - + (ent_ents[e].offsx < 0 ? 0x03 : 0x00); + pEnt->sprite = pEnt->sprbase + + ent_sprseq[(pEnt->x & 0x1c) >> 3] + + (pEnt->offsx < 0 ? 0x03 : 0x00); /* reset offsy */ - ent_ents[e].offsy = 0x0080; + pEnt->offsy = 0x0080; /* align to ground */ - ent_ents[e].y &= 0xfff8; - ent_ents[e].y |= 0x0003; + pEnt->y &= 0xfff8; + pEnt->y |= 0x0003; /* latency: if not zero then decrease and return */ - if (ent_ents[e].latency > 0) { - ent_ents[e].latency--; + if (pEnt->latency > 0) { + pEnt->latency--; return; } /* horizontal move. calculate new x */ - if (ent_ents[e].offsx == 0) /* not supposed to move -> don't */ + if (pEnt->offsx == 0) /* not supposed to move -> don't */ return; - x = ent_ents[e].x + ent_ents[e].offsx; - if (ent_ents[e].x < 0 || ent_ents[e].x > 0xe8) { + x = pEnt->x + pEnt->offsx; + if (pEnt->x < 0 || pEnt->x > 0xe8) { /* U-turn and return if reaching horizontal boundaries */ - ent_ents[e].step_count = 0; - ent_ents[e].offsx = -ent_ents[e].offsx; + pEnt->step_count = 0; + pEnt->offsx = -pEnt->offsx; return; } /* test environment */ - u_envtest(x, ent_ents[e].y, FALSE, &env0, &env1); + u_envtest(x, pEnt->y, FALSE, &env0, &env1); if (env1 & (MAP_EFLG_VERT|MAP_EFLG_SOLID|MAP_EFLG_SPAD|MAP_EFLG_WAYUP)) { /* horizontal move not possible: u-turn and return */ - ent_ents[e].step_count = 0; - ent_ents[e].offsx = -ent_ents[e].offsx; + pEnt->step_count = 0; + pEnt->offsx = -pEnt->offsx; return; } /* horizontal move possible */ if (env1 & MAP_EFLG_LETHAL) { /* lethal entities kill e_them */ - e_them_gozombie(e); + e_them_gozombie(pEnt); return; } /* save */ - ent_ents[e].x = x; + pEnt->x = x; /* depending on type, */ if (type == TYPE_1B) { /* set direction to move horizontally towards rick */ - if ((ent_ents[e].x & 0x1e) != 0x10) /* prevents too frequent u-turns */ + if ((pEnt->x & 0x1e) != 0x10) /* prevents too frequent u-turns */ return; - ent_ents[e].offsx = (ent_ents[e].x < E_RICK_ENT.x) ? 0x02 : -0x02; + pEnt->offsx = (pEnt->x < E_RICK_ENT.x) ? 0x02 : -0x02; return; } else { /* set direction according to step counter */ - ent_ents[e].step_count++; + pEnt->step_count++; /* FIXME why trig_x (b16) ?? */ - if ((ent_ents[e].trig_x >> 1) > ent_ents[e].step_count) + if ((pEnt->trig_x >> 1) > pEnt->step_count) return; } /* type is 1A and step counter reached its limit: u-turn */ - ent_ents[e].step_count = 0; - ent_ents[e].offsx = -ent_ents[e].offsx; + pEnt->step_count = 0; + pEnt->offsx = -pEnt->offsx; #undef offsx #undef step_count } @@ -218,38 +218,38 @@ e_them_t1_action2(U8 e, U8 type) * ASM 21CF */ void -e_them_t1_action(U8 e, U8 type) +e_them_t1_action(ent_t* pEnt, U8 type) { - e_them_t1_action2(e, type); + e_them_t1_action2(pEnt, type); /* lethal entities kill them */ - if (u_themtest(e)) { - e_them_gozombie(e); + if (u_themtest(pEnt)) { + e_them_gozombie(pEnt); return; } /* bullet kills them */ if (E_BULLET_ENT.n && - u_fboxtest(e, E_BULLET_ENT.x + (e_bullet_offsx < 0 ? 0 : 0x18), + u_fboxtest(pEnt, E_BULLET_ENT.x + (e_bullet_offsx < 0 ? 0 : 0x18), E_BULLET_ENT.y)) { E_BULLET_ENT.n = 0; - e_them_gozombie(e); + e_them_gozombie(pEnt); return; } /* bomb kills them */ - if (e_bomb_lethal && e_bomb_hit(e)) { - e_them_gozombie(e); + if (e_bomb_lethal && e_bomb_hit(pEnt)) { + e_them_gozombie(pEnt); return; } /* rick stops them */ if (E_RICK_STTST(E_RICK_STSTOP) && - u_fboxtest(e, e_rick_stop_x, e_rick_stop_y)) - ent_ents[e].latency = 0x14; + u_fboxtest(pEnt, e_rick_stop_x, e_rick_stop_y)) + pEnt->latency = 0x14; /* they kill rick */ - if (e_rick_boxtest(e)) + if (e_rick_boxtest(pEnt)) e_rick_gozombie(); } @@ -260,9 +260,9 @@ e_them_t1_action(U8 e, U8 type) * ASM 2452 */ void -e_them_t1a_action(U8 e) +e_them_t1a_action(ent_t* pEnt) { - e_them_t1_action(e, TYPE_1A); + e_them_t1_action(pEnt, TYPE_1A); } @@ -272,9 +272,9 @@ e_them_t1a_action(U8 e) * ASM 21CA */ void -e_them_t1b_action(U8 e) +e_them_t1b_action(ent_t* pEnt) { - e_them_t1_action(e, TYPE_1B); + e_them_t1_action(pEnt, TYPE_1B); } @@ -284,37 +284,37 @@ e_them_t1b_action(U8 e) * ASM 23B8 */ void -e_them_z_action(U8 e) +e_them_z_action(ent_t* pEnt) { #define offsx c1 U32 i; /* calc new sprite */ - ent_ents[e].sprite = ent_ents[e].sprbase - + ((ent_ents[e].x & 0x04) ? 0x07 : 0x06); + pEnt->sprite = pEnt->sprbase + + ((pEnt->x & 0x04) ? 0x07 : 0x06); /* calc new y */ - i = (((S32)ent_ents[e].y) << 8) + ((S32)ent_ents[e].offsy) + ((U32)ent_ents[e].ylow); + i = (((S32)pEnt->y) << 8) + ((S32)pEnt->offsy) + ((U32)pEnt->ylow); /* deactivate if out of vertical boundaries */ - if (ent_ents[e].y < 0 || ent_ents[e].y > 0x0140) { - ent_ents[e].n = 0; + if (pEnt->y < 0 || pEnt->y > 0x0140) { + pEnt->n = 0; return; } /* save */ - ent_ents[e].offsy += 0x0080; - ent_ents[e].ylow = i; - ent_ents[e].y = i >> 8; + pEnt->offsy += 0x0080; + pEnt->ylow = i; + pEnt->y = i >> 8; /* calc new x */ - ent_ents[e].x += ent_ents[e].offsx; + pEnt->x += pEnt->offsx; /* must stay within horizontal boundaries */ - if (ent_ents[e].x < 0) - ent_ents[e].x = 0; - if (ent_ents[e].x > 0xe8) - ent_ents[e].x = 0xe8; + if (pEnt->x < 0) + pEnt->x = 0; + if (pEnt->x > 0xe8) + pEnt->x = 0xe8; #undef offsx } @@ -327,7 +327,7 @@ e_them_z_action(U8 e) * ASM 2792 */ void -e_them_t2_action2(U8 e) +e_them_t2_action2(ent_t* pEnt) { #define flgclmb c1 #define offsx c2 @@ -351,50 +351,50 @@ e_them_t2_action2(U8 e) /*sys_printf("e_them_t2 ------------------------------\n");*/ /* latency: if not zero then decrease */ - if (ent_ents[e].latency > 0) ent_ents[e].latency--; + if (pEnt->latency > 0) pEnt->latency--; /* climbing? */ - if (ent_ents[e].flgclmb != TRUE) goto climbing_not; + if (pEnt->flgclmb != TRUE) goto climbing_not; /* CLIMBING */ /*sys_printf("e_them_t2 climbing\n");*/ /* latency: if not zero then return */ - if (ent_ents[e].latency > 0) return; + if (pEnt->latency > 0) return; /* calc new sprite */ - ent_ents[e].sprite = ent_ents[e].sprbase + 0x08 + - (((ent_ents[e].x ^ ent_ents[e].y) & 0x04) ? 1 : 0); + pEnt->sprite = pEnt->sprbase + 0x08 + + (((pEnt->x ^ pEnt->y) & 0x04) ? 1 : 0); /* reached rick's level? */ - if ((ent_ents[e].y & 0xfe) != (E_RICK_ENT.y & 0xfe)) goto ymove; + if ((pEnt->y & 0xfe) != (E_RICK_ENT.y & 0xfe)) goto ymove; xmove: /* calc new x and test environment */ - ent_ents[e].offsx = (ent_ents[e].x < E_RICK_ENT.x) ? 0x02 : -0x02; - x = ent_ents[e].x + ent_ents[e].offsx; - u_envtest(x, ent_ents[e].y, FALSE, &env0, &env1); + pEnt->offsx = (pEnt->x < E_RICK_ENT.x) ? 0x02 : -0x02; + x = pEnt->x + pEnt->offsx; + u_envtest(x, pEnt->y, FALSE, &env0, &env1); if (env1 & (MAP_EFLG_SOLID|MAP_EFLG_SPAD|MAP_EFLG_WAYUP)) return; if (env1 & MAP_EFLG_LETHAL) { - e_them_gozombie(e); + e_them_gozombie(pEnt); return; } - ent_ents[e].x = x; + pEnt->x = x; if (env1 & (MAP_EFLG_VERT|MAP_EFLG_CLIMB)) /* still climbing */ return; goto climbing_not; /* not climbing anymore */ ymove: /* calc new y and test environment */ - yd = ent_ents[e].y < E_RICK_ENT.y ? 0x02 : -0x02; - y = ent_ents[e].y + yd; + yd = pEnt->y < E_RICK_ENT.y ? 0x02 : -0x02; + y = pEnt->y + yd; if (y < 0 || y > 0x0140) { - ent_ents[e].n = 0; + pEnt->n = 0; return; } - u_envtest(ent_ents[e].x, y, FALSE, &env0, &env1); + u_envtest(pEnt->x, y, FALSE, &env0, &env1); if (env1 & (MAP_EFLG_SOLID|MAP_EFLG_SPAD|MAP_EFLG_WAYUP)) { if (yd < 0) goto xmove; /* can't go up */ @@ -402,7 +402,7 @@ e_them_t2_action2(U8 e) goto climbing_not; /* can't go down */ } /* can move */ - ent_ents[e].y = y; + pEnt->y = y; if (env1 & (MAP_EFLG_VERT|MAP_EFLG_CLIMB)) /* still climbing */ return; @@ -411,70 +411,70 @@ e_them_t2_action2(U8 e) climbing_not: /*sys_printf("e_them_t2 climbing NOT\n");*/ - ent_ents[e].flgclmb = FALSE; /* not climbing */ + pEnt->flgclmb = FALSE; /* not climbing */ /* calc new y (falling) and test environment */ - i = (ent_ents[e].y << 8) + ent_ents[e].offsy + ent_ents[e].ylow; + i = (pEnt->y << 8) + pEnt->offsy + pEnt->ylow; y = i >> 8; - u_envtest(ent_ents[e].x, y, FALSE, &env0, &env1); + u_envtest(pEnt->x, y, FALSE, &env0, &env1); if (!(env1 & (MAP_EFLG_SOLID|MAP_EFLG_SPAD|MAP_EFLG_WAYUP))) { /*sys_printf("e_them_t2 y move OK\n");*/ /* can go there */ if (env1 & MAP_EFLG_LETHAL) { - e_them_gozombie(e); + e_them_gozombie(pEnt); return; } if (y > 0x0140) { /* deactivate if outside */ - ent_ents[e].n = 0; + pEnt->n = 0; return; } if (!(env1 & MAP_EFLG_VERT)) { /* save */ - ent_ents[e].y = y; - ent_ents[e].ylow = i; - ent_ents[e].offsy += 0x0080; - if (ent_ents[e].offsy > 0x0800) - ent_ents[e].offsy = 0x0800; + pEnt->y = y; + pEnt->ylow = i; + pEnt->offsy += 0x0080; + if (pEnt->offsy > 0x0800) + pEnt->offsy = 0x0800; return; } - if (((ent_ents[e].x & 0x07) == 0x04) && (y < E_RICK_ENT.y)) { + if (((pEnt->x & 0x07) == 0x04) && (y < E_RICK_ENT.y)) { /*sys_printf("e_them_t2 climbing00\n");*/ - ent_ents[e].flgclmb = TRUE; /* climbing */ + pEnt->flgclmb = TRUE; /* climbing */ return; } } /*sys_printf("e_them_t2 ymove nok or ...\n");*/ /* can't go there, or ... */ - ent_ents[e].y = (ent_ents[e].y & 0xf8) | 0x03; /* align to ground */ - ent_ents[e].offsy = 0x0100; - if (ent_ents[e].latency != 00) + pEnt->y = (pEnt->y & 0xf8) | 0x03; /* align to ground */ + pEnt->offsy = 0x0100; + if (pEnt->latency != 00) return; if ((env1 & MAP_EFLG_CLIMB) && - ((ent_ents[e].x & 0x0e) == 0x04) && - (ent_ents[e].y > E_RICK_ENT.y)) { + ((pEnt->x & 0x0e) == 0x04) && + (pEnt->y > E_RICK_ENT.y)) { /*sys_printf("e_them_t2 climbing01\n");*/ - ent_ents[e].flgclmb = TRUE; /* climbing */ + pEnt->flgclmb = TRUE; /* climbing */ return; } /* calc new sprite */ - ent_ents[e].sprite = ent_ents[e].sprbase + - ent_sprseq[(ent_ents[e].offsx < 0 ? 4 : 0) + - ((ent_ents[e].x & 0x0e) >> 3)]; - /*sys_printf("e_them_t2 sprite %02x\n", ent_ents[e].sprite);*/ + pEnt->sprite = pEnt->sprbase + + ent_sprseq[(pEnt->offsx < 0 ? 4 : 0) + + ((pEnt->x & 0x0e) >> 3)]; + /*sys_printf("e_them_t2 sprite %02x\n", pEnt->sprite);*/ /* */ - if (ent_ents[e].offsx == 0) - ent_ents[e].offsx = 2; - x = ent_ents[e].x + ent_ents[e].offsx; + if (pEnt->offsx == 0) + pEnt->offsx = 2; + x = pEnt->x + pEnt->offsx; /*sys_printf("e_them_t2 xmove x=%02x\n", x);*/ if (x < 0xe8) { - u_envtest(x, ent_ents[e].y, FALSE, &env0, &env1); + u_envtest(x, pEnt->y, FALSE, &env0, &env1); if (!(env1 & (MAP_EFLG_VERT|MAP_EFLG_SOLID|MAP_EFLG_SPAD|MAP_EFLG_WAYUP))) { - ent_ents[e].x = x; + pEnt->x = x; if ((x & 0x1e) != 0x08) return; @@ -492,7 +492,7 @@ e_them_t2_action2(U8 e) *bl ^= *bh; e_them_rndnbr = bx; - ent_ents[e].offsx = (*bl & 0x01) ? -0x02 : 0x02; + pEnt->offsx = (*bl & 0x01) ? -0x02 : 0x02; /* back to normal */ @@ -503,10 +503,10 @@ e_them_t2_action2(U8 e) /* U-turn */ /*sys_printf("e_them_t2 u-turn\n");*/ - if (ent_ents[e].offsx == 0) - ent_ents[e].offsx = 2; + if (pEnt->offsx == 0) + pEnt->offsx = 2; else - ent_ents[e].offsx = -ent_ents[e].offsx; + pEnt->offsx = -pEnt->offsx; #undef offsx } @@ -516,39 +516,39 @@ e_them_t2_action2(U8 e) * ASM 2718 */ void -e_them_t2_action(U8 e) +e_them_t2_action(ent_t* pEnt) { - e_them_t2_action2(e); + e_them_t2_action2(pEnt); /* they kill rick */ - if (e_rick_boxtest(e)) + if (e_rick_boxtest(pEnt)) e_rick_gozombie(); /* lethal entities kill them */ - if (u_themtest(e)) { - e_them_gozombie(e); + if (u_themtest(pEnt)) { + e_them_gozombie(pEnt); return; } /* bullet kills them */ if (E_BULLET_ENT.n && - u_fboxtest(e, E_BULLET_ENT.x + (e_bullet_offsx < 0 ? 00 : 0x18), + u_fboxtest(pEnt, E_BULLET_ENT.x + (e_bullet_offsx < 0 ? 00 : 0x18), E_BULLET_ENT.y)) { E_BULLET_ENT.n = 0; - e_them_gozombie(e); + e_them_gozombie(pEnt); return; } /* bomb kills them */ - if (e_bomb_lethal && e_bomb_hit(e)) { - e_them_gozombie(e); + if (e_bomb_lethal && e_bomb_hit(pEnt)) { + e_them_gozombie(pEnt); return; } /* rick stops them */ if (E_RICK_STTST(E_RICK_STSTOP) && - u_fboxtest(e, e_rick_stop_x, e_rick_stop_y)) - ent_ents[e].latency = 0x14; + u_fboxtest(pEnt, e_rick_stop_x, e_rick_stop_y)) + pEnt->latency = 0x14; } @@ -566,7 +566,7 @@ e_them_t2_action(U8 e) * ASM: 255A */ void -e_them_t3_action2(U8 e) +e_them_t3_action2(ent_t* pEnt) { #define sproffs c1 #define step_count c2 @@ -576,41 +576,41 @@ e_them_t3_action2(U8 e) while (1) { /* calc new sprite */ - i = ent_sprseq[ent_ents[e].sprbase + ent_ents[e].sproffs]; + i = ent_sprseq[pEnt->sprbase + pEnt->sproffs]; if (i == 0xff) - i = ent_sprseq[ent_ents[e].sprbase]; - ent_ents[e].sprite = i; + i = ent_sprseq[pEnt->sprbase]; + pEnt->sprite = i; - if (ent_ents[e].sproffs != 0) { /* awake */ + if (pEnt->sproffs != 0) { /* awake */ /* rotate sprseq */ - if (ent_sprseq[ent_ents[e].sprbase + ent_ents[e].sproffs] != 0xff) - ent_ents[e].sproffs++; - if (ent_sprseq[ent_ents[e].sprbase + ent_ents[e].sproffs] == 0xff) - ent_ents[e].sproffs = 1; + if (ent_sprseq[pEnt->sprbase + pEnt->sproffs] != 0xff) + pEnt->sproffs++; + if (ent_sprseq[pEnt->sprbase + pEnt->sproffs] == 0xff) + pEnt->sproffs = 1; - if (ent_ents[e].step_count < ent_mvstep[ent_ents[e].step_no].count) { + if (pEnt->step_count < ent_mvstep[pEnt->step_no].count) { /* * still running this step: try to increment x and y while * checking that they remain within boudaries. if so, return. * else switch to next step. */ - ent_ents[e].step_count++; - x = ent_ents[e].x + ((S16)(ent_mvstep[ent_ents[e].step_no].dx)); + pEnt->step_count++; + x = pEnt->x + ((S16)(ent_mvstep[pEnt->step_no].dx)); /* check'n save */ if (x > 0 && x < 0xe8) { - ent_ents[e].x = x; + pEnt->x = x; /*FIXME*/ /* - y = ent_mvstep[ent_ents[e].step_no].dy; + y = ent_mvstep[pEnt->step_no].dy; if (y < 0) y += 0xff00; - y += ent_ents[e].y; + y += pEnt->y; */ - y = ent_ents[e].y + ((S16)(ent_mvstep[ent_ents[e].step_no].dy)); + y = pEnt->y + ((S16)(ent_mvstep[pEnt->step_no].dy)); if (y > 0 && y < 0x0140) { - ent_ents[e].y = y; + pEnt->y = y; return; } } @@ -620,62 +620,62 @@ e_them_t3_action2(U8 e) * step is done, or x or y is outside boundaries. try to * switch to next step */ - ent_ents[e].step_no++; - if (ent_mvstep[ent_ents[e].step_no].count != 0xff) { + pEnt->step_no++; + if (ent_mvstep[pEnt->step_no].count != 0xff) { /* there is a next step: init and loop */ - ent_ents[e].step_count = 0; + pEnt->step_count = 0; } else { /* there is no next step: restart or deactivate */ if (!E_RICK_STTST(E_RICK_STZOMBIE) && - !(ent_ents[e].flags & ENT_FLG_ONCE)) { + !(pEnt->flags & ENT_FLG_ONCE)) { /* loop this entity */ - ent_ents[e].sproffs = 0; - ent_ents[e].n &= ~ENT_LETHAL; - if (ent_ents[e].flags & ENT_FLG_LETHALR) - ent_ents[e].n |= ENT_LETHAL; - ent_ents[e].x = ent_ents[e].xsave; - ent_ents[e].y = ent_ents[e].ysave; - if (ent_ents[e].y < 0 || ent_ents[e].y > 0x140) { - ent_ents[e].n = 0; + pEnt->sproffs = 0; + pEnt->n &= ~ENT_LETHAL; + if (pEnt->flags & ENT_FLG_LETHALR) + pEnt->n |= ENT_LETHAL; + pEnt->x = pEnt->xsave; + pEnt->y = pEnt->ysave; + if (pEnt->y < 0 || pEnt->y > 0x140) { + pEnt->n = 0; return; } } else { /* deactivate this entity */ - ent_ents[e].n = 0; + pEnt->n = 0; return; } } } - else { /* ent_ents[e].sprseq1 == 0 -- waiting */ + else { /* pEnt->sprseq1 == 0 -- waiting */ /* ugly GOTOs */ - if (ent_ents[e].flags & ENT_FLG_TRIGRICK) { /* reacts to rick */ + if (pEnt->flags & ENT_FLG_TRIGRICK) { /* reacts to rick */ /* wake up if triggered by rick */ - if (u_trigbox(e, E_RICK_ENT.x + 0x0C, E_RICK_ENT.y + 0x0A)) + if (u_trigbox(pEnt, E_RICK_ENT.x + 0x0C, E_RICK_ENT.y + 0x0A)) goto wakeup; } - if (ent_ents[e].flags & ENT_FLG_TRIGSTOP) { /* reacts to rick "stop" */ + if (pEnt->flags & ENT_FLG_TRIGSTOP) { /* reacts to rick "stop" */ /* wake up if triggered by rick "stop" */ if (E_RICK_STTST(E_RICK_STSTOP) && - u_trigbox(e, e_rick_stop_x, e_rick_stop_y)) + u_trigbox(pEnt, e_rick_stop_x, e_rick_stop_y)) goto wakeup; } - if (ent_ents[e].flags & ENT_FLG_TRIGBULLET) { /* reacts to bullets */ + if (pEnt->flags & ENT_FLG_TRIGBULLET) { /* reacts to bullets */ /* wake up if triggered by bullet */ - if (E_BULLET_ENT.n && u_trigbox(e, e_bullet_xc, e_bullet_yc)) { + if (E_BULLET_ENT.n && u_trigbox(pEnt, e_bullet_xc, e_bullet_yc)) { E_BULLET_ENT.n = 0; goto wakeup; } } - if (ent_ents[e].flags & ENT_FLG_TRIGBOMB) { /* reacts to bombs */ + if (pEnt->flags & ENT_FLG_TRIGBOMB) { /* reacts to bombs */ /* wake up if triggered by bomb */ - if (e_bomb_lethal && u_trigbox(e, e_bomb_xc, e_bomb_yc)) + if (e_bomb_lethal && u_trigbox(pEnt, e_bomb_xc, e_bomb_yc)) goto wakeup; } @@ -694,15 +694,15 @@ e_them_t3_action2(U8 e) * FIXME is it 8 of them, not 10? * FIXME testing below... */ - syssnd_play(WAV_ENTITY[(ent_ents[e].trigsnd & 0x1F) - 0x14], 1); + syssnd_play(WAV_ENTITY[(pEnt->trigsnd & 0x1F) - 0x14], 1); /*syssnd_play(WAV_ENTITY[0], 1);*/ #endif - ent_ents[e].n &= ~ENT_LETHAL; - if (ent_ents[e].flags & ENT_FLG_LETHALI) - ent_ents[e].n |= ENT_LETHAL; - ent_ents[e].sproffs = 1; - ent_ents[e].step_count = 0; - ent_ents[e].step_no = ent_ents[e].step_no_i; + pEnt->n &= ~ENT_LETHAL; + if (pEnt->flags & ENT_FLG_LETHALI) + pEnt->n |= ENT_LETHAL; + pEnt->sproffs = 1; + pEnt->step_count = 0; + pEnt->step_no = pEnt->step_no_i; return; } } @@ -716,13 +716,13 @@ e_them_t3_action2(U8 e) * ASM 2546 */ void -e_them_t3_action(U8 e) +e_them_t3_action(ent_t* pEnt) { - e_them_t3_action2(e); + e_them_t3_action2(pEnt); /* if lethal, can kill rick */ - if ((ent_ents[e].n & ENT_LETHAL) && - !E_RICK_STTST(E_RICK_STZOMBIE) && e_rick_boxtest(e)) { /* CALL 1130 */ + if ((pEnt->n & ENT_LETHAL) && + !E_RICK_STTST(E_RICK_STZOMBIE) && e_rick_boxtest(pEnt)) { /* CALL 1130 */ e_rick_gozombie(); } } diff --git a/src/ents.c b/src/ents.c index d9817a1..68939f2 100644 --- a/src/ents.c +++ b/src/ents.c @@ -1 +1 @@ -/* * xrick/src/ents.c * * Copyright (C) 1998-2002 BigOrno (bigorno@bigorno.net). All rights reserved. * * The use and distribution terms for this software are contained in the file * named README, which can be found in the root of this distribution. By * using this software in any fashion, you are agreeing to be bound by the * terms of this license. * * You must not remove this notice, or any other, from this software. */ #include #include "system.h" #include "config.h" #include "game.h" #include "ents.h" #include "debug.h" #include "e_bullet.h" #include "e_bomb.h" #include "e_rick.h" #include "e_them.h" #include "e_bonus.h" #include "e_box.h" #include "e_sbonus.h" #include "rects.h" #include "maps.h" #include "draw.h" #ifdef IIGS #pragma noroot segment "game"; #endif /* * global vars */ ent_t ent_ents[ENT_ENTSNUM + 1]; rect_t *ent_rects = NULL; /* * prototypes */ static void ent_addrect(S16, S16, U16, U16); static U8 ent_creat1(U8 *); static U8 ent_creat2(U8 *, U16); /* * Reset entities * * ASM 2520 */ void ent_reset(void) { U8 i; E_RICK_STRST(E_RICK_STSTOP); e_bomb_lethal = FALSE; ent_ents[0].n = 0; for (i = 2; ent_ents[i].n != 0xff; i++) ent_ents[i].n = 0; } /* * Create an entity on slots 4 to 8 by using the first slot available. * Entities of type e_them on slots 4 to 8, when lethal, can kill * other e_them (on slots 4 to C) as well as rick. * * ASM 209C * * e: anything, CHANGED to the allocated entity number. * return: TRUE/OK FALSE/not */ static U8 ent_creat1(U8 *e) { /* look for a slot */ for (*e = 0x04; *e < 0x09; (*e)++) if (ent_ents[*e].n == 0) { /* if slot available, use it */ ent_ents[*e].c1 = 0; return TRUE; } return FALSE; } /* * Create an entity on slots 9 to C by using the first slot available. * Entities of type e_them on slots 9 to C can kill rick when lethal, * but they can never kill other e_them. * * ASM 20BC * * e: anything, CHANGED to the allocated entity number. * m: number of the mark triggering the creation of the entity. * ret: TRUE/OK FALSE/not */ static U8 ent_creat2(U8 *e, U16 m) { /* make sure the entity created by this mark is not active already */ for (*e = 0x09; *e < 0x0c; (*e)++) if (ent_ents[*e].n != 0 && ent_ents[*e].mark == m) return FALSE; /* look for a slot */ for (*e = 0x09; *e < 0x0c; (*e)++) if (ent_ents[*e].n == 0) { /* if slot available, use it */ ent_ents[*e].c1 = 2; return TRUE; } return FALSE; } /* * Process marks that are within the visible portion of the map, * and create the corresponding entities. * * absolute map coordinate means that they are not relative to * map_frow, as any other coordinates are. * * ASM 1F40 * * frow: first visible row of the map -- absolute map coordinate * lrow: last visible row of the map -- absolute map coordinate */ void ent_actvis(U8 frow, U8 lrow) { U16 m; U8 e; U16 y; /* * go through the list and find the first mark that * is visible, i.e. which has a row greater than the * first row (marks being ordered by row number). */ for (m = map_submaps[game_submap].mark; map_marks[m].row != 0xff && map_marks[m].row < frow; m++); if (map_marks[m].row == 0xff) /* none found */ return; /* * go through the list and process all marks that are * visible, i.e. which have a row lower than the last * row (marks still being ordered by row number). */ for (; map_marks[m].row != 0xff && map_marks[m].row < lrow; m++) { /* ignore marks that are not active */ if (map_marks[m].ent & MAP_MARK_NACT) continue; /* * allocate a slot to the new entity * * slot type * 0 available for e_them (lethal to other e_them, and stops entities * i.e. entities can't move over them. E.g. moving blocks. But they * can move over entities and kill them!). * 1 xrick * 2 bullet * 3 bomb * 4-8 available for e_them, e_box, e_bonus or e_sbonus (lethal to * other e_them, identified by their number being >= 0x10) * 9-C available for e_them, e_box, e_bonus or e_sbonus (not lethal to * other e_them, identified by their number being < 0x10) * * the type of an entity is determined by its .n as detailed below. * * 1 xrick * 2 bullet * 3 bomb * 4, 7, a, d e_them, type 1a * 5, 8, b, e e_them, type 1b * 6, 9, c, f e_them, type 2 * 10, 11 box * 12, 13, 14, 15 bonus * 16, 17 speed bonus * >17 e_them, type 3 * 47 zombie */ if (!(map_marks[m].flags & ENT_FLG_STOPRICK)) { if (map_marks[m].ent >= 0x10) { /* boxes, bonuses and type 3 e_them go to slot 4-8 */ /* (c1 set to 0 -> all type 3 e_them are sleeping) */ if (!ent_creat1(&e)) continue; } else { /* type 1 and 2 e_them go to slot 9-c */ /* (c1 set to 2) */ if (!ent_creat2(&e, m)) continue; } } else { /* entities stopping rick (e.g. blocks) go to slot 0 */ if (ent_ents[0].n) continue; e = 0; ent_ents[0].c1 = 0; } /* * initialize the entity */ ent_ents[e].mark = m; ent_ents[e].flags = map_marks[m].flags; ent_ents[e].n = map_marks[m].ent; /* * if entity is to be already running (i.e. not asleep and waiting * for some trigger to move), then use LETHALR i.e. restart flag, right * from the beginning */ if (ent_ents[e].flags & ENT_FLG_LETHALR) ent_ents[e].n |= ENT_LETHAL; ent_ents[e].x = map_marks[m].xy & 0xf8; y = (map_marks[m].xy & 0x07) + (map_marks[m].row & 0xf8) - map_frow; y <<= 3; if (!(ent_ents[e].flags & ENT_FLG_STOPRICK)) y += 3; ent_ents[e].y = y; ent_ents[e].xsave = ent_ents[e].x; ent_ents[e].ysave = ent_ents[e].y; /*ent_ents[e].w0C = 0;*/ /* in ASM code but never used */ ent_ents[e].w = ent_entdata[map_marks[m].ent].w; ent_ents[e].h = ent_entdata[map_marks[m].ent].h; ent_ents[e].sprbase = ent_entdata[map_marks[m].ent].spr; ent_ents[e].sprite = (U8)ent_entdata[map_marks[m].ent].spr; ent_ents[e].step_no_i = ent_entdata[map_marks[m].ent].sni; ent_ents[e].trigsnd = (U8)ent_entdata[map_marks[m].ent].snd; /* * FIXME what is this? when all trigger flags are up, then * use .sni for sprbase. Why? What is the point? (This is * for type 1 and 2 e_them, ...) * * This also means that as long as sprite has not been * recalculated, a wrong value is used. This is normal, see * what happens to the falling guy on the right on submap 3: * it changes when hitting the ground. */ #define ENT_FLG_TRIGGERS \ (ENT_FLG_TRIGBOMB|ENT_FLG_TRIGBULLET|ENT_FLG_TRIGSTOP|ENT_FLG_TRIGRICK) if ((ent_ents[e].flags & ENT_FLG_TRIGGERS) == ENT_FLG_TRIGGERS && e >= 0x09) ent_ents[e].sprbase = (U8)(ent_entdata[map_marks[m].ent].sni & 0x00ff); #undef ENT_FLG_TRIGGERS ent_ents[e].trig_x = map_marks[m].lt & 0xf8; ent_ents[e].latency = (map_marks[m].lt & 0x07) << 5; /* <<5 eq *32 */ ent_ents[e].trig_y = 3 + 8 * ((map_marks[m].row & 0xf8) - map_frow + (map_marks[m].lt & 0x07)); ent_ents[e].c2 = 0; ent_ents[e].offsy = 0; ent_ents[e].ylow = 0; ent_ents[e].front = FALSE; } } /* * Add a tile-aligned rectangle containing the given rectangle (indicated * by its MAP coordinates) to the list of rectangles. Clip the rectangle * so it fits into the display zone. */ static void ent_addrect(S16 x, S16 y, U16 width, U16 height) { S16 x0, y0; U16 w0, h0; /*sys_printf("rect %#04x,%#04x %#04x %#04x ", x, y, width, height);*/ /* align to tiles */ x0 = x & 0xfff8; y0 = y & 0xfff8; w0 = width; h0 = height; if (x - x0) w0 = (w0 + (x - x0)) | 0x0007; if (y - y0) h0 = (h0 + (y - y0)) | 0x0007; /* clip */ if (draw_clipms(&x0, &y0, &w0, &h0)) { /* do not add if fully clipped */ /*sys_printf("-> [clipped]\n");*/ return; } /*sys_printf("-> %#04x,%#04x %#04x %#04x\n", x0, y0, w0, h0);*/ #if defined(GFXST) || defined(GFXGS) y0 += 8; #endif /* get to screen */ x0 -= DRAW_XYMAP_SCRLEFT; y0 -= DRAW_XYMAP_SCRTOP; /* add rectangle to the list */ ent_rects = rects_new(x0, y0, w0, h0, ent_rects); } /* * Draw all entities onto the frame buffer. * * ASM 07a4 * * NOTE This may need to be part of draw.c. Also needs better comments, * NOTE and probably better rectangles management. */ void ent_draw(void) { #ifdef ENABLE_CHEATS static U8 ch3 = FALSE; #endif S16 dx, dy; ent_t *pEnt; draw_tilesBank = map_tilesBank; /* reset rectangles list */ rects_free(ent_rects); ent_rects = NULL; /*sys_printf("\n");*/ /* * background loop : erase all entities that were visible */ for (pEnt=ent_ents; pEnt->n != 0xff; ++pEnt) { #ifdef ENABLE_CHEATS if (pEnt->prev_n && (ch3 || pEnt->prev_s)) #else if (pEnt->prev_n && pEnt->prev_s) #endif /* if entity was active, then erase it (redraw the map) */ draw_spriteBackground(pEnt->prev_x, pEnt->prev_y); } /* * foreground loop : draw all entities that are visible */ for (pEnt=ent_ents; pEnt->n != 0xff; ++pEnt) { /* * If entity is active now, draw the sprite. If entity was * not active before, add a rectangle for the sprite. */ #ifdef ENABLE_CHEATS if (pEnt->n && (game_cheat3 || pEnt->sprite)) #else if (pEnt->n && pEnt->sprite) #endif /* If entitiy is active, draw the sprite. */ draw_sprite2(pEnt->sprite, pEnt->x, pEnt->y, pEnt->front); } /* * rectangles loop : figure out which parts of the screen have been * impacted and need to be refreshed, then save state */ for (pEnt=ent_ents; pEnt->n != 0xff; ++pEnt) { #ifdef ENABLE_CHEATS if (pEnt->prev_n && (ch3 || pEnt->prev_s)) { #else if (pEnt->prev_n && pEnt->prev_s) { #endif /* (1) if entity was active and has been drawn ... */ #ifdef ENABLE_CHEATS if (pEnt->n && (game_cheat3 || pEnt->sprite)) { #else if (pEnt->n && pEnt->sprite) { #endif /* (1.1) ... and is still active now and still needs to be drawn, */ /* then check if rectangles intersect */ dx = abs(pEnt->x - pEnt->prev_x); dy = abs(pEnt->y - pEnt->prev_y); if (dx < 0x20 && dy < 0x16) { /* (1.1.1) if they do, then create one rectangle */ ent_addrect((pEnt->prev_x < pEnt->x) ? pEnt->prev_x : pEnt->x, (pEnt->prev_y < pEnt->y) ? pEnt->prev_y : pEnt->y, dx + 0x20, dy + 0x15); } else { /* (1.1.2) else, create two rectangles */ ent_addrect(pEnt->x, pEnt->y, 0x20, 0x15); ent_addrect(pEnt->prev_x, pEnt->prev_y, 0x20, 0x15); } } else /* (1.2) ... and is not active anymore or does not need to be drawn */ /* then create one single rectangle */ ent_addrect(pEnt->prev_x, pEnt->prev_y, 0x20, 0x15); } #ifdef ENABLE_CHEATS else if (pEnt->n && (game_cheat3 || pEnt->sprite)) { #else else if (pEnt->n && pEnt->sprite) { #endif /* (2) if entity is active and needs to be drawn, */ /* then create one rectangle */ ent_addrect(pEnt->x, pEnt->y, 0x20, 0x15); } /* save state */ pEnt->prev_x = pEnt->x; pEnt->prev_y = pEnt->y; pEnt->prev_n = pEnt->n; pEnt->prev_s = pEnt->sprite; } #ifdef ENABLE_CHEATS ch3 = game_cheat3; #endif } /* * Clear entities previous state * */ void ent_clprev(void) { U8 i; for (i = 0; ent_ents[i].n != 0xff; i++) ent_ents[i].prev_n = 0; } /* * Table containing entity action function pointers. */ void (*ent_actf[])(U8) = { NULL, /* 00 - zero means that the slot is free */ e_rick_action, /* 01 - 12CA */ e_bullet_action, /* 02 - 1883 */ e_bomb_action, /* 03 - 18CA */ e_them_t1a_action, /* 04 - 2452 */ e_them_t1b_action, /* 05 - 21CA */ e_them_t2_action, /* 06 - 2718 */ e_them_t1a_action, /* 07 - 2452 */ e_them_t1b_action, /* 08 - 21CA */ e_them_t2_action, /* 09 - 2718 */ e_them_t1a_action, /* 0A - 2452 */ e_them_t1b_action, /* 0B - 21CA */ e_them_t2_action, /* 0C - 2718 */ e_them_t1a_action, /* 0D - 2452 */ e_them_t1b_action, /* 0E - 21CA */ e_them_t2_action, /* 0F - 2718 */ e_box_action, /* 10 - 245A */ e_box_action, /* 11 - 245A */ e_bonus_action, /* 12 - 242C */ e_bonus_action, /* 13 - 242C */ e_bonus_action, /* 14 - 242C */ e_bonus_action, /* 15 - 242C */ e_sbonus_start, /* 16 - 2182 */ e_sbonus_stop /* 17 - 2143 */ }; /* * Run entities action function * */ void ent_action(void) { U8 i, k; IFDEBUG_ENTS( sys_printf("xrick/ents: --------- action ----------------\n"); for (i = 0; ent_ents[i].n != 0xff; i++) if (ent_ents[i].n) { sys_printf("xrick/ents: slot %#04x, entity %#04x", i, ent_ents[i].n); sys_printf(" (%#06x, %#06x), sprite %#04x.\n", ent_ents[i].x, ent_ents[i].y, ent_ents[i].sprite); } ); for (i = 0; ent_ents[i].n != 0xff; i++) { if (ent_ents[i].n) { k = ent_ents[i].n & 0x7f; if (k == 0x47) e_them_z_action(i); else if (k >= 0x18) e_them_t3_action(i); else ent_actf[k](i); } } } /* eof */ \ No newline at end of file +/* * xrick/src/ents.c * * Copyright (C) 1998-2002 BigOrno (bigorno@bigorno.net). All rights reserved. * * The use and distribution terms for this software are contained in the file * named README, which can be found in the root of this distribution. By * using this software in any fashion, you are agreeing to be bound by the * terms of this license. * * You must not remove this notice, or any other, from this software. */ #include #include "system.h" #include "config.h" #include "game.h" #include "ents.h" #include "debug.h" #include "e_bullet.h" #include "e_bomb.h" #include "e_rick.h" #include "e_them.h" #include "e_bonus.h" #include "e_box.h" #include "e_sbonus.h" #include "rects.h" #include "maps.h" #include "draw.h" #ifdef IIGS #pragma noroot segment "game"; #endif /* * global vars */ ent_t ent_ents[ENT_ENTSNUM + 1]; rect_t *ent_rects = NULL; /* * prototypes */ static void ent_addrect(S16, S16, U16, U16); static U8 ent_creat1(U8 *); static U8 ent_creat2(U8 *, U16); /* * Reset entities * * ASM 2520 */ void ent_reset(void) { U8 i; E_RICK_STRST(E_RICK_STSTOP); e_bomb_lethal = FALSE; ent_ents[0].n = 0; for (i = 2; ent_ents[i].n != 0xff; i++) ent_ents[i].n = 0; } /* * Create an entity on slots 4 to 8 by using the first slot available. * Entities of type e_them on slots 4 to 8, when lethal, can kill * other e_them (on slots 4 to C) as well as rick. * * ASM 209C * * e: anything, CHANGED to the allocated entity number. * return: TRUE/OK FALSE/not */ static U8 ent_creat1(U8 *e) { /* look for a slot */ for (*e = 0x04; *e < 0x09; (*e)++) if (ent_ents[*e].n == 0) { /* if slot available, use it */ ent_ents[*e].c1 = 0; return TRUE; } return FALSE; } /* * Create an entity on slots 9 to C by using the first slot available. * Entities of type e_them on slots 9 to C can kill rick when lethal, * but they can never kill other e_them. * * ASM 20BC * * e: anything, CHANGED to the allocated entity number. * m: number of the mark triggering the creation of the entity. * ret: TRUE/OK FALSE/not */ static U8 ent_creat2(U8 *e, U16 m) { /* make sure the entity created by this mark is not active already */ for (*e = 0x09; *e < 0x0c; (*e)++) if (ent_ents[*e].n != 0 && ent_ents[*e].mark == m) return FALSE; /* look for a slot */ for (*e = 0x09; *e < 0x0c; (*e)++) if (ent_ents[*e].n == 0) { /* if slot available, use it */ ent_ents[*e].c1 = 2; return TRUE; } return FALSE; } /* * Process marks that are within the visible portion of the map, * and create the corresponding entities. * * absolute map coordinate means that they are not relative to * map_frow, as any other coordinates are. * * ASM 1F40 * * frow: first visible row of the map -- absolute map coordinate * lrow: last visible row of the map -- absolute map coordinate */ void ent_actvis(U8 frow, U8 lrow) { U16 m; U8 e; U16 y; /* * go through the list and find the first mark that * is visible, i.e. which has a row greater than the * first row (marks being ordered by row number). */ for (m = map_submaps[game_submap].mark; map_marks[m].row != 0xff && map_marks[m].row < frow; m++); if (map_marks[m].row == 0xff) /* none found */ return; /* * go through the list and process all marks that are * visible, i.e. which have a row lower than the last * row (marks still being ordered by row number). */ for (; map_marks[m].row != 0xff && map_marks[m].row < lrow; m++) { /* ignore marks that are not active */ if (map_marks[m].ent & MAP_MARK_NACT) continue; /* * allocate a slot to the new entity * * slot type * 0 available for e_them (lethal to other e_them, and stops entities * i.e. entities can't move over them. E.g. moving blocks. But they * can move over entities and kill them!). * 1 xrick * 2 bullet * 3 bomb * 4-8 available for e_them, e_box, e_bonus or e_sbonus (lethal to * other e_them, identified by their number being >= 0x10) * 9-C available for e_them, e_box, e_bonus or e_sbonus (not lethal to * other e_them, identified by their number being < 0x10) * * the type of an entity is determined by its .n as detailed below. * * 1 xrick * 2 bullet * 3 bomb * 4, 7, a, d e_them, type 1a * 5, 8, b, e e_them, type 1b * 6, 9, c, f e_them, type 2 * 10, 11 box * 12, 13, 14, 15 bonus * 16, 17 speed bonus * >17 e_them, type 3 * 47 zombie */ if (!(map_marks[m].flags & ENT_FLG_STOPRICK)) { if (map_marks[m].ent >= 0x10) { /* boxes, bonuses and type 3 e_them go to slot 4-8 */ /* (c1 set to 0 -> all type 3 e_them are sleeping) */ if (!ent_creat1(&e)) continue; } else { /* type 1 and 2 e_them go to slot 9-c */ /* (c1 set to 2) */ if (!ent_creat2(&e, m)) continue; } } else { /* entities stopping rick (e.g. blocks) go to slot 0 */ if (ent_ents[0].n) continue; e = 0; ent_ents[0].c1 = 0; } /* * initialize the entity */ ent_ents[e].mark = m; ent_ents[e].flags = map_marks[m].flags; ent_ents[e].n = map_marks[m].ent; /* * if entity is to be already running (i.e. not asleep and waiting * for some trigger to move), then use LETHALR i.e. restart flag, right * from the beginning */ if (ent_ents[e].flags & ENT_FLG_LETHALR) ent_ents[e].n |= ENT_LETHAL; ent_ents[e].x = map_marks[m].xy & 0xf8; y = (map_marks[m].xy & 0x07) + (map_marks[m].row & 0xf8) - map_frow; y <<= 3; if (!(ent_ents[e].flags & ENT_FLG_STOPRICK)) y += 3; ent_ents[e].y = y; ent_ents[e].xsave = ent_ents[e].x; ent_ents[e].ysave = ent_ents[e].y; /*ent_ents[e].w0C = 0;*/ /* in ASM code but never used */ ent_ents[e].w = ent_entdata[map_marks[m].ent].w; ent_ents[e].h = ent_entdata[map_marks[m].ent].h; ent_ents[e].sprbase = ent_entdata[map_marks[m].ent].spr; ent_ents[e].sprite = (U8)ent_entdata[map_marks[m].ent].spr; ent_ents[e].step_no_i = ent_entdata[map_marks[m].ent].sni; ent_ents[e].trigsnd = (U8)ent_entdata[map_marks[m].ent].snd; /* * FIXME what is this? when all trigger flags are up, then * use .sni for sprbase. Why? What is the point? (This is * for type 1 and 2 e_them, ...) * * This also means that as long as sprite has not been * recalculated, a wrong value is used. This is normal, see * what happens to the falling guy on the right on submap 3: * it changes when hitting the ground. */ #define ENT_FLG_TRIGGERS \ (ENT_FLG_TRIGBOMB|ENT_FLG_TRIGBULLET|ENT_FLG_TRIGSTOP|ENT_FLG_TRIGRICK) if ((ent_ents[e].flags & ENT_FLG_TRIGGERS) == ENT_FLG_TRIGGERS && e >= 0x09) ent_ents[e].sprbase = (U8)(ent_entdata[map_marks[m].ent].sni & 0x00ff); #undef ENT_FLG_TRIGGERS ent_ents[e].trig_x = map_marks[m].lt & 0xf8; ent_ents[e].latency = (map_marks[m].lt & 0x07) << 5; /* <<5 eq *32 */ ent_ents[e].trig_y = 3 + 8 * ((map_marks[m].row & 0xf8) - map_frow + (map_marks[m].lt & 0x07)); ent_ents[e].c2 = 0; ent_ents[e].offsy = 0; ent_ents[e].ylow = 0; ent_ents[e].front = FALSE; } } /* * Add a tile-aligned rectangle containing the given rectangle (indicated * by its MAP coordinates) to the list of rectangles. Clip the rectangle * so it fits into the display zone. */ static void ent_addrect(S16 x, S16 y, U16 width, U16 height) { S16 x0, y0; U16 w0, h0; /*sys_printf("rect %#04x,%#04x %#04x %#04x ", x, y, width, height);*/ /* align to tiles */ x0 = x & 0xfff8; y0 = y & 0xfff8; w0 = width; h0 = height; if (x - x0) w0 = (w0 + (x - x0)) | 0x0007; if (y - y0) h0 = (h0 + (y - y0)) | 0x0007; /* clip */ if (draw_clipms(&x0, &y0, &w0, &h0)) { /* do not add if fully clipped */ /*sys_printf("-> [clipped]\n");*/ return; } /*sys_printf("-> %#04x,%#04x %#04x %#04x\n", x0, y0, w0, h0);*/ #if defined(GFXST) || defined(GFXGS) y0 += 8; #endif /* get to screen */ x0 -= DRAW_XYMAP_SCRLEFT; y0 -= DRAW_XYMAP_SCRTOP; /* add rectangle to the list */ ent_rects = rects_new(x0, y0, w0, h0, ent_rects); } /* * Draw all entities onto the frame buffer. * * ASM 07a4 * * NOTE This may need to be part of draw.c. Also needs better comments, * NOTE and probably better rectangles management. */ void ent_draw(void) { #ifdef ENABLE_CHEATS static U8 ch3 = FALSE; #endif S16 dx, dy; ent_t *pEnt; draw_tilesBank = map_tilesBank; /* reset rectangles list */ rects_free(ent_rects); ent_rects = NULL; /*sys_printf("\n");*/ /* * background loop : erase all entities that were visible */ for (pEnt=ent_ents; pEnt->n != 0xff; ++pEnt) { #ifdef ENABLE_CHEATS if (pEnt->prev_n && (ch3 || pEnt->prev_s)) #else if (pEnt->prev_n && pEnt->prev_s) #endif /* if entity was active, then erase it (redraw the map) */ draw_spriteBackground(pEnt->prev_x, pEnt->prev_y); } /* * foreground loop : draw all entities that are visible */ for (pEnt=ent_ents; pEnt->n != 0xff; ++pEnt) { /* * If entity is active now, draw the sprite. If entity was * not active before, add a rectangle for the sprite. */ #ifdef ENABLE_CHEATS if (pEnt->n && (game_cheat3 || pEnt->sprite)) #else if (pEnt->n && pEnt->sprite) #endif /* If entitiy is active, draw the sprite. */ draw_sprite2(pEnt->sprite, pEnt->x, pEnt->y, pEnt->front); } /* * rectangles loop : figure out which parts of the screen have been * impacted and need to be refreshed, then save state */ for (pEnt=ent_ents; pEnt->n != 0xff; ++pEnt) { #ifdef ENABLE_CHEATS if (pEnt->prev_n && (ch3 || pEnt->prev_s)) { #else if (pEnt->prev_n && pEnt->prev_s) { #endif /* (1) if entity was active and has been drawn ... */ #ifdef ENABLE_CHEATS if (pEnt->n && (game_cheat3 || pEnt->sprite)) { #else if (pEnt->n && pEnt->sprite) { #endif /* (1.1) ... and is still active now and still needs to be drawn, */ /* then check if rectangles intersect */ dx = abs(pEnt->x - pEnt->prev_x); dy = abs(pEnt->y - pEnt->prev_y); if (dx < 0x20 && dy < 0x16) { /* (1.1.1) if they do, then create one rectangle */ ent_addrect((pEnt->prev_x < pEnt->x) ? pEnt->prev_x : pEnt->x, (pEnt->prev_y < pEnt->y) ? pEnt->prev_y : pEnt->y, dx + 0x20, dy + 0x15); } else { /* (1.1.2) else, create two rectangles */ ent_addrect(pEnt->x, pEnt->y, 0x20, 0x15); ent_addrect(pEnt->prev_x, pEnt->prev_y, 0x20, 0x15); } } else /* (1.2) ... and is not active anymore or does not need to be drawn */ /* then create one single rectangle */ ent_addrect(pEnt->prev_x, pEnt->prev_y, 0x20, 0x15); } #ifdef ENABLE_CHEATS else if (pEnt->n && (game_cheat3 || pEnt->sprite)) { #else else if (pEnt->n && pEnt->sprite) { #endif /* (2) if entity is active and needs to be drawn, */ /* then create one rectangle */ ent_addrect(pEnt->x, pEnt->y, 0x20, 0x15); } /* save state */ pEnt->prev_x = pEnt->x; pEnt->prev_y = pEnt->y; pEnt->prev_n = pEnt->n; pEnt->prev_s = pEnt->sprite; } #ifdef ENABLE_CHEATS ch3 = game_cheat3; #endif } /* * Clear entities previous state * */ void ent_clprev(void) { U8 i; for (i = 0; ent_ents[i].n != 0xff; i++) ent_ents[i].prev_n = 0; } /* * Table containing entity action function pointers. */ void (*ent_actf[])(ent_t*) = { NULL, /* 00 - zero means that the slot is free */ e_rick_action, /* 01 - 12CA */ e_bullet_action, /* 02 - 1883 */ e_bomb_action, /* 03 - 18CA */ e_them_t1a_action, /* 04 - 2452 */ e_them_t1b_action, /* 05 - 21CA */ e_them_t2_action, /* 06 - 2718 */ e_them_t1a_action, /* 07 - 2452 */ e_them_t1b_action, /* 08 - 21CA */ e_them_t2_action, /* 09 - 2718 */ e_them_t1a_action, /* 0A - 2452 */ e_them_t1b_action, /* 0B - 21CA */ e_them_t2_action, /* 0C - 2718 */ e_them_t1a_action, /* 0D - 2452 */ e_them_t1b_action, /* 0E - 21CA */ e_them_t2_action, /* 0F - 2718 */ e_box_action, /* 10 - 245A */ e_box_action, /* 11 - 245A */ e_bonus_action, /* 12 - 242C */ e_bonus_action, /* 13 - 242C */ e_bonus_action, /* 14 - 242C */ e_bonus_action, /* 15 - 242C */ e_sbonus_start, /* 16 - 2182 */ e_sbonus_stop /* 17 - 2143 */ }; /* * Run entities action function * */ void ent_action(void) { U8 i, k; ent_t* pEnt; IFDEBUG_ENTS( sys_printf("xrick/ents: --------- action ----------------\n"); for (i = 0; ent_ents[i].n != 0xff; i++) if (ent_ents[i].n) { sys_printf("xrick/ents: slot %#04x, entity %#04x", i, ent_ents[i].n); sys_printf(" (%#06x, %#06x), sprite %#04x.\n", ent_ents[i].x, ent_ents[i].y, ent_ents[i].sprite); } ); for (pEnt=ent_ents; pEnt->n != 0xff; ++pEnt) { if (pEnt->n) { k = pEnt->n & 0x7f; if (k == 0x47) e_them_z_action(pEnt); else if (k >= 0x18) e_them_t3_action(pEnt); else ent_actf[k](pEnt); } } } /* eof */ \ No newline at end of file diff --git a/src/game.c b/src/game.c index 5d1616f..7e69305 100644 --- a/src/game.c +++ b/src/game.c @@ -293,7 +293,7 @@ frame(void) while (1) { { - printf("%ld game_state = %s\n", *tick, game_state_strings[game_state]); +// printf("%ld game_state = %s\n", *tick, game_state_strings[game_state]); } @@ -610,8 +610,6 @@ init(void) { U8 i; - printf("game.c: init(void);\n"); - E_RICK_STRST(0xff); game_lives = 6; diff --git a/src/util.c b/src/util.c index 24e8cc9..7a5785f 100644 --- a/src/util.c +++ b/src/util.c @@ -36,12 +36,12 @@ * ret: TRUE/(x,y) is within e's space, FALSE/not. */ U8 -u_fboxtest(U8 e, S16 x, S16 y) +u_fboxtest(ent_t* pEnt, S16 x, S16 y) { - if (ent_ents[e].x >= x || - ent_ents[e].x + ent_ents[e].w < x || - ent_ents[e].y >= y || - ent_ents[e].y + ent_ents[e].h < y) + if (pEnt->x >= x || + pEnt->x + pEnt->w < x || + pEnt->y >= y || + pEnt->y + pEnt->h < y) return FALSE; else return TRUE; @@ -60,20 +60,20 @@ u_fboxtest(U8 e, S16 x, S16 y) * ret: TRUE/intersect, FALSE/not. */ U8 -u_boxtest(U8 e1, U8 e2) +u_boxtest(ent_t* pEnt1, ent_t* pEnt2) { /* rick is special (may be crawling) */ - if (e1 == E_RICK_NO) - return e_rick_boxtest(e2); + if (pEnt1 == &ent_ents[E_RICK_NO]) + return e_rick_boxtest(pEnt2); /* * entity 1: x+0x05 to x+0x011, y to y+0x14 * entity 2: x to x+ .w, y to y+ .h */ - if (ent_ents[e1].x + 0x11 < ent_ents[e2].x || - ent_ents[e1].x + 0x05 > ent_ents[e2].x + ent_ents[e2].w || - ent_ents[e1].y + 0x14 < ent_ents[e2].y || - ent_ents[e1].y > ent_ents[e2].y + ent_ents[e2].h - 1) + if (pEnt1->x + 0x11 < pEnt2->x || + pEnt1->x + 0x05 > pEnt2->x + pEnt2->w || + pEnt1->y + 0x14 < pEnt2->y || + pEnt1->y > pEnt2->y + pEnt2->h - 1) return FALSE; else return TRUE; @@ -175,7 +175,7 @@ u_envtest(S16 x, S16 y, U8 crawl, U8 *rc0, U8 *rc1) */ if (!(*rc1 & MAP_EFLG_LETHAL) && ent_ents[0].n - && u_boxtest(ENT_ENTSNUM, 0)) { + && u_boxtest(&ent_ents[ENT_ENTSNUM], &ent_ents[0])) { *rc1 |= MAP_EFLG_SOLID; } @@ -193,17 +193,19 @@ u_envtest(S16 x, S16 y, U8 crawl, U8 *rc0, U8 *rc1) * return: FALSE if not in box, TRUE if in box. */ U8 -u_trigbox(U8 e, S16 x, S16 y) +u_trigbox(ent_t* pEnt, S16 x, S16 y) { U16 xmax, ymax; - xmax = ent_ents[e].trig_x + (ent_entdata[ent_ents[e].n & 0x7F].trig_w << 3); - ymax = ent_ents[e].trig_y + (ent_entdata[ent_ents[e].n & 0x7F].trig_h << 3); + //printf("u_trigbox e=%d x=%d y=%d ", e, x, y); + + xmax = pEnt->trig_x + (ent_entdata[pEnt->n & 0x7F].trig_w << 3); + ymax = pEnt->trig_y + (ent_entdata[pEnt->n & 0x7F].trig_h << 3); if (xmax > 0xFF) xmax = 0xFF; - if (x <= ent_ents[e].trig_x || x > xmax || - y <= ent_ents[e].trig_y || y > ymax) + if (x <= pEnt->trig_x || x > xmax || + y <= pEnt->trig_y || y > ymax) return FALSE; else return TRUE;