objectify AGI sprite.h/cpp

svn-id: r22781
This commit is contained in:
Chris Apers 2006-05-30 18:53:01 +00:00
parent 148995dc2d
commit cbfc7bfc1a
8 changed files with 172 additions and 136 deletions

View file

@ -513,7 +513,7 @@ void AgiEngine::initialize() {
game.sbuf = (uint8 *) calloc(_WIDTH, _HEIGHT); game.sbuf = (uint8 *) calloc(_WIDTH, _HEIGHT);
game.hires = (uint8 *) calloc(_WIDTH * 2, _HEIGHT); game.hires = (uint8 *) calloc(_WIDTH * 2, _HEIGHT);
init_sprites(); _sprites = new SpritesMan;
init_video(); init_video();
tick_timer = 0; tick_timer = 0;
@ -539,7 +539,7 @@ AgiEngine::~AgiEngine() {
delete g_agi_music; delete g_agi_music;
deinit_sound(); deinit_sound();
deinit_video(); deinit_video();
deinit_sprites(); delete _sprites;
free(game.hires); free(game.hires);
free(game.sbuf); free(game.sbuf);
deinit_machine(); deinit_machine();

View file

@ -218,11 +218,11 @@ int main_cycle() {
} }
if (key == KEY_PRIORITY) { if (key == KEY_PRIORITY) {
erase_both(); _sprites->erase_both();
debug_.priority = !debug_.priority; debug_.priority = !debug_.priority;
show_pic(); show_pic();
blit_both(); _sprites->blit_both();
commit_both(); _sprites->commit_both();
key = 0; key = 0;
} }

View file

@ -400,11 +400,11 @@ cmd(status_line_off) {
} }
cmd(show_obj) { cmd(show_obj) {
show_obj(p0); _sprites->show_obj(p0);
} }
cmd(show_obj_v) { cmd(show_obj_v) {
show_obj(_v[p0]); _sprites->show_obj(_v[p0]);
} }
cmd(sound) { cmd(sound) {
@ -558,9 +558,9 @@ cmd(call_f) {
cmd(draw_pic) { cmd(draw_pic) {
debugC(6, kDebugLevelScripts, "=== draw pic %d ===", _v[p0]); debugC(6, kDebugLevelScripts, "=== draw pic %d ===", _v[p0]);
erase_both(); _sprites->erase_both();
decode_picture(_v[p0], true); decode_picture(_v[p0], true);
blit_both(); _sprites->blit_both();
game.picture_shown = 0; game.picture_shown = 0;
debugC(6, kDebugLevelScripts, "--- end of draw pic %d ---", _v[p0]); debugC(6, kDebugLevelScripts, "--- end of draw pic %d ---", _v[p0]);
} }
@ -575,9 +575,9 @@ cmd(show_pic) {
} }
cmd(load_pic) { cmd(load_pic) {
erase_both(); _sprites->erase_both();
agi_load_resource(rPICTURE, _v[p0]); agi_load_resource(rPICTURE, _v[p0]);
blit_both(); _sprites->blit_both();
} }
cmd(discard_pic) { cmd(discard_pic) {
@ -587,23 +587,23 @@ cmd(discard_pic) {
cmd(overlay_pic) { cmd(overlay_pic) {
debugC(6, kDebugLevelScripts, "--- overlay pic ---"); debugC(6, kDebugLevelScripts, "--- overlay pic ---");
erase_both(); _sprites->erase_both();
decode_picture(_v[p0], false); decode_picture(_v[p0], false);
blit_both(); _sprites->blit_both();
game.picture_shown = 0; game.picture_shown = 0;
commit_both(); _sprites->commit_both();
} }
cmd(show_pri_screen) { cmd(show_pri_screen) {
debug_.priority = 1; debug_.priority = 1;
erase_both(); _sprites->erase_both();
show_pic(); show_pic();
blit_both(); _sprites->blit_both();
wait_key(); wait_key();
debug_.priority = 0; debug_.priority = 0;
erase_both(); _sprites->erase_both();
show_pic(); show_pic();
blit_both(); _sprites->blit_both();
} }
cmd(animate_obj) { cmd(animate_obj) {
@ -641,16 +641,16 @@ cmd(draw) {
vt.x_pos2 = vt.x_pos; vt.x_pos2 = vt.x_pos;
vt.y_pos2 = vt.y_pos; vt.y_pos2 = vt.y_pos;
vt.cel_data_2 = vt.cel_data; vt.cel_data_2 = vt.cel_data;
erase_upd_sprites(); _sprites->erase_upd_sprites();
vt.flags |= DRAWN; vt.flags |= DRAWN;
if (agi_get_release() <= 0x2440) /* See bug #546562 */ if (agi_get_release() <= 0x2440) /* See bug #546562 */
vt.flags |= ANIMATED; vt.flags |= ANIMATED;
blit_upd_sprites(); _sprites->blit_upd_sprites();
vt.flags &= ~DONTUPDATE; vt.flags &= ~DONTUPDATE;
commit_block(vt.x_pos, vt.y_pos - vt.y_size + 1, vt.x_pos + vt.x_size - 1, vt.y_pos); _sprites->commit_block(vt.x_pos, vt.y_pos - vt.y_size + 1, vt.x_pos + vt.x_size - 1, vt.y_pos);
debugC(4, kDebugLevelScripts, "vt entry #%d flags = %02x", p0, vt.flags); debugC(4, kDebugLevelScripts, "vt entry #%d flags = %02x", p0, vt.flags);
} }
@ -659,17 +659,17 @@ cmd(erase) {
if (~vt.flags & DRAWN) if (~vt.flags & DRAWN)
return; return;
erase_upd_sprites(); _sprites->erase_upd_sprites();
if (vt.flags & UPDATE) { if (vt.flags & UPDATE) {
vt.flags &= ~DRAWN; vt.flags &= ~DRAWN;
} else { } else {
erase_nonupd_sprites(); _sprites->erase_nonupd_sprites();
vt.flags &= ~DRAWN; vt.flags &= ~DRAWN;
blit_nonupd_sprites(); _sprites->blit_nonupd_sprites();
} }
blit_upd_sprites(); _sprites->blit_upd_sprites();
commit_block(vt.x_pos, vt.y_pos - vt.y_size + 1, vt.x_pos + vt.x_size - 1, vt.y_pos); _sprites->commit_block(vt.x_pos, vt.y_pos - vt.y_size + 1, vt.x_pos + vt.x_size - 1, vt.y_pos);
} }
cmd(position) { cmd(position) {
@ -721,17 +721,17 @@ cmd(reposition_to_f) {
} }
cmd(add_to_pic) { cmd(add_to_pic) {
add_to_pic(p0, p1, p2, p3, p4, p5, p6); _sprites->add_to_pic(p0, p1, p2, p3, p4, p5, p6);
} }
cmd(add_to_pic_f) { cmd(add_to_pic_f) {
add_to_pic(_v[p0], _v[p1], _v[p2], _v[p3], _v[p4], _v[p5], _v[p6]); _sprites->add_to_pic(_v[p0], _v[p1], _v[p2], _v[p3], _v[p4], _v[p5], _v[p6]);
} }
cmd(force_update) { cmd(force_update) {
erase_both(); _sprites->erase_both();
blit_both(); _sprites->blit_both();
commit_both(); _sprites->commit_both();
} }
cmd(reverse_loop) { cmd(reverse_loop) {
@ -1216,7 +1216,7 @@ cmd(shake_screen) {
} else } else
shake_start(); shake_start();
commit_both(); /* Fixes SQ1 demo */ _sprites->commit_both(); /* Fixes SQ1 demo */
for (i = 4 * p0; i; i--) { for (i = 4 * p0; i; i--) {
shake_screen(i & 1); shake_screen(i & 1);
flush_block(0, 0, GFX_WIDTH - 1, GFX_HEIGHT - 1); flush_block(0, 0, GFX_WIDTH - 1, GFX_HEIGHT - 1);
@ -1444,11 +1444,11 @@ int run_logic(int n) {
debug_.steps--; debug_.steps--;
} }
} else { } else {
blit_both(); _sprites->blit_both();
do { do {
main_cycle(); main_cycle();
} while (!debug_.steps && debug_.enabled); } while (!debug_.steps && debug_.enabled);
erase_both(); _sprites->erase_both();
} }
} }

View file

@ -117,7 +117,7 @@ void replay_image_stack_call(uint8 type, int16 p1, int16 p2, int16 p3,
break; break;
case ADD_VIEW: case ADD_VIEW:
agi_load_resource(rVIEW, p1); agi_load_resource(rVIEW, p1);
add_to_pic(p1, p2, p3, p4, p5, p6, p7); _sprites->add_to_pic(p1, p2, p3, p4, p5, p6, p7);
break; break;
} }
} }
@ -544,7 +544,7 @@ int load_game(char *s) {
v->s = NULL; /* not sure if it is used... */ v->s = NULL; /* not sure if it is used... */
} }
erase_both(); _sprites->erase_both();
/* Clear input line */ /* Clear input line */
clear_screen(0); clear_screen(0);
@ -566,9 +566,9 @@ int load_game(char *s) {
game.has_prompt = 0; /* force input line repaint if necessary */ game.has_prompt = 0; /* force input line repaint if necessary */
clean_input(); clean_input();
erase_both(); _sprites->erase_both();
blit_both(); _sprites->blit_both();
commit_both(); _sprites->commit_both();
show_pic(); show_pic();
do_update(); do_update();
@ -725,7 +725,7 @@ int loadgame_simple() {
sprintf(path, "%s/%05X_%s_%02d.sav", _savePath, game.crc, game.id, 0); sprintf(path, "%s/%05X_%s_%02d.sav", _savePath, game.crc, game.id, 0);
erase_both(); _sprites->erase_both();
stop_sound(); stop_sound();
close_window(); close_window();
@ -754,7 +754,7 @@ int loadgame_dialog() {
sprintf(path, "%s/%05X_%s_%02d.sav", _savePath, game.crc, game.id, slot); sprintf(path, "%s/%05X_%s_%02d.sav", _savePath, game.crc, game.id, slot);
erase_both(); _sprites->erase_both();
stop_sound(); stop_sound();
draw_window(hp, vp, GFX_WIDTH - hp, GFX_HEIGHT - vp); draw_window(hp, vp, GFX_WIDTH - hp, GFX_HEIGHT - vp);

View file

@ -27,25 +27,10 @@
#include "agi/graphics.h" #include "agi/graphics.h"
#include "agi/text.h" #include "agi/text.h"
#include "agi/savegame.h" #include "agi/savegame.h"
#include "common/list.h"
namespace Agi { namespace Agi {
/** SpritesMan *_sprites;
* Sprite structure.
* This structure holds information on visible and priority data of
* a rectangular area of the AGI screen. Sprites are chained in two
* circular lists, one for updating and other for non-updating sprites.
*/
struct sprite {
vt_entry *v; /**< pointer to view table entry */
int16 x_pos; /**< x coordinate of the sprite */
int16 y_pos; /**< y coordinate of the sprite */
int16 x_size; /**< width of the sprite */
int16 y_size; /**< height of the sprite */
uint8 *buffer; /**< buffer to store background data */
uint8 *hires; /**< buffer for hi-res background */
};
/* /*
* Sprite pool replaces dynamic allocation * Sprite pool replaces dynamic allocation
@ -53,11 +38,8 @@ struct sprite {
#undef ALLOC_DEBUG #undef ALLOC_DEBUG
#define POOL_SIZE 68000 /* Gold Rush mine room needs > 50000 */ #define POOL_SIZE 68000 /* Gold Rush mine room needs > 50000 */
/* Speeder bike challenge needs > 67000 */
static uint8 *sprite_pool;
static uint8 *pool_top;
static void *pool_alloc(int size) { void *SpritesMan::pool_alloc(int size) {
uint8 *x; uint8 *x;
/* Adjust size to 32-bit boundary to prevent data misalignment /* Adjust size to 32-bit boundary to prevent data misalignment
@ -80,7 +62,7 @@ static void *pool_alloc(int size) {
/* Note: it's critical that pool_release() is called in the exact /* Note: it's critical that pool_release() is called in the exact
reverse order of pool_alloc() reverse order of pool_alloc()
*/ */
static void pool_release(void *s) { void SpritesMan::pool_release(void *s) {
pool_top = (uint8 *)s; pool_top = (uint8 *)s;
} }
@ -90,7 +72,7 @@ static void pool_release(void *s) {
/* Blit one pixel considering the priorities */ /* Blit one pixel considering the priorities */
static void blit_pixel(uint8 *p, uint8 *end, uint8 col, int spr, int width, int *hidden) { void SpritesMan::blit_pixel(uint8 *p, uint8 *end, uint8 col, int spr, int width, int *hidden) {
int epr = 0, pr = 0; /* effective and real priorities */ int epr = 0, pr = 0; /* effective and real priorities */
/* CM: priority 15 overrides control lines and is ignored when /* CM: priority 15 overrides control lines and is ignored when
@ -138,7 +120,7 @@ static void blit_pixel(uint8 *p, uint8 *end, uint8 col, int spr, int width, int
#define X_FACT 2 /* Horizontal hires factor */ #define X_FACT 2 /* Horizontal hires factor */
static int blit_hires_cel(int x, int y, int spr, view_cel *c) { int SpritesMan::blit_hires_cel(int x, int y, int spr, view_cel *c) {
uint8 *q = NULL; uint8 *q = NULL;
uint8 *h0, *h, *end; uint8 *h0, *h, *end;
int i, j, t, m, col; int i, j, t, m, col;
@ -170,7 +152,7 @@ static int blit_hires_cel(int x, int y, int spr, view_cel *c) {
return hidden; return hidden;
} }
static int blit_cel(int x, int y, int spr, view_cel *c) { int SpritesMan::blit_cel(int x, int y, int spr, view_cel *c) {
uint8 *p0, *p, *q = NULL, *end; uint8 *p0, *p, *q = NULL, *end;
int i, j, t, m, col; int i, j, t, m, col;
int hidden = true; int hidden = true;
@ -214,7 +196,7 @@ static int blit_cel(int x, int y, int spr, view_cel *c) {
return hidden; return hidden;
} }
static void objs_savearea(sprite *s) { void SpritesMan::objs_savearea(sprite *s) {
int y; int y;
int16 x_pos = s->x_pos, y_pos = s->y_pos; int16 x_pos = s->x_pos, y_pos = s->y_pos;
int16 x_size = s->x_size, y_size = s->y_size; int16 x_size = s->x_size, y_size = s->y_size;
@ -254,7 +236,7 @@ static void objs_savearea(sprite *s) {
} }
} }
static void objs_restorearea(sprite *s) { void SpritesMan::objs_restorearea(sprite *s) {
int y, offset; int y, offset;
int16 x_pos = s->x_pos, y_pos = s->y_pos; int16 x_pos = s->x_pos, y_pos = s->y_pos;
int16 x_size = s->x_size, y_size = s->y_size; int16 x_size = s->x_size, y_size = s->y_size;
@ -299,19 +281,11 @@ static void objs_restorearea(sprite *s) {
} }
} }
/*
* Sprite management functions
*/
typedef Common::List<sprite*> SpriteList;
static SpriteList spr_upd;
static SpriteList spr_nonupd;
/** /**
* Condition to determine whether a sprite will be in the 'updating' list. * Condition to determine whether a sprite will be in the 'updating' list.
*/ */
static int test_updating(vt_entry *v) { int SpritesMan::test_updating(vt_entry *v) {
/* Sanity check (see bug #779302) */ /* Sanity check (see bug #779302) */
if (~game.dir_view[v->current_view].flags & RES_LOADED) if (~game.dir_view[v->current_view].flags & RES_LOADED)
return 0; return 0;
@ -322,7 +296,7 @@ static int test_updating(vt_entry *v) {
/** /**
* Condition to determine whether a sprite will be in the 'non-updating' list. * Condition to determine whether a sprite will be in the 'non-updating' list.
*/ */
static int test_not_updating(vt_entry *v) { int SpritesMan::test_not_updating(vt_entry *v) {
/* Sanity check (see bug #779302) */ /* Sanity check (see bug #779302) */
if (~game.dir_view[v->current_view].flags & RES_LOADED) if (~game.dir_view[v->current_view].flags & RES_LOADED)
return 0; return 0;
@ -333,7 +307,7 @@ static int test_not_updating(vt_entry *v) {
/** /**
* Convert sprite priority to y value. * Convert sprite priority to y value.
*/ */
static INLINE int prio_to_y(int p) { INLINE int SpritesMan::prio_to_y(int p) {
int i; int i;
if (p == 0) if (p == 0)
@ -350,7 +324,7 @@ static INLINE int prio_to_y(int p) {
/** /**
* Create and initialize a new sprite structure. * Create and initialize a new sprite structure.
*/ */
static sprite *new_sprite(vt_entry *v) { sprite *SpritesMan::new_sprite(vt_entry *v) {
sprite *s; sprite *s;
s = (sprite *)pool_alloc(sizeof(sprite)); s = (sprite *)pool_alloc(sizeof(sprite));
if (s == NULL) if (s == NULL)
@ -371,7 +345,7 @@ static sprite *new_sprite(vt_entry *v) {
/** /**
* Insert sprite in the specified sprite list. * Insert sprite in the specified sprite list.
*/ */
static void spr_addlist(SpriteList& l, vt_entry *v) { void SpritesMan::spr_addlist(SpriteList& l, vt_entry *v) {
sprite *s = new_sprite(v); sprite *s = new_sprite(v);
l.push_back(s); l.push_back(s);
} }
@ -379,7 +353,7 @@ static void spr_addlist(SpriteList& l, vt_entry *v) {
/** /**
* Sort sprites from lower y values to build a sprite list. * Sort sprites from lower y values to build a sprite list.
*/ */
static void build_list(SpriteList& l, int (*test) (vt_entry *)) { void SpritesMan::build_list(SpriteList& l, int (SpritesMan::*test) (vt_entry *)) {
int i, j, k; int i, j, k;
vt_entry *v; vt_entry *v;
vt_entry *entry[0x100]; vt_entry *entry[0x100];
@ -391,7 +365,7 @@ static void build_list(SpriteList& l, int (*test) (vt_entry *)) {
*/ */
i = 0; i = 0;
for (v = game.view_table; v < &game.view_table[MAX_VIEWTABLE]; v++) { for (v = game.view_table; v < &game.view_table[MAX_VIEWTABLE]; v++) {
if (test(v)) { if ((this->*(test))(v)) {
entry[i] = v; entry[i] = v;
y_val[i] = v->flags & FIXED_PRIORITY ? prio_to_y(v->priority) : v->y_pos; y_val[i] = v->flags & FIXED_PRIORITY ? prio_to_y(v->priority) : v->y_pos;
i++; i++;
@ -418,21 +392,21 @@ static void build_list(SpriteList& l, int (*test) (vt_entry *)) {
/** /**
* Build list of updating sprites. * Build list of updating sprites.
*/ */
static void build_upd_blitlist() { void SpritesMan::build_upd_blitlist() {
build_list(spr_upd, test_updating); build_list(spr_upd, test_updating);
} }
/** /**
* Build list of non-updating sprites. * Build list of non-updating sprites.
*/ */
static void build_nonupd_blitlist() { void SpritesMan::build_nonupd_blitlist() {
build_list(spr_nonupd, test_not_updating); build_list(spr_nonupd, test_not_updating);
} }
/** /**
* Clear the given sprite list. * Clear the given sprite list.
*/ */
static void free_list(SpriteList& l) { void SpritesMan::free_list(SpriteList& l) {
SpriteList::iterator iter; SpriteList::iterator iter;
for (iter = l.reverse_begin(); iter != l.end(); ) { for (iter = l.reverse_begin(); iter != l.end(); ) {
sprite* s = *iter; sprite* s = *iter;
@ -447,7 +421,7 @@ static void free_list(SpriteList& l) {
* Copy sprites from the pic buffer to the screen buffer, and check if * Copy sprites from the pic buffer to the screen buffer, and check if
* sprites of the given list have moved. * sprites of the given list have moved.
*/ */
static void commit_sprites(SpriteList& l) { void SpritesMan::commit_sprites(SpriteList& l) {
SpriteList::iterator iter; SpriteList::iterator iter;
for (iter = l.begin(); iter != l.end(); ++iter) { for (iter = l.begin(); iter != l.end(); ++iter) {
sprite *s = *iter; sprite *s = *iter;
@ -497,7 +471,7 @@ static void commit_sprites(SpriteList& l) {
/** /**
* Erase all sprites in the given list. * Erase all sprites in the given list.
*/ */
static void erase_sprites(SpriteList& l) { void SpritesMan::erase_sprites(SpriteList& l) {
SpriteList::iterator iter; SpriteList::iterator iter;
for (iter = l.reverse_begin(); iter != l.end(); --iter) { for (iter = l.reverse_begin(); iter != l.end(); --iter) {
sprite *s = *iter; sprite *s = *iter;
@ -510,7 +484,7 @@ static void erase_sprites(SpriteList& l) {
/** /**
* Blit all sprites in the given list. * Blit all sprites in the given list.
*/ */
static void blit_sprites(SpriteList& l) { void SpritesMan::blit_sprites(SpriteList& l) {
int hidden; int hidden;
SpriteList::iterator iter; SpriteList::iterator iter;
for (iter = l.begin(); iter != l.end(); ++iter) { for (iter = l.begin(); iter != l.end(); ++iter) {
@ -528,16 +502,16 @@ static void blit_sprites(SpriteList& l) {
* Public functions * Public functions
*/ */
void commit_upd_sprites() { void SpritesMan::commit_upd_sprites() {
commit_sprites(spr_upd); commit_sprites(spr_upd);
} }
void commit_nonupd_sprites() { void SpritesMan::commit_nonupd_sprites() {
commit_sprites(spr_nonupd); commit_sprites(spr_nonupd);
} }
/* check moves in both lists */ /* check moves in both lists */
void commit_both() { void SpritesMan::commit_both() {
commit_upd_sprites(); commit_upd_sprites();
commit_nonupd_sprites(); commit_nonupd_sprites();
} }
@ -551,7 +525,7 @@ void commit_both() {
* @see erase_nonupd_sprites() * @see erase_nonupd_sprites()
* @see erase_both() * @see erase_both()
*/ */
void erase_upd_sprites() { void SpritesMan::erase_upd_sprites() {
erase_sprites(spr_upd); erase_sprites(spr_upd);
} }
@ -564,7 +538,7 @@ void erase_upd_sprites() {
* @see erase_upd_sprites() * @see erase_upd_sprites()
* @see erase_both() * @see erase_both()
*/ */
void erase_nonupd_sprites() { void SpritesMan::erase_nonupd_sprites() {
erase_sprites(spr_nonupd); erase_sprites(spr_nonupd);
} }
@ -577,7 +551,7 @@ void erase_nonupd_sprites() {
* @see erase_upd_sprites() * @see erase_upd_sprites()
* @see erase_nonupd_sprites() * @see erase_nonupd_sprites()
*/ */
void erase_both() { void SpritesMan::erase_both() {
erase_upd_sprites(); erase_upd_sprites();
erase_nonupd_sprites(); erase_nonupd_sprites();
} }
@ -590,7 +564,7 @@ void erase_both() {
* @see blit_nonupd_sprites() * @see blit_nonupd_sprites()
* @see blit_both() * @see blit_both()
*/ */
void blit_upd_sprites() { void SpritesMan::blit_upd_sprites() {
debugC(7, kDebugLevelSprites, "blit updating"); debugC(7, kDebugLevelSprites, "blit updating");
build_upd_blitlist(); build_upd_blitlist();
blit_sprites(spr_upd); blit_sprites(spr_upd);
@ -604,7 +578,7 @@ void blit_upd_sprites() {
* @see blit_upd_sprites() * @see blit_upd_sprites()
* @see blit_both() * @see blit_both()
*/ */
void blit_nonupd_sprites() { void SpritesMan::blit_nonupd_sprites() {
debugC(7, kDebugLevelSprites, "blit non-updating"); debugC(7, kDebugLevelSprites, "blit non-updating");
build_nonupd_blitlist(); build_nonupd_blitlist();
blit_sprites(spr_nonupd); blit_sprites(spr_nonupd);
@ -618,7 +592,7 @@ void blit_nonupd_sprites() {
* @see blit_upd_sprites() * @see blit_upd_sprites()
* @see blit_nonupd_sprites() * @see blit_nonupd_sprites()
*/ */
void blit_both() { void SpritesMan::blit_both() {
blit_nonupd_sprites(); blit_nonupd_sprites();
blit_upd_sprites(); blit_upd_sprites();
} }
@ -636,7 +610,7 @@ void blit_both() {
* @param pri priority to use * @param pri priority to use
* @param mar if < 4, create a margin around the the base of the cel * @param mar if < 4, create a margin around the the base of the cel
*/ */
void add_to_pic(int view, int loop, int cel, int x, int y, int pri, int mar) { void SpritesMan::add_to_pic(int view, int loop, int cel, int x, int y, int pri, int mar) {
view_cel *c = NULL; view_cel *c = NULL;
int x1, y1, x2, y2, y3; int x1, y1, x2, y2, y3;
uint8 *p1, *p2; uint8 *p1, *p2;
@ -727,7 +701,7 @@ void add_to_pic(int view, int loop, int cel, int x, int y, int pri, int mar) {
* a message box with the object description. * a message box with the object description.
* @param n Number of the object to show * @param n Number of the object to show
*/ */
void show_obj(int n) { void SpritesMan::show_obj(int n) {
view_cel *c; view_cel *c;
sprite s; sprite s;
int x1, y1, x2, y2; int x1, y1, x2, y2;
@ -761,7 +735,7 @@ void show_obj(int n) {
free(s.hires); free(s.hires);
} }
void commit_block(int x1, int y1, int x2, int y2) { void SpritesMan::commit_block(int x1, int y1, int x2, int y2) {
int i, w, offset; int i, w, offset;
uint8 *q; uint8 *q;
uint8 *h; uint8 *h;
@ -805,16 +779,17 @@ void commit_block(int x1, int y1, int x2, int y2) {
flush_block_a(x1, y1 + offset, x2, y2 + offset); flush_block_a(x1, y1 + offset, x2, y2 + offset);
} }
int init_sprites() { SpritesMan::SpritesMan() {
if ((sprite_pool = (uint8 *)malloc(POOL_SIZE)) == NULL) // if ((sprite_pool = (uint8 *)malloc(POOL_SIZE)) == NULL)
return err_NotEnoughMemory; // return err_NotEnoughMemory;
sprite_pool = (uint8 *)malloc(POOL_SIZE);
pool_top = sprite_pool; pool_top = sprite_pool;
return err_OK; // return err_OK;
} }
void deinit_sprites() { SpritesMan::~SpritesMan() {
free(sprite_pool); free(sprite_pool);
} }

View file

@ -25,22 +25,83 @@
#ifndef AGI_SPRITE_H #ifndef AGI_SPRITE_H
#define AGI_SPRITE_H #define AGI_SPRITE_H
#include "common/list.h"
namespace Agi { namespace Agi {
int init_sprites(void); /**
void deinit_sprites(void); * Sprite structure.
void erase_upd_sprites(void); * This structure holds information on visible and priority data of
void erase_nonupd_sprites(void); * a rectangular area of the AGI screen. Sprites are chained in two
void erase_both(void); * circular lists, one for updating and other for non-updating sprites.
void blit_upd_sprites(void); */
void blit_nonupd_sprites(void); struct sprite {
void blit_both(void); vt_entry *v; /**< pointer to view table entry */
void commit_upd_sprites(void); int16 x_pos; /**< x coordinate of the sprite */
void commit_nonupd_sprites(void); int16 y_pos; /**< y coordinate of the sprite */
void commit_both(void); int16 x_size; /**< width of the sprite */
void add_to_pic(int, int, int, int, int, int, int); int16 y_size; /**< height of the sprite */
void show_obj(int); uint8 *buffer; /**< buffer to store background data */
void commit_block(int, int, int, int); uint8 *hires; /**< buffer for hi-res background */
};
typedef Common::List<sprite*> SpriteList;
class SpritesMan {
private:
/* Speeder bike challenge needs > 67000 */
uint8 *sprite_pool;
uint8 *pool_top;
/*
* Sprite management functions
*/
SpriteList spr_upd;
SpriteList spr_nonupd;
void *pool_alloc(int size);
void pool_release(void *s);
void blit_pixel(uint8 *p, uint8 *end, uint8 col, int spr, int width, int *hidden);
int blit_hires_cel(int x, int y, int spr, view_cel *c);
int blit_cel(int x, int y, int spr, view_cel *c);
void objs_savearea(sprite *s);
void objs_restorearea(sprite *s);
int test_updating(vt_entry *v);
int test_not_updating(vt_entry *v);
FORCEINLINE int prio_to_y(int p);
sprite *new_sprite(vt_entry *v);
void spr_addlist(SpriteList& l, vt_entry *v);
void build_list(SpriteList& l, int (SpritesMan::*test) (vt_entry *));
void build_upd_blitlist();
void build_nonupd_blitlist();
void free_list(SpriteList& l);
void commit_sprites(SpriteList& l);
void erase_sprites(SpriteList& l);
void blit_sprites(SpriteList& l);
public:
SpritesMan();
~SpritesMan();
int init_sprites(void);
void deinit_sprites(void);
void erase_upd_sprites(void);
void erase_nonupd_sprites(void);
void erase_both(void);
void blit_upd_sprites(void);
void blit_nonupd_sprites(void);
void blit_both(void);
void commit_upd_sprites(void);
void commit_nonupd_sprites(void);
void commit_both(void);
void add_to_pic(int, int, int, int, int, int, int);
void show_obj(int);
void commit_block(int, int, int, int);
};
extern SpritesMan *_sprites;
} // End of namespace Agi } // End of namespace Agi

View file

@ -277,10 +277,10 @@ char *word_wrap_string(char *str, int *len) {
*/ */
void close_window() { void close_window() {
debugC(4, kDebugLevelText, "close window"); debugC(4, kDebugLevelText, "close window");
erase_both(); _sprites->erase_both();
erase_textbox(); /* remove window, if any */ erase_textbox(); /* remove window, if any */
blit_both(); _sprites->blit_both();
commit_both(); /* redraw sprites */ _sprites->commit_both(); /* redraw sprites */
game.has_window = false; game.has_window = false;
} }
@ -293,9 +293,9 @@ void close_window() {
int message_box(const char *s) { int message_box(const char *s) {
int k; int k;
erase_both(); _sprites->erase_both();
blit_textbox(s, -1, -1, -1); blit_textbox(s, -1, -1, -1);
blit_both(); _sprites->blit_both();
k = wait_key(); k = wait_key();
debugC(4, kDebugLevelText, "wait_key returned %02x", k); debugC(4, kDebugLevelText, "wait_key returned %02x", k);
close_window(); close_window();
@ -316,7 +316,7 @@ int selection_box(const char *m, const char **b) {
int rc = -1; int rc = -1;
int bx[5], by[5]; int bx[5], by[5];
erase_both(); _sprites->erase_both();
blit_textbox(m, -1, -1, -1); blit_textbox(m, -1, -1, -1);
x = game.window.x1 + 5 * CHAR_COLS / 2; x = game.window.x1 + 5 * CHAR_COLS / 2;
@ -342,7 +342,7 @@ int selection_box(const char *m, const char **b) {
x += CHAR_COLS * strlen(b[i]) + s; x += CHAR_COLS * strlen(b[i]) + s;
} }
blit_both(); _sprites->blit_both();
/* clear key queue */ /* clear key queue */
while (keypress()) { while (keypress()) {

View file

@ -212,9 +212,9 @@ void unload_view(int n) {
return; return;
/* Rebuild sprite list, see bug #779302 */ /* Rebuild sprite list, see bug #779302 */
erase_both(); _sprites->erase_both();
blit_both(); _sprites->blit_both();
commit_both(); _sprites->commit_both();
/* free all the loops */ /* free all the loops */
for (x = 0; x < game.views[n].num_loops; x++) for (x = 0; x < game.views[n].num_loops; x++)
@ -282,9 +282,9 @@ void set_view(vt_entry *v, int n) {
*/ */
void start_update(vt_entry *v) { void start_update(vt_entry *v) {
if (~v->flags & UPDATE) { if (~v->flags & UPDATE) {
erase_both(); _sprites->erase_both();
v->flags |= UPDATE; v->flags |= UPDATE;
blit_both(); _sprites->blit_both();
} }
} }
@ -294,9 +294,9 @@ void start_update(vt_entry *v) {
*/ */
void stop_update(vt_entry *v) { void stop_update(vt_entry *v) {
if (v->flags & UPDATE) { if (v->flags & UPDATE) {
erase_both(); _sprites->erase_both();
v->flags &= ~UPDATE; v->flags &= ~UPDATE;
blit_both(); _sprites->blit_both();
} }
} }
@ -367,10 +367,10 @@ void update_viewtable() {
} }
if (i) { if (i) {
erase_upd_sprites(); _sprites->erase_upd_sprites();
update_position(); update_position();
blit_upd_sprites(); _sprites->blit_upd_sprites();
commit_upd_sprites(); _sprites->commit_upd_sprites();
game.view_table[0].flags &= ~(ON_WATER | ON_LAND); game.view_table[0].flags &= ~(ON_WATER | ON_LAND);
} }
} }