diff options
author | Paweł Kołodziejski | 2006-12-06 19:27:02 +0000 |
---|---|---|
committer | Paweł Kołodziejski | 2006-12-06 19:27:02 +0000 |
commit | 1d3ca2e40908ababd16fe8b1c9070198f9b75c82 (patch) | |
tree | 3c38e45040b1bbd97694b6eaf0ea4dec6f460753 /engines | |
parent | 1a85adfa833e78d4460e89ff5db1c6bc8688b048 (diff) | |
download | scummvm-rg350-1d3ca2e40908ababd16fe8b1c9070198f9b75c82.tar.gz scummvm-rg350-1d3ca2e40908ababd16fe8b1c9070198f9b75c82.tar.bz2 scummvm-rg350-1d3ca2e40908ababd16fe8b1c9070198f9b75c82.zip |
first phase of objectisation of agi engine
svn-id: r24808
Diffstat (limited to 'engines')
39 files changed, 1848 insertions, 1742 deletions
diff --git a/engines/agi/agi.cpp b/engines/agi/agi.cpp index 4f331839e3..ee71c73da8 100644 --- a/engines/agi/agi.cpp +++ b/engines/agi/agi.cpp @@ -43,78 +43,54 @@ #include "agi/keyboard.h" #include "agi/menu.h" #include "agi/savegame.h" +#include "agi/sound.h" namespace Agi { -void gfx_set_palette(); +static uint32 g_tick_timer; +struct Mouse g_mouse; -extern int optind; +#define key_enqueue(k) do { _key_queue[_key_queue_end++] = (k); \ + _key_queue_end %= KEY_QUEUE_SIZE; } while (0) +#define key_dequeue(k) do { (k) = _key_queue[_key_queue_start++]; \ + _key_queue_start %= KEY_QUEUE_SIZE; } while (0) -struct agi_options opt; -struct game_id_list game_info; -struct agi_game game; - -static struct agi_loader *loader; /* loader */ - -extern struct agi_loader agi_v2; -extern struct agi_loader agi_v3; - -static volatile uint32 tick_timer = 0; - -#define TICK_SECONDS 20 - -static int key_control = 0; -static int key_alt = 0; - -static Console *_console; - -#define KEY_QUEUE_SIZE 16 - -static int key_queue[KEY_QUEUE_SIZE]; -static int key_queue_start = 0; -static int key_queue_end = 0; - -#define key_enqueue(k) do { key_queue[key_queue_end++] = (k); \ - key_queue_end %= KEY_QUEUE_SIZE; } while (0) -#define key_dequeue(k) do { (k) = key_queue[key_queue_start++]; \ - key_queue_start %= KEY_QUEUE_SIZE; } while (0) - -static void process_events() { +void AgiEngine::processEvents() { OSystem::Event event; int key = 0; while (g_system->pollEvent(event)) { switch (event.type) { case OSystem::EVENT_QUIT: - deinit_video(); - deinit_machine(); + _gfx->deinitVideo(); + _gfx->deinitMachine(); g_system->quit(); break; case OSystem::EVENT_LBUTTONDOWN: key = BUTTON_LEFT; - mouse.button = 1; + g_mouse.button = 1; key_enqueue(key); - mouse.x = event.mouse.x; - mouse.y = event.mouse.y; + g_mouse.x = event.mouse.x; + g_mouse.y = event.mouse.y; break; case OSystem::EVENT_RBUTTONDOWN: key = BUTTON_RIGHT; - mouse.button = 2; + g_mouse.button = 2; key_enqueue(key); - mouse.x = event.mouse.x; - mouse.y = event.mouse.y; + g_mouse.x = event.mouse.x; + g_mouse.y = event.mouse.y; break; case OSystem::EVENT_MOUSEMOVE: - mouse.x = event.mouse.x; - mouse.y = event.mouse.y; + g_mouse.x = event.mouse.x; + g_mouse.y = event.mouse.y; break; case OSystem::EVENT_LBUTTONUP: case OSystem::EVENT_RBUTTONUP: - mouse.button = 0; + g_mouse.button = 0; break; case OSystem::EVENT_KEYDOWN: - key_control = 0; - key_alt = 0; + _key_control = 0; + _key_alt = 0; if (event.kbd.flags == OSystem::KBD_CTRL && event.kbd.keycode == 'd') { _console->attach(); @@ -122,10 +98,10 @@ static void process_events() { } if (event.kbd.flags & OSystem::KBD_CTRL) - key_control = 1; + _key_control = 1; if (event.kbd.flags & OSystem::KBD_ALT) - key_alt = 1; + _key_alt = 1; switch (key = event.kbd.keycode) { case 256 + 20: // left arrow @@ -222,9 +198,9 @@ static void process_events() { key = event.kbd.ascii; break; } - if (key_control) + if (_key_control) key = (key & ~0x20) - 0x40; - else if (key_alt) + else if (_key_alt) key = scancode_table[(key & ~0x20) - 0x41] << 8; else if (event.kbd.flags & OSystem::KBD_SHIFT) key = event.kbd.ascii; @@ -239,43 +215,102 @@ static void process_events() { } } -int agi_is_keypress_low() { - process_events(); - return key_queue_start != key_queue_end; +int AgiEngine::agiIsKeypressLow() { + processEvents(); + return _key_queue_start != _key_queue_end; } -void agi_timer_low() { +void AgiEngine::agiTimerLow() { static uint32 m = 0; uint32 dm; - if (tick_timer < m) + if (g_tick_timer < m) m = 0; - while ((dm = tick_timer - m) < 5) { - process_events(); + while ((dm = g_tick_timer - m) < 5) { + processEvents(); if (_console->isAttached()) _console->onFrame(); g_system->delayMillis(10); g_system->updateScreen(); } - m = tick_timer; + m = g_tick_timer; } -int agi_get_keypress_low() { +int AgiEngine::agiGetKeypressLow() { int k; - while (key_queue_start == key_queue_end) /* block */ - agi_timer_low(); + while (_key_queue_start == _key_queue_end) /* block */ + agiTimerLow(); key_dequeue(k); return k; } -static void agi_timer_function_low(void *refCon) { - tick_timer++; +void AgiEngine::agiTimerFunctionLow(void *refCon) { + g_tick_timer++; +} + +void AgiEngine::clear_image_stack(void) { + image_stack_pointer = 0; +} + +void AgiEngine::release_image_stack(void) { + if (image_stack) + free(image_stack); + image_stack = NULL; + stack_size = image_stack_pointer = 0; +} + +void AgiEngine::record_image_stack_call(uint8 type, int16 p1, int16 p2, int16 p3, + int16 p4, int16 p5, int16 p6, int16 p7) { + struct image_stack_element *pnew; + + if (image_stack_pointer == stack_size) { + if (stack_size == 0) { /* first call */ + image_stack = (struct image_stack_element *) + malloc(INITIAL_IMAGE_STACK_SIZE * sizeof(struct image_stack_element)); + stack_size = INITIAL_IMAGE_STACK_SIZE; + } else { /* has to grow */ + struct image_stack_element *new_stack; + new_stack = (struct image_stack_element *) + malloc(2 * stack_size * sizeof(struct image_stack_element)); + memcpy(new_stack, image_stack, stack_size * sizeof(struct image_stack_element)); + free(image_stack); + image_stack = new_stack; + stack_size *= 2; + } + } + + pnew = &image_stack[image_stack_pointer]; + image_stack_pointer++; + + pnew->type = type; + pnew->parm1 = p1; + pnew->parm2 = p2; + pnew->parm3 = p3; + pnew->parm4 = p4; + pnew->parm5 = p5; + pnew->parm6 = p6; + pnew->parm7 = p7; +} + +void AgiEngine::replay_image_stack_call(uint8 type, int16 p1, int16 p2, int16 p3, + int16 p4, int16 p5, int16 p6, int16 p7) { + switch (type) { + case ADD_PIC: + debugC(8, kDebugLevelMain, "--- decoding picture %d ---", p1); + agiLoadResource(rPICTURE, p1); + _picture->decode_picture(p1, p2); + break; + case ADD_VIEW: + agiLoadResource(rVIEW, p1); + _sprites->add_to_pic(p1, p2, p3, p4, p5, p6, p7); + break; + } } -static void init_pri_table() { +void AgiEngine::initPriTable() { int i, p, y = 0; for (p = 1; p < 15; p++) { @@ -285,7 +320,7 @@ static void init_pri_table() { } } -int agi_init() { +int AgiEngine::agiInit() { int ec, i; debug(2, "initializing"); @@ -303,6 +338,10 @@ int agi_init() { memset(&game.pictures[i], 0, sizeof(struct agi_picture)); memset(&game.logics[i], 0, sizeof(struct agi_logic)); memset(&game.sounds[i], 0, sizeof(struct agi_sound)); + memset(&game.dir_view[i], 0, sizeof(struct agi_dir)); + memset(&game.dir_pic[i], 0, sizeof(struct agi_dir)); + memset(&game.dir_logic[i], 0, sizeof(struct agi_dir)); + memset(&game.dir_sound[i], 0, sizeof(struct agi_dir)); } /* clear view table */ @@ -312,9 +351,9 @@ int agi_init() { init_words(); if (!menu) - menu = new Menu(); + menu = new Menu(this, _gfx, _picture); - init_pri_table(); + initPriTable(); /* clear string buffer */ for (i = 0; i < MAX_STRINGS; i++) @@ -322,16 +361,16 @@ int agi_init() { /* setup emulation */ - switch (loader->int_version >> 12) { + switch (loader->getIntVersion() >> 12) { case 2: report("Emulating Sierra AGI v%x.%03x\n", - (int)(loader->int_version >> 12) & 0xF, - (int)(loader->int_version) & 0xFFF); + (int)(loader->version() >> 12) & 0xF, + (int)(loader->version()) & 0xFFF); break; case 3: report("Emulating Sierra AGI v%x.002.%03x\n", - (int)(loader->int_version >> 12) & 0xF, - (int)(loader->int_version) & 0xFFF); + (int)(loader->version() >> 12) & 0xF, + (int)(loader->version()) & 0xFFF); break; } @@ -367,7 +406,7 @@ int agi_init() { * Public functions */ -void agi_unload_resources() { +void AgiEngine::agiUnloadResources() { int i; /* Make sure logic 0 is always loaded */ @@ -381,11 +420,11 @@ void agi_unload_resources() { } } -int agi_deinit() { +int AgiEngine::agiDeinit() { int ec; clean_input(); /* remove all words from memory */ - agi_unload_resources(); /* unload resources in memory */ + agiUnloadResources(); /* unload resources in memory */ loader->unload_resource(rLOGIC, 0); ec = loader->deinit(); unload_objects(); @@ -396,33 +435,33 @@ int agi_deinit() { return ec; } -int agi_detect_game() { +int AgiEngine::agiDetectGame() { int ec = err_OK; - loader = &agi_v2; + loader = new AgiLoader_v2(this); ec = loader->detect_game(); if (ec != err_OK) { - loader = &agi_v3; + loader = new AgiLoader_v3(this); ec = loader->detect_game(); } return ec; } -int agi_version() { - return loader->version; +int AgiEngine::agiVersion() { + return loader->version(); } -int agi_get_release() { - return loader->int_version; +int AgiEngine::agiGetRelease() { + return loader->getIntVersion(); } -void agi_set_release(int n) { - loader->int_version = n; +void AgiEngine::agiSetRelease(int n) { + loader->setIntVersion(n); } -int agi_load_resource(int r, int n) { +int AgiEngine::agiLoadResource(int r, int n) { int i; i = loader->load_resource(r, n); @@ -434,13 +473,10 @@ int agi_load_resource(int r, int n) { return i; } -int agi_unload_resource(int r, int n) { +int AgiEngine::agiUnloadResource(int r, int n) { return loader->unload_resource(r, n); } -const char *_savePath; // FIXME: Get rid of this -extern AGIMusic *g_agi_music; - struct GameSettings { const char *gameid; const char *description; @@ -456,7 +492,7 @@ static const GameSettings agi_settings[] = { Common::RandomSource * rnd; -AgiEngine::AgiEngine(OSystem * syst) : Engine(syst) { +AgiEngine::AgiEngine(OSystem *syst) : Engine(syst) { // Setup mixer if (!_mixer->isReady()) { @@ -475,7 +511,7 @@ AgiEngine::AgiEngine(OSystem * syst) : Engine(syst) { if (!scumm_stricmp(g->gameid, gameid)) _gameId = g->id; - rnd = new Common::RandomSource(); + _rnd = new Common::RandomSource(); Common::addSpecialDebugLevel(kDebugLevelMain, "Main", "Generic debug level"); Common::addSpecialDebugLevel(kDebugLevelResources, "Resources", "Resources debugging"); @@ -487,8 +523,34 @@ AgiEngine::AgiEngine(OSystem * syst) : Engine(syst) { Common::addSpecialDebugLevel(kDebugLevelSound, "Sound", "Sound debugging"); Common::addSpecialDebugLevel(kDebugLevelText, "Text", "Text output debugging"); + + memset(&game, 0, sizeof(struct agi_game)); + memset(&_debug, 0, sizeof(struct agi_debug)); + memset(&g_mouse, 0, sizeof(struct Mouse)); + game.clock_enabled = false; game.state = STATE_INIT; + + _key_queue_start = 0; + _key_queue_end = 0; + + _key_control = 0; + _key_alt = 0; + + g_tick_timer = 0; + + intobj = NULL; + + stack_size = 0; + image_stack = NULL; + image_stack_pointer = 0; + + menu = NULL; + + last_sentence[0] = 0; + memset(&stringdata, 0, sizeof(struct string_data)); + + objects = NULL; } void AgiEngine::initialize() { @@ -513,29 +575,33 @@ void AgiEngine::initialize() { opt.renderMode = Common::parseRenderMode(ConfMan.get("render_mode").c_str()); _console = new Console(this); + _gfx = new GfxMgr(this); + _sound = new SoundMgr(this, _mixer); + _picture = new PictureMgr(this, _gfx); + _sprites = new SpritesMgr(this, _gfx); + _saveGameMgr = new SaveGameMgr(this, _sprites, _gfx, _sound, _picture); + + _gfx->initMachine(); - init_machine(); + game.game_flags = 0; game.color_fg = 15; game.color_bg = 0; - *game.name = 0; + *game.name = NULL; - game.sbuf = (uint8 *) calloc(_WIDTH, _HEIGHT); - game.hires = (uint8 *) calloc(_WIDTH * 2, _HEIGHT); + game.sbuf = (uint8 *)calloc(_WIDTH, _HEIGHT); + game.hires = (uint8 *)calloc(_WIDTH * 2, _HEIGHT); - menu = 0; - _sprites = new SpritesMan; - _text = new TextMan; - init_video(); + _gfx->initVideo(); + _sound->init_sound(); - tick_timer = 0; - _timer->installTimerProc(agi_timer_function_low, 10 * 1000, NULL); + _timer->installTimerProc(agiTimerFunctionLow, 10 * 1000, NULL); game.ver = -1; /* Don't display the conf file warning */ debugC(2, kDebugLevelMain, "Detect game"); - if (agi_detect_game() == err_OK) { + if (agiDetectGame() == err_OK) { game.state = STATE_LOADED; debugC(2, kDebugLevelMain, "game loaded"); } else { @@ -543,19 +609,17 @@ void AgiEngine::initialize() { } debugC(2, kDebugLevelMain, "Init sound"); - init_sound(); - g_agi_music = new AGIMusic(_mixer); } AgiEngine::~AgiEngine() { - agi_deinit(); - delete g_agi_music; - deinit_sound(); - deinit_video(); + agiDeinit(); + _sound->deinit_sound(); + delete _sound; + _gfx->deinitVideo(); delete _sprites; free(game.hires); free(game.sbuf); - deinit_machine(); + _gfx->deinitMachine(); delete rnd; delete _console; } @@ -569,7 +633,7 @@ int AgiEngine::init() { initialize(); - gfx_set_palette(); + _gfx->gfxSetPalette(); return 0; } @@ -642,6 +706,7 @@ PluginError Engine_AGI_create(OSystem *syst, Engine **engine) { FSList fslist; FilesystemNode dir(ConfMan.get("path")); if (!dir.listDir(fslist, FilesystemNode::kListFilesOnly)) { + warning("AgiEngine: invalid game path '%s'", dir.path().c_str()); return kInvalidPathError; } @@ -656,7 +721,8 @@ PluginError Engine_AGI_create(OSystem *syst, Engine **engine) { } } + warning("AgiEngine: Unable to locate game data at path '%s'", dir.path().c_str()); return kNoGameDataFoundError; } -REGISTER_PLUGIN(AGI, "AGI Engine", "Sierra AGI Games (C) Sierra On-Line, Inc."); +REGISTER_PLUGIN(AGI, "AGI Engine", "TODO (C) TODO"); diff --git a/engines/agi/agi.h b/engines/agi/agi.h index b1a10b54ea..5e8ee30767 100644 --- a/engines/agi/agi.h +++ b/engines/agi/agi.h @@ -32,6 +32,7 @@ #include "common/file.h" #include "common/savefile.h" #include "common/system.h" +#include "common/hash-str.h" #include "engines/engine.h" @@ -95,29 +96,6 @@ typedef signed int Err; namespace Agi { -int getflag(int); -void setflag(int, int); -void flipflag(int); -int getvar(int); -void setvar(int, int); -void decrypt(uint8 * mem, int len); -void release_sprites(void); -int main_cycle(void); -int view_pictures(void); -int parse_cli(int, char **); -int run_game(void); -int init_machine(void); -int deinit_machine(void); -int get_direction(int x, int y, int x0, int y0, int s); -void inventory(void); -void list_games(void); -uint32 match_crc(uint32, char *, int); -int v2id_game(void); -int v3id_game(void); -int v4id_game(uint32 ver); -void update_timer(void); -int get_app_dir(char *app_dir, unsigned int size); - enum { NO_GAMEDIR = 0, GAMEDIR @@ -180,7 +158,7 @@ struct game_id_list { char *switches; }; -struct mouse { +struct Mouse { int button; unsigned int x; unsigned int y; @@ -207,42 +185,12 @@ struct agi_options { int agimouse; /**< AGI Mouse 1.0 emulation */ }; -extern struct agi_options opt; -extern uint8 *exec_name; - -extern volatile uint32 clock_ticks; -extern volatile uint32 clock_count; -extern volatile uint32 msg_box_secs2; - -extern struct agi_debug debug_; -extern struct mouse mouse; - #define report printf enum GameId { GID_AGI = 1 }; -extern Common::RandomSource * rnd; -extern const char *_savePath; - -class AgiEngine : public ::Engine { - int _gameId; - -protected: - int init(); - int go(); - void shutdown(); - void initialize(); - - -public: - AgiEngine(OSystem * syst); - virtual ~ AgiEngine(); - int getGameId() { - return _gameId; -}}; - #define WIN_TO_PIC_X(x) ((x) / 2) #define WIN_TO_PIC_Y(y) ((y) < 8 ? 999 : (y) >= (8 + _HEIGHT) ? 999 : (y) - 8) @@ -436,57 +384,362 @@ struct agi_game { int simple_save; /**< select simple savegames */ }; -/** - * - */ -struct agi_loader { - int version; +class AgiLoader { +private: + int int_version; + AgiEngine *_vm; + +public: + + AgiLoader() {} + + virtual int init() = 0; + virtual int deinit() = 0; + virtual int detect_game() = 0; + virtual int load_resource(int, int) = 0; + virtual int unload_resource(int, int) = 0; + virtual int load_objects(const char *) = 0; + virtual int load_words(const char *) = 0; + virtual int version() = 0; + virtual void setIntVersion(int) = 0; + virtual int getIntVersion() = 0; +}; + +class AgiLoader_v2 : public AgiLoader { +private: + int int_version; + AgiEngine *_vm; + + int load_dir(struct agi_dir *agid, const char *fname); + uint8 *load_vol_res(struct agi_dir *agid); + +public: + + AgiLoader_v2(AgiEngine *vm) { + _vm = vm; + int_version = 0; + } + + virtual int init(); + virtual int deinit(); + virtual int detect_game(); + virtual int load_resource(int, int); + virtual int unload_resource(int, int); + virtual int load_objects(const char *); + virtual int load_words(const char *); + virtual int version(); + virtual void setIntVersion(int); + virtual int getIntVersion(); +}; + +class AgiLoader_v3 : public AgiLoader { +private: int int_version; - int (*init) (void); - int (*deinit) (void); - int (*detect_game) (); - int (*load_resource) (int, int); - int (*unload_resource) (int, int); - int (*load_objects) (const char *); - int (*load_words) (const char *); + AgiEngine *_vm; + + int AgiLoader_v3::load_dir(agi_dir *agid, Common::File *fp, + uint32 offs, uint32 len); + uint8 *AgiLoader_v3::load_vol_res(agi_dir *agid); + +public: + + AgiLoader_v3(AgiEngine *vm) { + _vm = vm; + int_version = 0; + } + + virtual int init(); + virtual int deinit(); + virtual int detect_game(); + virtual int load_resource(int, int); + virtual int unload_resource(int, int); + virtual int load_objects(const char *); + virtual int load_words(const char *); + virtual int version(); + virtual void setIntVersion(int); + virtual int getIntVersion(); }; -extern struct agi_game game; - -int agi_init(void); -int agi_deinit(void); -int agi_version(void); -int agi_get_release(void); -void agi_set_release(int); -int agi_detect_game(); -int agi_load_resource(int, int); -int agi_unload_resource(int, int); -void agi_unload_resources(void); - -/* words */ -int show_words(void); -int load_words(const char *); -void unload_words(void); -int find_word(char *word, int *flen); -void dictionary_words(char *); - -/* objects */ -int show_objects(void); -int load_objects(const char *fname); -int alloc_objects(int); -void unload_objects(void); -const char *object_name(unsigned int); -int object_get_location(unsigned int); -void object_set_location(unsigned int, int); - -void new_input_mode(int); -void old_input_mode(void); - -int run_logic(int); - -void agi_timer_low(); -int agi_get_keypress_low(); -int agi_is_keypress_low(); +class GfxMgr; +class SpritesMgr; +class Menu; +class SaveGameMgr; + +extern struct Mouse g_mouse; + +/* Image stack support */ +struct image_stack_element { + uint8 type; + uint8 pad; + int16 parm1; + int16 parm2; + int16 parm3; + int16 parm4; + int16 parm5; + int16 parm6; + int16 parm7; +}; + +struct string_data { + int x; + int y; + int len; + int str; +}; + +#define TICK_SECONDS 20 + +#define KEY_QUEUE_SIZE 16 + +class AgiEngine : public ::Engine { + int _gameId; + +protected: + int init(); + int go(); + void shutdown(); + void initialize(); + +public: + AgiEngine(OSystem *syst); + virtual ~AgiEngine(); + int getGameId() { + return _gameId; + } + +private: + + int _key_queue[KEY_QUEUE_SIZE]; + int _key_queue_start; + int _key_queue_end; + + int check_priority(struct vt_entry *v); + int check_collision(struct vt_entry *v); + int check_position(struct vt_entry *v); + + uint32 match_version(uint32 crc); + +public: + struct agi_game game; + struct agi_object *objects; /* objects in the game */ + + struct string_data stringdata; + + AgiLoader *loader; /* loader */ + + Common::RandomSource *_rnd; + const char *_savePath; + + volatile uint32 clock_count; + + uint8 *intobj; + + Menu* menu; + + char last_sentence[40]; + + SpritesMgr *_sprites; + GfxMgr *_gfx; + SoundMgr *_sound; + PictureMgr *_picture; + SaveGameMgr *_saveGameMgr; + + #define INITIAL_IMAGE_STACK_SIZE 32 + + int stack_size; + struct image_stack_element *image_stack; + int image_stack_pointer; + + void clear_image_stack(); + void record_image_stack_call(uint8 type, int16 p1, int16 p2, int16 p3, + int16 p4, int16 p5, int16 p6, int16 p7); + void replay_image_stack_call(uint8 type, int16 p1, int16 p2, int16 p3, + int16 p4, int16 p5, int16 p6, int16 p7); + void release_image_stack(); + + struct agi_debug _debug; + struct agi_options opt; + + int _key_control; + int _key_alt; + + Console *_console; + + int agiInit(); + int agiDeinit(); + int agiVersion(); + int agiGetRelease(); + void agiSetRelease(int); + int agiDetectGame(); + int agiLoadResource(int, int); + int agiUnloadResource(int, int); + void agiUnloadResources(); + + void agiTimerLow(); + int agiGetKeypressLow(); + int agiIsKeypressLow(); + static void agiTimerFunctionLow(void *refCon); + void initPriTable(); + + void new_input_mode(int); + void old_input_mode(); + + int getflag(int); + void setflag(int, int); + void flipflag(int); + int getvar(int); + void setvar(int, int); + void decrypt(uint8 * mem, int len); + void release_sprites(); + int main_cycle(); + int view_pictures(); + int parse_cli(int, char **); + int run_game(); + void inventory(); + void list_games(); + uint32 match_crc(uint32, char *, int); + int v2id_game(); + int v3id_game(); + int v4id_game(uint32 ver); + void update_timer(); + int get_app_dir(char *app_dir, unsigned int size); + + int setup_v2_game(int ver, uint32 crc); + int setup_v3_game(int ver, uint32 crc); + + void new_room(int n); + void reset_controllers(); + void interpret_cycle(); + int play_game(); + + void printItem(int n, int fg, int bg); + int findItem(); + int showItems(); + void selectItems(int n); + + void processEvents(); + + // Objects + int show_objects(); + int decode_objects(uint8 *mem, uint32 flen); + int load_objects(const char *fname); + int alloc_objects(int); + void unload_objects(); + const char *object_name(unsigned int); + int object_get_location(unsigned int); + void object_set_location(unsigned int, int); + + // Logic + int decode_logic(int); + void unload_logic(int); + int run_logic(int); + void patch_logic(int n); + + void debug_console(int, int, const char *); + int test_if_code(int); + void execute_agi_command(uint8, uint8 *); + + // View +private: + + void _set_cel(vt_entry *v, int n); + void _set_loop(vt_entry *v, int n); + void update_view(vt_entry *v); + +public: + + void set_cel(vt_entry *, int); + void set_loop(vt_entry *, int); + void set_view(vt_entry *, int); + void start_update(vt_entry *); + void stop_update(vt_entry *); + void update_viewtable(); + void unload_view(int); + int decode_view(int); + void add_to_pic(int, int, int, int, int, int, int); + void draw_obj(int); + bool is_ego_view(const vt_entry *v); + + // Words + int show_words(); + int load_words(const char *); + void unload_words(); + int find_word(char *word, int *flen); + void dictionary_words(char *); + + // Motion +private: + int check_step(int delta, int step); + int check_block(int x, int y); + void changepos(struct vt_entry *v); + void motion_wander(struct vt_entry *v); + void motion_followego(struct vt_entry *v); + void motion_moveobj(struct vt_entry *v); + void check_motion(struct vt_entry *v); +public: + void check_all_motions(); + void move_obj(vt_entry *); + void in_destination(vt_entry *); + void fix_position(int); + void update_position(); + int get_direction(int x0, int y0, int x, int y, int s); + + // Keyboard + void init_words(); + void clean_input(); + int do_poll_keyboard(); + void clean_keyboard(); + void handle_keys(int); + void handle_getstring(int); + int handle_controller(int); + void get_string(int, int, int, int); + uint16 agi_get_keypress(); + int wait_key(); + int wait_any_key(); + + // Text +public: + #define MAXWORDLEN 24 + + typedef Common::String String; + + int message_box(const char *); + int selection_box(const char *, const char **); + void close_window(void); + void draw_window(int, int, int, int); + void print_text(const char *, int, int, int, int, int, int); + void print_text_console(const char *, int, int, int, int, int); + int print(const char *, int, int, int); + char *word_wrap_string(char *, int *); + char *agi_sprintf(const char *); + void write_status(void); + void write_prompt(void); + void clear_lines(int, int, int); + void flush_lines(int, int); + bool predictiveDialog(void); + +private: + void print_status(const char *message, ...); + void print_text2(int l, const char *msg, int foff, int xoff, int yoff, int len, int fg, int bg); + void blit_textbox(const char *p, int y, int x, int len); + void erase_textbox(); + char *safe_strcat(char *s, const char *t); + void loadDict(void); + bool matchWord(void); + + typedef Common::HashMap<String, String, Common::CaseSensitiveString_Hash, Common::CaseSensitiveString_EqualTo> DictMap; + DictMap _dict; + Common::StringList _dictKeys; + String _currentCode; + String _currentWord; + String _matchedWord; + int _wordNumber; + uint _wordPosition; + bool _nextIsActive; + bool _addIsActive; +public: + char _predictiveResult[40]; +}; } // End of namespace Agi diff --git a/engines/agi/agi_v2.cpp b/engines/agi/agi_v2.cpp index f03554e4fc..a7dc951842 100644 --- a/engines/agi/agi_v2.cpp +++ b/engines/agi/agi_v2.cpp @@ -29,38 +29,30 @@ namespace Agi { -static int agi_v2_init(void); -static int agi_v2_deinit(void); -static int agi_v2_detect_game(); -static int agi_v2_load_resource(int, int); -static int agi_v2_unload_resource(int, int); -static int agi_v2_load_objects(const char *); -static int agi_v2_load_words(const char *); - -struct agi_loader agi_v2 = { - 2, - 0, - agi_v2_init, - agi_v2_deinit, - agi_v2_detect_game, - agi_v2_load_resource, - agi_v2_unload_resource, - agi_v2_load_objects, - agi_v2_load_words -}; - -static int agi_v2_detect_game() { +int AgiLoader_v2::version() { + return 2; +} + +void AgiLoader_v2::setIntVersion(int version) { + int_version = version; +} + +int AgiLoader_v2::getIntVersion() { + return int_version; +} + +int AgiLoader_v2::detect_game() { if (!Common::File::exists(LOGDIR) || !Common::File::exists(PICDIR) || !Common::File::exists(SNDDIR) || !Common::File::exists(VIEWDIR)) return err_InvalidAGIFile; - agi_v2.int_version = 0x2917; /* setup for 2.917 */ - return v2id_game(); + int_version = 0x2917; /* setup for 2.917 */ + return _vm->v2id_game(); } -static int agi_v2_load_dir(struct agi_dir *agid, const char *fname) { +int AgiLoader_v2::load_dir(struct agi_dir *agid, const char *fname) { Common::File fp; uint8 *mem; uint32 flen; @@ -76,7 +68,7 @@ static int agi_v2_load_dir(struct agi_dir *agid, const char *fname) { flen = fp.pos(); fp.seek(0, SEEK_SET); - if ((mem = (uint8 *) malloc(flen + 32)) == NULL) { + if ((mem = (uint8 *)malloc(flen + 32)) == NULL) { fp.close(); return err_NotEnoughMemory; } @@ -102,22 +94,22 @@ static int agi_v2_load_dir(struct agi_dir *agid, const char *fname) { return err_OK; } -static int agi_v2_init() { +int AgiLoader_v2::init() { int ec = err_OK; /* load directory files */ - ec = agi_v2_load_dir(game.dir_logic, LOGDIR); + ec = load_dir(_vm->game.dir_logic, LOGDIR); if (ec == err_OK) - ec = agi_v2_load_dir(game.dir_pic, PICDIR); + ec = load_dir(_vm->game.dir_pic, PICDIR); if (ec == err_OK) - ec = agi_v2_load_dir(game.dir_view, VIEWDIR); + ec = load_dir(_vm->game.dir_view, VIEWDIR); if (ec == err_OK) - ec = agi_v2_load_dir(game.dir_sound, SNDDIR); + ec = load_dir(_vm->game.dir_sound, SNDDIR); return ec; } -static int agi_v2_deinit() { +int AgiLoader_v2::deinit() { int ec = err_OK; #if 0 @@ -131,21 +123,21 @@ static int agi_v2_deinit() { return ec; } -static int agi_v2_unload_resource(int t, int n) { +int AgiLoader_v2::unload_resource(int t, int n) { debugC(3, kDebugLevelResources, "unload resource"); switch (t) { case rLOGIC: - unload_logic(n); + _vm->unload_logic(n); break; case rPICTURE: - unload_picture(n); + _vm->_picture->unload_picture(n); break; case rVIEW: - unload_view(n); + _vm->unload_view(n); break; case rSOUND: - unload_sound(n); + _vm->_sound->unload_sound(n); break; } @@ -157,7 +149,7 @@ static int agi_v2_unload_resource(int t, int n) { * if further decoding is required, it must be done by another * routine. NULL is returned if unsucsessfull. */ -static uint8 *agi_v2_load_vol_res(struct agi_dir *agid) { +uint8 *AgiLoader_v2::load_vol_res(struct agi_dir *agid) { uint8 *data = NULL; char x[MAX_PATH], *path; Common::File fp; @@ -204,7 +196,7 @@ static uint8 *agi_v2_load_vol_res(struct agi_dir *agid) { * Loads a resource into memory, a raw resource is loaded in * with above routine, then further decoded here. */ -int agi_v2_load_resource(int t, int n) { +int AgiLoader_v2::load_resource(int t, int n) { int ec = err_OK; uint8 *data = NULL; @@ -214,23 +206,23 @@ int agi_v2_load_resource(int t, int n) { switch (t) { case rLOGIC: - if (~game.dir_logic[n].flags & RES_LOADED) { + if (~_vm->game.dir_logic[n].flags & RES_LOADED) { debugC(3, kDebugLevelResources, "loading logic resource %d", n); - agi_v2.unload_resource(rLOGIC, n); + unload_resource(rLOGIC, n); /* load raw resource into data */ - data = agi_v2_load_vol_res(&game.dir_logic[n]); + data = load_vol_res(&_vm->game.dir_logic[n]); - game.logics[n].data = data; - ec = data ? decode_logic(n) : err_BadResource; + _vm->game.logics[n].data = data; + ec = data ? _vm->decode_logic(n) : err_BadResource; - game.logics[n].sIP = 2; + _vm->game.logics[n].sIP = 2; } /* if logic was cached, we get here */ /* reset code pointers incase it was cached */ - game.logics[n].cIP = game.logics[n].sIP; + _vm->game.logics[n].cIP = _vm->game.logics[n].sIP; break; case rPICTURE: /* if picture is currently NOT loaded *OR* cacheing is off, @@ -238,32 +230,32 @@ int agi_v2_load_resource(int t, int n) { */ debugC(3, kDebugLevelResources, "loading picture resource %d", n); - if (game.dir_pic[n].flags & RES_LOADED) + if (_vm->game.dir_pic[n].flags & RES_LOADED) break; /* if loaded but not cached, unload it */ /* if cached but not loaded, etc */ - agi_v2.unload_resource(rPICTURE, n); - data = agi_v2_load_vol_res(&game.dir_pic[n]); + unload_resource(rPICTURE, n); + data = load_vol_res(&_vm->game.dir_pic[n]); if (data != NULL) { - game.pictures[n].rdata = data; - game.dir_pic[n].flags |= RES_LOADED; + _vm->game.pictures[n].rdata = data; + _vm->game.dir_pic[n].flags |= RES_LOADED; } else { ec = err_BadResource; } break; case rSOUND: debugC(3, kDebugLevelResources, "loading sound resource %d", n); - if (game.dir_sound[n].flags & RES_LOADED) + if (_vm->game.dir_sound[n].flags & RES_LOADED) break; - data = agi_v2_load_vol_res(&game.dir_sound[n]); + data = load_vol_res(&_vm->game.dir_sound[n]); if (data != NULL) { - game.sounds[n].rdata = data; - game.dir_sound[n].flags |= RES_LOADED; - decode_sound(n); + _vm->game.sounds[n].rdata = data; + _vm->game.dir_sound[n].flags |= RES_LOADED; + _vm->_sound->decode_sound(n); } else { ec = err_BadResource; } @@ -274,16 +266,16 @@ int agi_v2_load_resource(int t, int n) { * can we cache the view? or must we reload it all * the time? */ - if (game.dir_view[n].flags & RES_LOADED) + if (_vm->game.dir_view[n].flags & RES_LOADED) break; debugC(3, kDebugLevelResources, "loading view resource %d", n); - agi_v2.unload_resource(rVIEW, n); - data = agi_v2_load_vol_res(&game.dir_view[n]); + unload_resource(rVIEW, n); + data = load_vol_res(&_vm->game.dir_view[n]); if (data) { - game.views[n].rdata = data; - game.dir_view[n].flags |= RES_LOADED; - ec = decode_view(n); + _vm->game.views[n].rdata = data; + _vm->game.dir_view[n].flags |= RES_LOADED; + ec = _vm->decode_view(n); } else { ec = err_BadResource; } @@ -296,12 +288,12 @@ int agi_v2_load_resource(int t, int n) { return ec; } -static int agi_v2_load_objects(const char *fname) { - return load_objects(fname); +int AgiLoader_v2::load_objects(const char *fname) { + return _vm->load_objects(fname); } -static int agi_v2_load_words(const char *fname) { - return load_words(fname); +int AgiLoader_v2::load_words(const char *fname) { + return _vm->load_words(fname); } } // End of namespace Agi diff --git a/engines/agi/agi_v3.cpp b/engines/agi/agi_v3.cpp index e207ad88bc..9f89d12c8f 100644 --- a/engines/agi/agi_v3.cpp +++ b/engines/agi/agi_v3.cpp @@ -32,27 +32,19 @@ namespace Agi { -static int agi_v3_init(void); -static int agi_v3_deinit(void); -static int agi_v3_detect_game(); -static int agi_v3_load_resource(int, int); -static int agi_v3_unload_resource(int, int); -static int agi_v3_load_objects(const char *); -static int agi_v3_load_words(const char *); - -struct agi_loader agi_v3 = { - 3, - 0, - agi_v3_init, - agi_v3_deinit, - agi_v3_detect_game, - agi_v3_load_resource, - agi_v3_unload_resource, - agi_v3_load_objects, - agi_v3_load_words -}; +int AgiLoader_v3::version() { + return 3; +} + +void AgiLoader_v3::setIntVersion(int version) { + int_version = version; +} + +int AgiLoader_v3::getIntVersion() { + return int_version; +} -int agi_v3_detect_game() { +int AgiLoader_v3::detect_game() { int ec = err_Unk; bool found = false; @@ -71,10 +63,10 @@ int agi_v3_detect_game() { f.toLowercase(); if (f.hasSuffix("vol.0")) { - strncpy(game.name, f.c_str(), f.size() > 5 ? f.size() - 5 : f.size()); - debugC(3, kDebugLevelMain, "game.name = %s", game.name); - agi_v3.int_version = 0x3149; // setup for 3.002.149 - ec = v3id_game(); + strncpy(_vm->game.name, f.c_str(), f.size() > 5 ? f.size() - 5 : f.size()); + debugC(3, kDebugLevelMain, "game.name = %s", _vm->game.name); + int_version = 0x3149; // setup for 3.002.149 + ec = _vm->v3id_game(); found = true; } @@ -88,7 +80,7 @@ int agi_v3_detect_game() { return ec; } -static int agi_v3_load_dir(struct agi_dir *agid, Common::File *fp, +int AgiLoader_v3::load_dir(struct agi_dir *agid, Common::File *fp, uint32 offs, uint32 len) { int ec = err_OK; uint8 *mem; @@ -123,7 +115,7 @@ struct agi3vol { uint32 len; }; -int agi_v3_init(void) { +int AgiLoader_v3::init() { int ec = err_OK; struct agi3vol agi_vol3[4]; int i; @@ -131,7 +123,7 @@ int agi_v3_init(void) { Common::File fp; Common::String path; - path = Common::String(game.name) + DIR_; + path = Common::String(_vm->game.name) + DIR_; if (!fp.open(path)) { printf("Failed to open \"%s\"\n", path.c_str()); @@ -155,25 +147,25 @@ int agi_v3_init(void) { fp.seek(0, SEEK_SET); /* read in directory files */ - ec = agi_v3_load_dir(game.dir_logic, &fp, agi_vol3[0].sddr, + ec = load_dir(_vm->game.dir_logic, &fp, agi_vol3[0].sddr, agi_vol3[0].len); if (ec == err_OK) { - ec = agi_v3_load_dir(game.dir_pic, &fp, agi_vol3[1].sddr, agi_vol3[1].len); + ec = load_dir(_vm->game.dir_pic, &fp, agi_vol3[1].sddr, agi_vol3[1].len); } if (ec == err_OK) { - ec = agi_v3_load_dir(game.dir_view, &fp, agi_vol3[2].sddr, agi_vol3[2].len); + ec = load_dir(_vm->game.dir_view, &fp, agi_vol3[2].sddr, agi_vol3[2].len); } if (ec == err_OK) { - ec = agi_v3_load_dir(game.dir_sound, &fp, agi_vol3[3].sddr, agi_vol3[3].len); + ec = load_dir(_vm->game.dir_sound, &fp, agi_vol3[3].sddr, agi_vol3[3].len); } return ec; } -int agi_v3_deinit() { +int AgiLoader_v3::deinit() { int ec = err_OK; #if 0 @@ -187,19 +179,19 @@ int agi_v3_deinit() { return ec; } -int agi_v3_unload_resource(int t, int n) { +int AgiLoader_v3::unload_resource(int t, int n) { switch (t) { case rLOGIC: - unload_logic(n); + _vm->unload_logic(n); break; case rPICTURE: - unload_picture(n); + _vm->_picture->unload_picture(n); break; case rVIEW: - unload_view(n); + _vm->unload_view(n); break; case rSOUND: - unload_sound(n); + _vm->_sound->unload_sound(n); break; } @@ -213,7 +205,7 @@ int agi_v3_unload_resource(int t, int n) { * * NULL is returned if unsucsessful. */ -uint8 *agi_v3_load_vol_res(struct agi_dir *agid) { +uint8 *AgiLoader_v3::load_vol_res(struct agi_dir *agid) { char x[MAX_PATH]; uint8 *data = NULL, *comp_buffer; Common::File fp; @@ -221,7 +213,7 @@ uint8 *agi_v3_load_vol_res(struct agi_dir *agid) { debugC(3, kDebugLevelResources, "(%p)", (void *)agid); sprintf(x, "vol.%i", agid->volume); - path = Common::String(game.name) + x; + path = Common::String(_vm->game.name) + x; if (agid->offset != _EMPTY && fp.open(path)) { fp.seek(agid->offset, SEEK_SET); @@ -282,7 +274,7 @@ uint8 *agi_v3_load_vol_res(struct agi_dir *agid) { * Loads a resource into memory, a raw resource is loaded in * with above routine, then further decoded here. */ -int agi_v3_load_resource(int t, int n) { +int AgiLoader_v3::load_resource(int t, int n) { int ec = err_OK; uint8 *data = NULL; @@ -294,20 +286,20 @@ int agi_v3_load_resource(int t, int n) { /* load resource into memory, decrypt messages at the end * and build the message list (if logic is in memory) */ - if (~game.dir_logic[n].flags & RES_LOADED) { + if (~_vm->game.dir_logic[n].flags & RES_LOADED) { /* if logic is already in memory, unload it */ - agi_v3.unload_resource(rLOGIC, n); + unload_resource(rLOGIC, n); /* load raw resource into data */ - data = agi_v3_load_vol_res(&game.dir_logic[n]); - game.logics[n].data = data; + data = load_vol_res(&_vm->game.dir_logic[n]); + _vm->game.logics[n].data = data; /* uncompressed logic files need to be decrypted */ if (data != NULL) { /* resloaded flag gets set by decode logic */ /* needed to build string table */ - ec = decode_logic(n); - game.logics[n].sIP = 2; + ec = _vm->decode_logic(n); + _vm->game.logics[n].sIP = 2; } else { ec = err_BadResource; } @@ -315,38 +307,39 @@ int agi_v3_load_resource(int t, int n) { /*logics[n].sIP=2; *//* saved IP = 2 */ /*logics[n].cIP=2; *//* current IP = 2 */ - game.logics[n].cIP = game.logics[n].sIP; + _vm->game.logics[n].cIP = _vm->game.logics[n].sIP; } /* if logic was cached, we get here */ /* reset code pointers incase it was cached */ - game.logics[n].cIP = game.logics[n].sIP; + _vm->game.logics[n].cIP = _vm->game.logics[n].sIP; break; case rPICTURE: /* if picture is currently NOT loaded *OR* cacheing is off, * unload the resource (caching==off) and reload it */ - if (~game.dir_pic[n].flags & RES_LOADED) { - agi_v3.unload_resource(rPICTURE, n); - data = agi_v3_load_vol_res(&game.dir_pic[n]); + if (~_vm->game.dir_pic[n].flags & RES_LOADED) { + unload_resource(rPICTURE, n); + data = load_vol_res(&_vm->game.dir_pic[n]); if (data != NULL) { - data = convert_v3_pic(data, game.dir_pic[n].len); - game.pictures[n].rdata = data; - game.dir_pic[n].flags |= RES_LOADED; + data = _vm->_picture->convert_v3_pic(data, _vm->game.dir_pic[n].len); + _vm->game.pictures[n].rdata = data; + _vm->game.dir_pic[n].flags |= RES_LOADED; } else { ec = err_BadResource; } } break; case rSOUND: - if (game.dir_sound[n].flags & RES_LOADED) + if (_vm->game.dir_sound[n].flags & RES_LOADED) break; - if ((data = agi_v3_load_vol_res(&game.dir_sound[n])) != NULL) { - game.sounds[n].rdata = data; - game.dir_sound[n].flags |= RES_LOADED; - decode_sound(n); + data = load_vol_res(&_vm->game.dir_sound[n]); + if (data != NULL) { + _vm->game.sounds[n].rdata = data; + _vm->game.dir_sound[n].flags |= RES_LOADED; + _vm->_sound->decode_sound(n); } else { ec = err_BadResource; } @@ -357,14 +350,15 @@ int agi_v3_load_resource(int t, int n) { * cache the view? or must we reload it all the time? */ /* load a raw view from a VOL file into data */ - if (game.dir_view[n].flags & RES_LOADED) + if (_vm->game.dir_view[n].flags & RES_LOADED) break; - agi_v3.unload_resource(rVIEW, n); - if ((data = agi_v3_load_vol_res(&game.dir_view[n])) != NULL) { - game.views[n].rdata = data; - game.dir_view[n].flags |= RES_LOADED; - ec = decode_view(n); + unload_resource(rVIEW, n); + data = load_vol_res(&_vm->game.dir_view[n]); + if (data != NULL) { + _vm->game.views[n].rdata = data; + _vm->game.dir_view[n].flags |= RES_LOADED; + ec = _vm->decode_view(n); } else { ec = err_BadResource; } @@ -377,12 +371,12 @@ int agi_v3_load_resource(int t, int n) { return ec; } -static int agi_v3_load_objects(const char *fname) { - return load_objects(fname); +int AgiLoader_v3::load_objects(const char *fname) { + return _vm->load_objects(fname); } -static int agi_v3_load_words(const char *fname) { - return load_words(fname); +int AgiLoader_v3::load_words(const char *fname) { + return _vm->load_words(fname); } } // End of namespace Agi diff --git a/engines/agi/checks.cpp b/engines/agi/checks.cpp index 93f40c07be..772ef7c132 100644 --- a/engines/agi/checks.cpp +++ b/engines/agi/checks.cpp @@ -27,7 +27,7 @@ namespace Agi { -static int check_position(struct vt_entry *v) { +int AgiEngine::check_position(struct vt_entry *v) { debugC(4, kDebugLevelSprites, "check position @ %d, %d", v->x_pos, v->y_pos); if (v->x_pos < 0 || @@ -41,7 +41,7 @@ static int check_position(struct vt_entry *v) { } /* MH1 needs this, but it breaks LSL1 */ - if (agi_get_release() >= 0x3000) { + if (agiGetRelease() >= 0x3000) { if (v->y_pos < v->y_size) return 0; } @@ -52,7 +52,7 @@ static int check_position(struct vt_entry *v) { /** * Check if there's another object on the way */ -static int check_collision(struct vt_entry *v) { +int AgiEngine::check_collision(struct vt_entry *v) { struct vt_entry *u; if (v->flags & IGNORE_OBJECTS) @@ -92,7 +92,7 @@ static int check_collision(struct vt_entry *v) { return 1; } -static int check_priority(struct vt_entry *v) { +int AgiEngine::check_priority(struct vt_entry *v) { int i, trigger, water, pass, pri; uint8 *p0; @@ -136,7 +136,7 @@ static int check_priority(struct vt_entry *v) { if (pri == 2) { /* trigger */ debugC(4, kDebugLevelSprites, "stepped on trigger"); - if (!debug_.ignoretriggers) + if (!_debug.ignoretriggers) trigger = 1; } } @@ -168,7 +168,7 @@ static int check_priority(struct vt_entry *v) { * new position must be valid according to the sprite positioning * rules, otherwise the previous position will be kept. */ -void update_position() { +void AgiEngine::update_position() { struct vt_entry *v; int x, y, old_x, old_y, border; @@ -206,7 +206,7 @@ void update_position() { if (x < 0) { x = 0; border = 4; - } else if (x <= 0 && agi_get_release() == 0x3086) { /* KQ4 */ + } else if (x <= 0 && agiGetRelease() == 0x3086) { /* KQ4 */ x = 0; /* See bug #590462 */ border = 4; } else if (v->entry == 0 && x == 0 && v->flags & ADJ_EGO_XY) { @@ -266,7 +266,7 @@ void update_position() { * * @param n view table entry number */ -void fix_position(int n) { +void AgiEngine::fix_position(int n) { struct vt_entry *v = &game.view_table[n]; int count, dir, size; diff --git a/engines/agi/console.cpp b/engines/agi/console.cpp index abf66ced48..5113d3eafd 100644 --- a/engines/agi/console.cpp +++ b/engines/agi/console.cpp @@ -34,8 +34,6 @@ namespace Agi { -struct agi_debug debug_; - Console::Console(AgiEngine *vm) : GUI::Debugger() { _vm = vm; @@ -72,7 +70,7 @@ bool Console::Cmd_SetVar(int argc, const char **argv) { } int p1 = (int)atoi(argv[1]); int p2 = (int)atoi(argv[2]); - setvar(p1, p2); + _vm->setvar(p1, p2); return true; } @@ -84,7 +82,7 @@ bool Console::Cmd_SetFlag(int argc, const char **argv) { } int p1 = (int)atoi(argv[1]); int p2 = (int)atoi(argv[2]); - setflag(p1, !!p2); + _vm->setflag(p1, !!p2); return true; } @@ -96,7 +94,7 @@ bool Console::Cmd_SetObj(int argc, const char **argv) { } int p1 = (int)atoi(argv[1]); int p2 = (int)atoi(argv[2]); - object_set_location(p1, p2); + _vm->object_set_location(p1, p2); return true; } @@ -117,7 +115,7 @@ bool Console::Cmd_RunOpcode(int argc, const char **argv) { debugC(5, kDebugLevelMain, "Opcode: %s %s %s %s", logic_names_cmd[i].name, argv[1], argv[2], argv[3]); - execute_agi_command(i, p); + _vm->execute_agi_command(i, p); return true; } @@ -128,8 +126,8 @@ bool Console::Cmd_RunOpcode(int argc, const char **argv) { bool Console::Cmd_Crc(int argc, const char **argv) { char name[80]; - DebugPrintf("0x%05x\n", game.crc); - if (match_crc(game.crc, name, 80)) + DebugPrintf("0x%05x\n", _vm->game.crc); + if (_vm->match_crc(_vm->game.crc, name, 80)) DebugPrintf("%s\n", name); else DebugPrintf("Unknown game\n"); @@ -140,7 +138,7 @@ bool Console::Cmd_Crc(int argc, const char **argv) { bool Console::Cmd_Agiver(int argc, const char **argv) { int ver, maj, min; - ver = agi_get_release(); + ver = _vm->agiGetRelease(); maj = (ver >> 12) & 0xf; min = ver & 0xfff; @@ -160,7 +158,7 @@ bool Console::Cmd_Flags(int argc, const char **argv) { for (i = 0; i < 255;) { DebugPrintf("%3d ", i); for (j = 0; j < 10; j++, i++) { - DebugPrintf("%c ", getflag(i) ? 'T' : 'F'); + DebugPrintf("%c ", _vm->getflag(i) ? 'T' : 'F'); } report("\n"); } @@ -173,7 +171,7 @@ bool Console::Cmd_Vars(int argc, const char **argv) { for (i = 0; i < 255;) { for (j = 0; j < 5; j++, i++) { - DebugPrintf("%03d:%3d ", i, getvar(i)); + DebugPrintf("%03d:%3d ", i, _vm->getvar(i)); } DebugPrintf("\n"); } @@ -184,8 +182,8 @@ bool Console::Cmd_Vars(int argc, const char **argv) { bool Console::Cmd_Objs(int argc, const char **argv) { unsigned int i; - for (i = 0; i < game.num_objects; i++) { - DebugPrintf("%3d]%-24s(%3d)\n", i, object_name(i), object_get_location(i)); + for (i = 0; i < _vm->game.num_objects; i++) { + DebugPrintf("%3d]%-24s(%3d)\n", i, _vm->object_name(i), _vm->object_get_location(i)); } return true; @@ -197,7 +195,7 @@ bool Console::Cmd_Opcode(int argc, const char **argv) { return false; } - debug_.opcodes = !strcmp(argv[1], "on"); + _vm->_debug.opcodes = !strcmp(argv[1], "on"); return true; } @@ -208,7 +206,7 @@ bool Console::Cmd_Logic0(int argc, const char **argv) { return false; } - debug_.logic0 = !strcmp(argv[1], "on"); + _vm->_debug.logic0 = !strcmp(argv[1], "on"); return true; } @@ -218,34 +216,34 @@ bool Console::Cmd_Trigger(int argc, const char **argv) { DebugPrintf("Usage: trigger on|off\n"); return false; } - debug_.ignoretriggers = strcmp (argv[1], "on"); + _vm->_debug.ignoretriggers = strcmp (argv[1], "on"); return true; } bool Console::Cmd_Step(int argc, const char **argv) { - debug_.enabled = 1; + _vm->_debug.enabled = 1; if (argc == 0) { - debug_.steps = 1; + _vm->_debug.steps = 1; return true; } - debug_.steps = strtoul(argv[1], NULL, 0); + _vm->_debug.steps = strtoul(argv[1], NULL, 0); return true; } bool Console::Cmd_Debug(int argc, const char **argv) { - debug_.enabled = 1; - debug_.steps = 0; + _vm->_debug.enabled = 1; + _vm->_debug.steps = 0; return true; } bool Console::Cmd_Cont(int argc, const char **argv) { - debug_.enabled = 0; - debug_.steps = 0; + _vm->_debug.enabled = 0; + _vm->_debug.steps = 0; return true; } diff --git a/engines/agi/cycle.cpp b/engines/agi/cycle.cpp index 4df9bc910c..f828efe0b2 100644 --- a/engines/agi/cycle.cpp +++ b/engines/agi/cycle.cpp @@ -34,24 +34,17 @@ namespace Agi { -#define TICK_SECONDS 20 - -struct mouse mouse; - -volatile uint32 clock_ticks; -volatile uint32 clock_count; - /** * Set up new room. * This function is called when ego enters a new room. * @param n room number */ -void new_room(int n) { +void AgiEngine::new_room(int n) { struct vt_entry *v; int i; debugC(4, kDebugLevelMain, "*** room %d ***", n); - stop_sound(); + _sound->stop_sound(); i = 0; for (v = game.view_table; v < &game.view_table[MAX_VIEWTABLE]; v++) { @@ -64,7 +57,7 @@ void new_room(int n) { v->cycle_time_count = 1; v->step_size = 1; } - agi_unload_resources(); + agiUnloadResources(); game.player_control = true; game.block.active = false; @@ -75,7 +68,7 @@ void new_room(int n) { game.vars[V_border_code] = 0; game.vars[V_ego_view_resource] = game.view_table[0].current_view; - agi_load_resource(rLOGIC, n); + agiLoadResource(rLOGIC, n); /* Reposition ego in the new room */ switch (game.vars[V_border_touch_ego]) { @@ -98,11 +91,11 @@ void new_room(int n) { game.exit_all_logics = true; - _text->write_status(); - _text->write_prompt(); + write_status(); + write_prompt(); } -static void reset_controllers() { +void AgiEngine::reset_controllers() { int i; for (i = 0; i < MAX_DIRS; i++) { @@ -110,7 +103,7 @@ static void reset_controllers() { } } -static void interpret_cycle() { +void AgiEngine::interpret_cycle() { int old_sound, old_score; if (game.player_control) @@ -138,7 +131,7 @@ static void interpret_cycle() { game.view_table[0].direction = game.vars[V_ego_dir]; if (game.vars[V_score] != old_score || getflag(F_sound_on) != old_sound) - _text->write_status(); + write_status(); game.vars[V_border_touch_obj] = 0; game.vars[V_border_code] = 0; @@ -148,14 +141,14 @@ static void interpret_cycle() { if (game.gfx_mode) { update_viewtable(); - do_update(); + _gfx->doUpdate(); } } /** * Update AGI interpreter timer. */ -void update_timer() { +void AgiEngine::update_timer() { clock_count++; if (clock_count <= TICK_SECONDS) return; @@ -185,25 +178,25 @@ void update_timer() { static int old_mode = -1; -void new_input_mode(int i) { +void AgiEngine::new_input_mode(int i) { old_mode = game.input_mode; game.input_mode = i; } -void old_input_mode() { +void AgiEngine::old_input_mode() { game.input_mode = old_mode; } /* If main_cycle returns false, don't process more events! */ -int main_cycle() { +int AgiEngine::main_cycle() { unsigned int key, kascii; struct vt_entry *v = &game.view_table[0]; - poll_timer(); /* msdos driver -> does nothing */ + _gfx->pollTimer(); /* msdos driver -> does nothing */ update_timer(); if (game.ver == 0) { - _text->message_box("Warning: game CRC not listed, assuming AGI version 2.917."); + message_box("Warning: game CRC not listed, assuming AGI version 2.917."); game.ver = -1; } @@ -213,22 +206,21 @@ int main_cycle() { * vars in every interpreter cycle. */ if (opt.agimouse) { - game.vars[28] = mouse.x / 2; - game.vars[29] = mouse.y; + game.vars[28] = g_mouse.x / 2; + game.vars[29] = g_mouse.y; } - if (key == KEY_PRIORITY) { _sprites->erase_both(); - debug_.priority = !debug_.priority; - show_pic(); + _debug.priority = !_debug.priority; + _picture->show_pic(); _sprites->blit_both(); _sprites->commit_both(); key = 0; } if (key == KEY_STATUSLN) { - debug_.statusline = !debug_.statusline; - _text->write_status(); + _debug.statusline = !_debug.statusline; + write_status(); key = 0; } @@ -274,7 +266,7 @@ int main_cycle() { break; case INPUT_MENU: menu->keyhandler(key); - do_update(); + _gfx->doUpdate(); return false; case INPUT_NONE: handle_controller(key); @@ -282,8 +274,7 @@ int main_cycle() { game.keypress = key; break; } - - do_update(); + _gfx->doUpdate(); if (game.msg_box_ticks > 0) game.msg_box_ticks--; @@ -291,14 +282,14 @@ int main_cycle() { return true; } -static int play_game() { +int AgiEngine::play_game() { int ec = err_OK; debugC(2, kDebugLevelMain, "initializing..."); debugC(2, kDebugLevelMain, "game.ver = 0x%x", game.ver); - stop_sound(); - clear_screen(0); + _sound->stop_sound(); + _gfx->clearScreen(0); game.horizon = HORIZON; game.player_control = false; @@ -329,14 +320,12 @@ static int play_game() { if (!main_cycle()) continue; - if (getvar(V_time_delay) == 0 || - (1 + clock_count) % getvar(V_time_delay) == 0) { + if (getvar(V_time_delay) == 0 || (1 + clock_count) % getvar(V_time_delay) == 0) { if (!game.has_prompt && game.input_mode == INPUT_NORMAL) { - _text->write_prompt(); + write_prompt(); game.has_prompt = 1; - } else - if (game.has_prompt && game.input_mode == INPUT_NONE) { - _text->write_prompt(); + } else if (game.has_prompt && game.input_mode == INPUT_NONE) { + write_prompt(); game.has_prompt = 0; } @@ -353,12 +342,12 @@ static int play_game() { } while (game.quit_prog_now == 0); - stop_sound(); + _sound->stop_sound(); return ec; } -int run_game() { +int AgiEngine::run_game() { int i, ec = err_OK; if (opt.renderMode == Common::kRenderCGA) @@ -372,7 +361,7 @@ int run_game() { debugC(2, kDebugLevelMain, "game loop"); debugC(2, kDebugLevelMain, "game.ver = 0x%x", game.ver); - if (agi_init() != err_OK) + if (agiInit() != err_OK) break; if (ec == err_RestartGame) setflag(F_restart_game, true); @@ -388,7 +377,7 @@ int run_game() { game.state = STATE_RUNNING; ec = play_game(); game.state = STATE_LOADED; - agi_deinit(); + agiDeinit(); } while (ec == err_RestartGame); delete menu; diff --git a/engines/agi/global.cpp b/engines/agi/global.cpp index 82021378b0..8a0d999a2e 100644 --- a/engines/agi/global.cpp +++ b/engines/agi/global.cpp @@ -28,14 +28,14 @@ namespace Agi { -int getflag(int n) { +int AgiEngine::getflag(int n) { uint8 *set = (uint8 *) &game.flags; set += n >> 3; return (*set & (1 << (n & 0x07))) != 0; } -void setflag(int n, int v) { +void AgiEngine::setflag(int n, int v) { uint8 *set = (uint8 *) &game.flags; set += n >> 3; @@ -45,22 +45,22 @@ void setflag(int n, int v) { *set &= ~(1 << (n & 0x07)); /* clear bit */ } -void flipflag(int n) { +void AgiEngine::flipflag(int n) { uint8 *set = (uint8 *) & game.flags; set += n >> 3; *set ^= 1 << (n & 0x07); /* flip bit */ } -void setvar(int var, int val) { +void AgiEngine::setvar(int var, int val) { game.vars[var] = val; } -int getvar(int var) { +int AgiEngine::getvar(int var) { return game.vars[var]; } -void decrypt(uint8 *mem, int len) { +void AgiEngine::decrypt(uint8 *mem, int len) { const uint8 *key; int i; diff --git a/engines/agi/graphics.cpp b/engines/agi/graphics.cpp index 8499e29ea1..221ae40544 100644 --- a/engines/agi/graphics.cpp +++ b/engines/agi/graphics.cpp @@ -39,10 +39,6 @@ namespace Agi { # define MAX_INT (int)((unsigned)~0 >> 1) #endif -static uint8 *agi_screen; - -static unsigned char *screen; - extern uint8 cur_font[]; /** @@ -91,8 +87,6 @@ uint8 new_palette[16 * 3] = { 0x3F, 0x3F, 0x3F }; -uint8 palette[32 * 3]; - static uint16 cga_map[16] = { 0x0000, /* 0 - black */ 0x0d00, /* 1 - blue */ @@ -136,9 +130,8 @@ static struct update_block update = { */ #define SHAKE_MAG 3 -static uint8 *shake_h, *shake_v; -void shake_start() { +void GfxMgr::shakeStart() { int i; if ((shake_h = (uint8 *)malloc(GFX_WIDTH * SHAKE_MAG)) == NULL) @@ -158,7 +151,7 @@ void shake_start() { } } -void shake_screen(int n) { +void GfxMgr::shakeScreen(int n) { int i; if (n == 0) { @@ -175,7 +168,7 @@ void shake_screen(int n) { } } -void shake_end() { +void GfxMgr::shakeEnd() { int i; for (i = 0; i < GFX_HEIGHT - SHAKE_MAG; i++) { @@ -186,13 +179,13 @@ void shake_end() { memcpy(agi_screen + i * GFX_WIDTH, shake_h + i * GFX_WIDTH, GFX_WIDTH); } - flush_block(0, 0, GFX_WIDTH - 1, GFX_HEIGHT - 1); + flushBlock(0, 0, GFX_WIDTH - 1, GFX_HEIGHT - 1); free(shake_v); free(shake_h); } -void put_text_character(int l, int x, int y, unsigned int c, int fg, int bg) { +void GfxMgr::putTextCharacter(int l, int x, int y, unsigned int c, int fg, int bg) { int x1, y1, xx, yy, cc; uint8 *p; @@ -210,10 +203,10 @@ void put_text_character(int l, int x, int y, unsigned int c, int fg, int bg) { /* FIXME: we don't want this when we're writing on the * console! */ - flush_block(x, y, x + CHAR_COLS - 1, y + CHAR_LINES - 1); + flushBlock(x, y, x + CHAR_COLS - 1, y + CHAR_LINES - 1); } -void draw_rectangle(int x1, int y1, int x2, int y2, int c) { +void GfxMgr::drawRectangle(int x1, int y1, int x2, int y2, int c) { int y, w, h; uint8 *p0; @@ -235,7 +228,7 @@ void draw_rectangle(int x1, int y1, int x2, int y2, int c) { } } -static void draw_frame(int x1, int y1, int x2, int y2, int c1, int c2) { +void GfxMgr::drawFrame(int x1, int y1, int x2, int y2, int c1, int c2) { int y, w; uint8 *p0; @@ -255,22 +248,22 @@ static void draw_frame(int x1, int y1, int x2, int y2, int c1, int c2) { } } -void draw_box(int x1, int y1, int x2, int y2, int colour1, int colour2, int m) { +void GfxMgr::drawBox(int x1, int y1, int x2, int y2, int colour1, int colour2, int m) { x1 += m; y1 += m; x2 -= m; y2 -= m; - draw_rectangle(x1, y1, x2, y2, colour1); - draw_frame(x1 + 2, y1 + 2, x2 - 2, y2 - 2, colour2, colour2); - flush_block(x1, y1, x2, y2); + drawRectangle(x1, y1, x2, y2, colour1); + drawFrame(x1 + 2, y1 + 2, x2 - 2, y2 - 2, colour2, colour2); + flushBlock(x1, y1, x2, y2); } -void print_character(int x, int y, char c, int fg, int bg) { +void GfxMgr::printCharacter(int x, int y, char c, int fg, int bg) { x *= CHAR_COLS; y *= CHAR_LINES; - put_text_character(0, x, y, c, fg, bg); + putTextCharacter(0, x, y, c, fg, bg); // redundant! already inside put_text_character! // flush_block (x, y, x + CHAR_COLS - 1, y + CHAR_LINES - 1); } @@ -282,7 +275,7 @@ void print_character(int x, int y, char c, int fg, int bg) { * @param a set if the button has focus * @param p set if the button is pressed */ -void draw_button(int x, int y, const char *s, int a, int p, int fgcolor, int bgcolor) { +void GfxMgr::drawButton(int x, int y, const char *s, int a, int p, int fgcolor, int bgcolor) { int len = strlen(s); int x1, y1, x2, y2; @@ -292,7 +285,7 @@ void draw_button(int x, int y, const char *s, int a, int p, int fgcolor, int bgc y2 = y + CHAR_LINES + 2; while (*s) { - put_text_character(0, x + (!!p), y + (!!p), *s++, a ? fgcolor : bgcolor, a ? bgcolor : fgcolor); + putTextCharacter(0, x + (!!p), y + (!!p), *s++, a ? fgcolor : bgcolor, a ? bgcolor : fgcolor); x += CHAR_COLS; } @@ -301,10 +294,10 @@ void draw_button(int x, int y, const char *s, int a, int p, int fgcolor, int bgc x2 += 2; y2 += 2; - flush_block(x1, y1, x2, y2); + flushBlock(x1, y1, x2, y2); } -int test_button(int x, int y, const char *s) { +int GfxMgr::testButton(int x, int y, const char *s) { int len = strlen(s); int x1, y1, x2, y2; @@ -313,30 +306,30 @@ int test_button(int x, int y, const char *s) { x2 = x + CHAR_COLS * len + 2; y2 = y + CHAR_LINES + 2; - if ((int)mouse.x >= x1 && (int)mouse.y >= y1 && (int)mouse.x <= x2 && (int)mouse.y <= y2) + if ((int)g_mouse.x >= x1 && (int)g_mouse.y >= y1 && (int)g_mouse.x <= x2 && (int)g_mouse.y <= y2) return true; return false; } -void put_block(int x1, int y1, int x2, int y2) { - gfx_putblock(x1, y1, x2, y2); +void GfxMgr::putBlock(int x1, int y1, int x2, int y2) { + gfxPutBlock(x1, y1, x2, y2); } -void put_screen() { - put_block(0, 0, GFX_WIDTH - 1, GFX_HEIGHT - 1); +void GfxMgr::putScreen() { + putBlock(0, 0, GFX_WIDTH - 1, GFX_HEIGHT - 1); } -void poll_timer() { - agi_timer_low(); +void GfxMgr::pollTimer() { + _vm->agiTimerLow(); } -int get_key() { - return agi_get_keypress_low(); +int GfxMgr::getKey() { + return _vm->agiGetKeypressLow(); } -int keypress() { - return agi_is_keypress_low(); +int GfxMgr::keypress() { + return _vm->agiIsKeypressLow(); } /* @@ -350,7 +343,7 @@ int keypress() { * for the interpreter console. * @param p A pointer to the 16-color RGB palette. */ -void init_palette(uint8 *p) { +void GfxMgr::initPalette(uint8 *p) { int i; for (i = 0; i < 48; i++) { @@ -359,7 +352,7 @@ void init_palette(uint8 *p) { } } -void gfx_set_palette() { +void GfxMgr::gfxSetPalette() { int i; byte pal[32 * 4]; @@ -373,7 +366,7 @@ void gfx_set_palette() { } /* put a block onto the screen */ -void gfx_putblock(int x1, int y1, int x2, int y2) { +void GfxMgr::gfxPutBlock(int x1, int y1, int x2, int y2) { if (x1 >= GFX_WIDTH) x1 = GFX_WIDTH - 1; if (y1 >= GFX_HEIGHT) @@ -384,7 +377,6 @@ void gfx_putblock(int x1, int y1, int x2, int y2) { y2 = GFX_HEIGHT - 1; g_system->copyRectToScreen(screen + y1 * 320 + x1, 320, x1, y1, x2 - x1 + 1, y2 - y1 + 1); - //g_system->copyRectToScreen(screen, 320, 0, 0, 320, 200); } static const byte mouseCursorArrow[] = { @@ -403,16 +395,16 @@ static const byte mouseCursorArrow[] = { * * @see deinit_video() */ -int init_video() { - if (opt.renderMode == Common::kRenderEGA) - init_palette(ega_palette); +int GfxMgr::initVideo() { + if (_vm->opt.renderMode == Common::kRenderEGA) + initPalette(ega_palette); else - init_palette(new_palette); + initPalette(new_palette); if ((agi_screen = (uint8 *)calloc(GFX_WIDTH, GFX_HEIGHT)) == NULL) return err_NotEnoughMemory; - gfx_set_palette(); + gfxSetPalette(); byte mouseCursor[16 * 16]; const byte *src = mouseCursorArrow; @@ -440,21 +432,20 @@ int init_video() { * * @see init_video() */ -int deinit_video() { +int GfxMgr::deinitVideo() { free(agi_screen); return err_OK; } -int init_machine() { +int GfxMgr::initMachine() { screen = (unsigned char *)malloc(320 * 200); - clock_count = 0; - clock_ticks = 0; + _vm->clock_count = 0; return err_OK; } -int deinit_machine() { +int GfxMgr::deinitMachine() { free(screen); return err_OK; @@ -470,29 +461,29 @@ int deinit_machine() { * @param n number of pixels in the row * @param p pointer to the row start in the AGI screen */ -void put_pixels_a(int x, int y, int n, uint8 *p) { - if (opt.renderMode == Common::kRenderCGA) { +void GfxMgr::putPixelsA(int x, int y, int n, uint8 *p) { + if (_vm->opt.renderMode == Common::kRenderCGA) { for (x *= 2; n--; p++, x += 2) { register uint16 q = (cga_map[(*p & 0xf0) >> 4] << 4) | cga_map[*p & 0x0f]; - if (debug_.priority) + if (_vm->_debug.priority) q >>= 4; *(uint16 *)&agi_screen[x + y * GFX_WIDTH] = q & 0x0f0f; } } else { for (x *= 2; n--; p++, x += 2) { register uint16 q = ((uint16) * p << 8) | *p; - if (debug_.priority) + if (_vm->_debug.priority) q >>= 4; *(uint16 *)&agi_screen[x + y * GFX_WIDTH] = q & 0x0f0f; } } } -void put_pixels_hires(int x, int y, int n, uint8 *p) { +void GfxMgr::putPixelsHires(int x, int y, int n, uint8 *p) { //y += CHAR_LINES; for (; n--; p++, x++) { uint8 q = *p; - if (debug_.priority) + if (_vm->_debug.priority) q >>= 4; agi_screen[x + y * GFX_WIDTH] = q & 0x0f; } @@ -509,7 +500,7 @@ void put_pixels_hires(int x, int y, int n, uint8 *p) { * * @see do_update() */ -void schedule_update(int x1, int y1, int x2, int y2) { +void GfxMgr::scheduleUpdate(int x1, int y1, int x2, int y2) { if (x1 < update.x1) update.x1 = x1; if (y1 < update.y1) @@ -527,9 +518,9 @@ void schedule_update(int x1, int y1, int x2, int y2) { * * @see schedule_update() */ -void do_update() { +void GfxMgr::doUpdate() { if (update.x1 <= update.x2 && update.y1 <= update.y2) { - gfx_putblock(update.x1, update.y1, update.x2, update.y2); + gfxPutBlock(update.x1, update.y1, update.x2, update.y2); } /* reset update block variables */ @@ -550,11 +541,11 @@ void do_update() { * * @see flush_block_a() */ -void flush_block(int x1, int y1, int x2, int y2) { +void GfxMgr::flushBlock(int x1, int y1, int x2, int y2) { int y, w; uint8 *p0; - schedule_update(x1, y1, x2, y2); + scheduleUpdate(x1, y1, x2, y2); p0 = &agi_screen[x1 + y1 * GFX_WIDTH]; w = x2 - x1 + 1; @@ -574,10 +565,10 @@ void flush_block(int x1, int y1, int x2, int y2) { * * @see flush_block() */ -void flush_block_a(int x1, int y1, int x2, int y2) { +void GfxMgr::flushBlockA(int x1, int y1, int x2, int y2) { //y1 += 8; //y2 += 8; - flush_block(DEV_X0(x1), DEV_Y(y1), DEV_X1(x2), DEV_Y(y2)); + flushBlock(DEV_X0(x1), DEV_Y(y1), DEV_X1(x2), DEV_Y(y2)); } /** @@ -585,8 +576,8 @@ void flush_block_a(int x1, int y1, int x2, int y2) { * This function updates the output device with the contents of the AGI * screen, handling console transparency. */ -void flush_screen() { - flush_block(0, 0, GFX_WIDTH - 1, GFX_HEIGHT - 1); +void GfxMgr::flushScreen() { + flushBlock(0, 0, GFX_WIDTH - 1, GFX_HEIGHT - 1); } /** @@ -597,15 +588,15 @@ void flush_screen() { * a graphic-only device. * @param c color to clear the screen */ -void clear_screen(int c) { +void GfxMgr::clearScreen(int c) { memset(agi_screen, c, GFX_WIDTH * GFX_HEIGHT); - flush_screen(); + flushScreen(); } /** * Save a block of the AGI engine screen */ -void save_block(int x1, int y1, int x2, int y2, uint8 *b) { +void GfxMgr::saveBlock(int x1, int y1, int x2, int y2, uint8 *b) { uint8 *p0; int w, h; @@ -622,7 +613,7 @@ void save_block(int x1, int y1, int x2, int y2, uint8 *b) { /** * Restore a block of the AGI engine screen */ -void restore_block(int x1, int y1, int x2, int y2, uint8 *b) { +void GfxMgr::restoreBlock(int x1, int y1, int x2, int y2, uint8 *b) { uint8 *p0; int w, h; @@ -634,7 +625,7 @@ void restore_block(int x1, int y1, int x2, int y2, uint8 *b) { b += w; p0 += GFX_WIDTH; } - flush_block(x1, y1, x2, y2); + flushBlock(x1, y1, x2, y2); } } // End of namespace Agi diff --git a/engines/agi/graphics.h b/engines/agi/graphics.h index 2f45dcb289..eef9a42bd7 100644 --- a/engines/agi/graphics.h +++ b/engines/agi/graphics.h @@ -27,8 +27,6 @@ #include "common/stdafx.h" -#include "agi/agi.h" - namespace Agi { #define GFX_WIDTH 320 @@ -36,47 +34,66 @@ namespace Agi { #define CHAR_COLS 8 #define CHAR_LINES 8 -extern uint8 palette[]; - -/* Transparent layer */ -extern uint8 layer1_data[]; -extern uint8 layer2_data[]; - -void gfx_putblock(int x1, int y1, int x2, int y2); - -void put_text_character(int, int, int, unsigned int, int, int); -void shake_screen(int); -void shake_start(void); -void shake_end(void); -void save_screen(void); -void restore_screen(void); - -int init_video(void); -int deinit_video(void); -void schedule_update(int, int, int, int); -void do_update(void); -void put_screen(void); -void flush_block(int, int, int, int); -void flush_block_a(int, int, int, int); -void put_pixels_a(int, int, int, uint8 *); -void flush_screen(void); -void clear_screen(int); -void clear_console_screen(int); -void draw_box(int, int, int, int, int, int, int); -void draw_button(int, int, const char *, int, int, int fgcolor = 0, int bgcolor = 0); -int test_button(int, int, const char *); -void draw_rectangle(int, int, int, int, int); -void save_block(int, int, int, int, uint8 *); -void restore_block(int, int, int, int, uint8 *); -void init_palette(uint8 *); - -void put_pixel(int, int, int); - -void put_pixels_hires(int x, int y, int n, uint8 * p); -int keypress(void); -int get_key(void); -void print_character(int, int, char, int, int); -void poll_timer(void); +class AgiEngine; + +class GfxMgr { +private: + AgiEngine *_vm; + + uint8 palette[32 * 3]; + uint8 *agi_screen; + unsigned char *screen; + + uint8 *shake_h, *shake_v; + +public: + GfxMgr(AgiEngine *vm) { + _vm = vm; + shake_h = NULL; + shake_v = NULL; + } + + void gfxPutBlock(int x1, int y1, int x2, int y2); + + void putTextCharacter(int, int, int, unsigned int, int, int); + void shakeScreen(int); + void shakeStart(); + void shakeEnd(); + void saveScreen(); + void restoreScreen(); + + int initVideo(); + int deinitVideo(); + void scheduleUpdate(int, int, int, int); + void doUpdate(); + void putScreen(); + void flushBlock(int, int, int, int); + void flushBlockA(int, int, int, int); + void putPixelsA(int, int, int, uint8 *); + void flushScreen(); + void clearScreen(int); + void clearConsoleScreen(int); + void drawBox(int, int, int, int, int, int, int); + void drawButton(int, int, const char *, int, int, int fgcolor = 0, int bgcolor = 0); + int testButton(int, int, const char *); + void drawRectangle(int, int, int, int, int); + void saveBlock(int, int, int, int, uint8 *); + void restoreBlock(int, int, int, int, uint8 *); + void initPalette(uint8 *); + void drawFrame(int x1, int y1, int x2, int y2, int c1, int c2); + + void putPixel(int, int, int); + void putBlock(int x1, int y1, int x2, int y2); + void gfxSetPalette(); + void putPixelsHires(int x, int y, int n, uint8 *p); + + int keypress(); + int getKey(); + void printCharacter(int, int, char, int, int); + void pollTimer(); + int initMachine(); + int deinitMachine(); +}; } // End of namespace Agi diff --git a/engines/agi/id.cpp b/engines/agi/id.cpp index 7736f76573..eeb6309042 100644 --- a/engines/agi/id.cpp +++ b/engines/agi/id.cpp @@ -75,7 +75,7 @@ const char *ids_database = "0x53971 0x3149 Manhunter SF (PC 3.5) 3.02 7/26/89 [AGI 3.002.149] \n" "0x584F9 0x3149 Manhunter SF (PC 5.25) 3.03 8/17/89 [AGI 3.002.149] \n" "0x5D77C 0x2917 Mixed-Up Mother Goose (PC) [AGI 2.915] \n" -"0x5D7C6 0x2917 Mixed Up Mother Goose (PC) [AGI 2.915] (Broken) \n" +"0x5D7C6 0x2917 Mixed Up Mother Goose (PC) [AGI 2.915] (Broken) \n" "0x7F18B 0x2917 Police Quest 1 (PC) 2.0A 10/23/87 [AGI 2.903/2.911] \n" "0x7EF35 0x2917 Police Quest 1 (PC) 2.0E 11/17/87 [AGI 2.915] \n" "0x7EF06 0x2917 Police Quest 1 (PC 5.25/ST) 2.0G 12/03/87 [AGI 2.917] \n" @@ -111,7 +111,7 @@ const char *ids_database = "0xAF778 0x3086 King's Quest 4 (IIgs) 1.0K 11/22/88 (CE) \n" "0x6E41E 0x2440 Leisure Suit Larry 1 (IIgs) 1.0E \n" "0x4C705 0x3149 Manhunter NY (IIgs) 2.0E 10/05/88 (CE) \n" -"0x5F4E8 0x2917 Mixed Up Mother Goose (IIgs) \n" +"0x5F4E8 0x2917 Mixed Up Mother Goose (IIgs) \n" "0x7DB3F 0x2917 Police Quest 1 (IIgs) 2.0A-88318 \n" "0x7DBE5 0x2917 Police Quest 1 (IIgs) 2.0B-88421 \n" "0x69EC0 0x2917 Space Quest 1 (IIgs) 2.2 \n" @@ -160,7 +160,7 @@ const char *ids_database = "0xB3E1A 0x3149 [A] Gold Rush! (Amiga) 1.01 1/13/89 aka 2.05 3/9/89 # 2.316 \n" "0x49C6B 0x2440 [A] King's Quest 1 (Amiga) 1.0U # 2.082 \n" "0x5D395 0x2440 [A] King's Quest 2 (Amiga) 2.0J # guessed int \n" -"0x5BCE6 0x2440 [A] King's Quest 2 (Amiga) 2.0J (Broken) \n" +"0x5BCE6 0x2440 [A] King's Quest 2 (Amiga) 2.0J (Broken) \n" "0x5F4B9 0x2440 [A] King's Quest 2 (Amiga) 2.0J (Broken) # 2.176 \n" "0x888C1 0x2440 [A] King's Quest 3 (Amiga) 1.01 11/8/86 \n" "0x84793 0x3086 [A] King's Quest 3 (Amiga) 2.15 11/15/89 # 2.333 \n" @@ -196,8 +196,8 @@ const char *ids_database = "#---------------------------------------------------------------------------- \n" " \n" "0x3F2F7 0x2917 [m] AGI Mouse 0.7 Demo \n" -"0x3F744 0x2917 [m] AGI Mouse 1.0 Demo # 2.917 6/24/00 \n" -"0x3F74F 0x2917 [m] AGI Mouse 1.1 Demo # 2.917 1/01/01 \n" +"0x3F744 0x2917 [m] AGI Mouse 1.0 Demo # 2.917 6/24/00 \n" +"0x3F74F 0x2917 [m] AGI Mouse 1.1 Demo # 2.917 1/01/01 \n" "0x17599 0x2917 [m] Sliding Tile Game v1.00 # 2.917 6/02/01 \n" "0x785c4 0x2936 [m] Jolimie v0.6 # 2.936 2000 \n" "#Jolimie uses AGIPal only and not AGIMouse; no way to separate these currently \n" @@ -226,11 +226,7 @@ const char *ids_database = "0x4EE64 0x2917 Monkey Man \n" ""; -int setup_v2_game(int ver, uint32 crc); -int setup_v3_game(int ver, uint32 crc); -int v4id_game(uint32 crc); - -uint32 match_crc(uint32 crc, char *name, int len) { +uint32 AgiEngine::match_crc(uint32 crc, char *name, int len) { char *c, *t, buf[256]; uint32 id, ver; @@ -296,7 +292,7 @@ uint32 match_crc(uint32 crc, char *name, int len) { return 0; } -static uint32 match_version(uint32 crc) { +uint32 AgiEngine::match_version(uint32 crc) { int ver; char name[80]; @@ -306,7 +302,7 @@ static uint32 match_version(uint32 crc) { return ver; } -int v2id_game() { +int AgiEngine::v2id_game() { int y, ver; uint32 len, c, crc; uint8 *buff; @@ -333,7 +329,7 @@ int v2id_game() { game.crc = crc; game.ver = ver; debugC(2, kDebugLevelMain, "game.ver = 0x%x", game.ver); - agi_set_release(ver); + agiSetRelease(ver); return setup_v2_game(ver, crc); } @@ -345,7 +341,7 @@ int v2id_game() { * 0x0149 */ -int v3id_game() { +int AgiEngine::v3id_game() { int ec = err_OK, y, ver; uint32 len, c, crc; uint8 *buff; @@ -388,7 +384,7 @@ int v3id_game() { ver = match_version(crc); game.crc = crc; game.ver = ver; - agi_set_release(ver); + agiSetRelease(ver); ec = setup_v3_game(ver, crc); @@ -398,24 +394,24 @@ int v3id_game() { /** * */ -int setup_v2_game(int ver, uint32 crc) { +int AgiEngine::setup_v2_game(int ver, uint32 crc) { int ec = err_OK; if (ver == 0) { report("Unknown v2 Sierra game: %08x\n\n", crc); - agi_set_release(0x2917); + agiSetRelease(0x2917); } /* setup the differences in the opcodes and other bits in the * AGI v2 specs */ if (opt.emuversion) - agi_set_release(opt.emuversion); + agiSetRelease(opt.emuversion); if (opt.agds) - agi_set_release(0x2440); /* ALL AGDS games built for 2.440 */ + agiSetRelease(0x2440); /* ALL AGDS games built for 2.440 */ - switch (agi_get_release()) { + switch (agiGetRelease()) { case 0x2089: logic_names_cmd[0x86].num_args = 0; /* quit: 0 args */ logic_names_cmd[0x97].num_args = 3; /* print.at: 3 args */ @@ -442,16 +438,16 @@ int setup_v2_game(int ver, uint32 crc) { /** * */ -int setup_v3_game(int ver, uint32 crc) { +int AgiEngine::setup_v3_game(int ver, uint32 crc) { int ec = err_OK; if (ver == 0) { report("Unknown v3 Sierra game: %08x\n\n", crc); - agi_set_release(ver = 0x3149); + agiSetRelease(ver = 0x3149); } if (opt.emuversion) - agi_set_release(ver = opt.emuversion); + agiSetRelease(ver = opt.emuversion); switch (ver) { case 0x3086: diff --git a/engines/agi/inv.cpp b/engines/agi/inv.cpp index 4c1f524638..56f1558734 100644 --- a/engines/agi/inv.cpp +++ b/engines/agi/inv.cpp @@ -53,19 +53,16 @@ namespace Agi { #define SELECT_Y 24 #define SELECT_MSG "Press ENTER to select, ESC to cancel" -static uint8 *intobj = NULL; - -static void print_item(int n, int fg, int bg) -{ - _text->print_text(object_name(intobj[n]), 0, n % 2 ? 39 - strlen(object_name(intobj[n])) : 1, +void AgiEngine::printItem(int n, int fg, int bg) { + print_text(object_name(intobj[n]), 0, n % 2 ? 39 - strlen(object_name(intobj[n])) : 1, (n / 2) + 2, 40, fg, bg); } -static int find_item() { +int AgiEngine::findItem() { int r, c; - r = mouse.y / CHAR_LINES; - c = mouse.x / CHAR_COLS; + r = g_mouse.y / CHAR_LINES; + c = g_mouse.x / CHAR_COLS; debugC(6, kDebugLevelInventory, "r = %d, c = %d", r, c); @@ -75,31 +72,31 @@ static int find_item() { return (r - 2) * 2 + (c > 20); } -static int show_items() { +int AgiEngine::showItems() { unsigned int x, i; for (x = i = 0; x < game.num_objects; x++) { if (object_get_location(x) == EGO_OWNED) { /* add object to our list! */ intobj[i] = x; - print_item(i, STATUS_FG, STATUS_BG); + printItem(i, STATUS_FG, STATUS_BG); i++; } } if (i == 0) { - _text->print_text(NOTHING_MSG, 0, NOTHING_X, NOTHING_Y, 40, STATUS_FG, STATUS_BG); + print_text(NOTHING_MSG, 0, NOTHING_X, NOTHING_Y, 40, STATUS_FG, STATUS_BG); } return i; } -static void select_items(int n) { +void AgiEngine::selectItems(int n) { int fsel = 0; - while (42) { + for (;;) { if (n > 0) - print_item(fsel, STATUS_BG, STATUS_FG); + printItem(fsel, STATUS_BG, STATUS_FG); switch (wait_any_key()) { case KEY_ENTER: @@ -125,13 +122,13 @@ static void select_items(int n) { fsel++; break; case BUTTON_LEFT:{ - int i = find_item(); + int i = findItem(); if (i >= 0 && i < n) { setvar(V_sel_item, intobj[fsel = i]); debugC(6, kDebugLevelInventory, "item found: %d", fsel); - show_items(); - print_item(fsel, STATUS_BG, STATUS_FG); - do_update(); + showItems(); + printItem(fsel, STATUS_BG, STATUS_FG); + _gfx->doUpdate(); goto exit_select; } break; @@ -140,11 +137,11 @@ static void select_items(int n) { break; } - show_items(); - do_update(); + showItems(); + _gfx->doUpdate(); } - exit_select: +exit_select: debugC(6, kDebugLevelInventory, "selected: %d", fsel); } @@ -155,7 +152,7 @@ static void select_items(int n) { /** * Display inventory items. */ -void inventory() { +void AgiEngine::inventory() { int old_fg, old_bg; int n; @@ -164,24 +161,24 @@ void inventory() { old_bg = game.color_bg; game.color_fg = 0; game.color_bg = 15; - clear_screen(game.color_bg); + _gfx->clearScreen(game.color_bg); - _text->print_text(YOUHAVE_MSG, 0, YOUHAVE_X, YOUHAVE_Y, 40, STATUS_FG, STATUS_BG); + print_text(YOUHAVE_MSG, 0, YOUHAVE_X, YOUHAVE_Y, 40, STATUS_FG, STATUS_BG); /* FIXME: doesn't check if objects overflow off screen... */ intobj = (uint8 *) malloc(4 + game.num_objects); memset(intobj, 0, (4 + game.num_objects)); - n = show_items(); + n = showItems(); if (getflag(F_status_selects_items)) { - _text->print_text(SELECT_MSG, 0, SELECT_X, SELECT_Y, 40, STATUS_FG, STATUS_BG); + print_text(SELECT_MSG, 0, SELECT_X, SELECT_Y, 40, STATUS_FG, STATUS_BG); } else { - _text->print_text(ANY_KEY_MSG, 0, ANY_KEY_X, ANY_KEY_Y, 40, STATUS_FG, STATUS_BG); + print_text(ANY_KEY_MSG, 0, ANY_KEY_X, ANY_KEY_Y, 40, STATUS_FG, STATUS_BG); } - flush_screen(); + _gfx->flushScreen(); /* If flag 13 is set, we want to highlight & select an item. * opon selection, put objnum in var 25. Then on esc put in @@ -189,20 +186,20 @@ void inventory() { */ if (getflag(F_status_selects_items)) - select_items(n); + selectItems(n); free(intobj); if (!getflag(F_status_selects_items)) wait_any_key(); - clear_screen(0); - _text->write_status(); - show_pic(); + _gfx->clearScreen(0); + write_status(); + _picture->show_pic(); game.color_fg = old_fg; game.color_bg = old_bg; game.has_prompt = 0; - _text->flush_lines(game.line_user_input, 24); + flush_lines(game.line_user_input, 24); } } // End of namespace Agi diff --git a/engines/agi/keyboard.cpp b/engines/agi/keyboard.cpp index bb8e99e7de..f159db3d36 100644 --- a/engines/agi/keyboard.cpp +++ b/engines/agi/keyboard.cpp @@ -32,20 +32,6 @@ namespace Agi { -char last_sentence[40]; - -/* FIXME */ -extern int open_dialogue; - -struct string_data { - int x; - int y; - int len; - int str; -}; - -struct string_data stringdata; - /* * IBM-PC keyboard scancodes */ @@ -78,16 +64,16 @@ uint8 scancode_table[26] = { 44 /* Z */ }; -void init_words() { +void AgiEngine::init_words() { game.num_ego_words = 0; } -void clean_input() { +void AgiEngine::clean_input() { while (game.num_ego_words) free(game.ego_words[--game.num_ego_words].word); } -void get_string(int x, int y, int len, int str) { +void AgiEngine::get_string(int x, int y, int len, int str) { new_input_mode(INPUT_GETSTRING); stringdata.x = x; stringdata.y = y; @@ -101,19 +87,19 @@ void get_string(int x, int y, int len, int str) { * It handles console keys and insulates AGI from the console. In the main * loop, handle_keys() handles keyboard input and ego movement. */ -int do_poll_keyboard() { +int AgiEngine::do_poll_keyboard() { int key = 0; /* If a key is ready, rip it */ - if (keypress()) { - key = get_key(); + if (_gfx->keypress()) { + key = _gfx->getKey(); debugC(3, kDebugLevelInput, "key %02x pressed", key); } return key; } -int handle_controller(int key) { +int AgiEngine::handle_controller(int key) { struct vt_entry *v = &game.view_table[0]; int i; @@ -133,7 +119,7 @@ int handle_controller(int key) { } if (key == BUTTON_LEFT) { - if (getflag(F_menus_work) && mouse.y <= CHAR_LINES) { + if (getflag(F_menus_work) && g_mouse.y <= CHAR_LINES) { new_input_mode(INPUT_MENU); return true; } @@ -172,10 +158,10 @@ int handle_controller(int key) { } if (key == BUTTON_LEFT && - (int)mouse.y >= game.line_user_input * CHAR_LINES && - (int)mouse.y <= (game.line_user_input + 1) * CHAR_LINES) { - if (_text->predictiveDialog()) { - strcpy((char *)game.input_buffer, _text->_predictiveResult); + (int)g_mouse.y >= game.line_user_input * CHAR_LINES && + (int)g_mouse.y <= (game.line_user_input + 1) * CHAR_LINES) { + if (predictiveDialog()) { + strcpy((char *)game.input_buffer, _predictiveResult); handle_keys(KEY_ENTER); } return true; @@ -185,8 +171,8 @@ int handle_controller(int key) { /* Handle mouse button events */ if (key == BUTTON_LEFT) { v->flags |= ADJ_EGO_XY; - v->parm1 = WIN_TO_PIC_X(mouse.x); - v->parm2 = WIN_TO_PIC_Y(mouse.y); + v->parm1 = WIN_TO_PIC_X(g_mouse.x); + v->parm2 = WIN_TO_PIC_Y(g_mouse.y); return true; } } @@ -202,7 +188,7 @@ int handle_controller(int key) { return false; } -void handle_getstring(int key) { +void AgiEngine::handle_getstring(int key) { static int pos = 0; /* Cursor position */ static char buf[40]; @@ -213,12 +199,12 @@ void handle_getstring(int key) { switch (key) { case BUTTON_LEFT: - if ((int)mouse.y >= stringdata.y * CHAR_LINES && - (int)mouse.y <= (stringdata.y + 1) * CHAR_LINES) { - if (_text->predictiveDialog()) { - strcpy(game.strings[stringdata.str], _text->_predictiveResult); + if ((int)g_mouse.y >= stringdata.y * CHAR_LINES && + (int)g_mouse.y <= (stringdata.y + 1) * CHAR_LINES) { + if (predictiveDialog()) { + strcpy(game.strings[stringdata.str], _predictiveResult); new_input_mode(INPUT_NORMAL); - print_character(stringdata.x + strlen(game.strings[stringdata.str]) + 1, + _gfx->printCharacter(stringdata.x + strlen(game.strings[stringdata.str]) + 1, stringdata.y, ' ', game.color_fg, game.color_bg); return; } @@ -232,7 +218,7 @@ void handle_getstring(int key) { debugC(3, kDebugLevelInput, "buffer=[%s]", buf); buf[pos = 0] = 0; new_input_mode(INPUT_NORMAL); - print_character(stringdata.x + strlen(game.strings[stringdata.str]) + 1, + _gfx->printCharacter(stringdata.x + strlen(game.strings[stringdata.str]) + 1, stringdata.y, ' ', game.color_fg, game.color_bg); return; case KEY_ESCAPE: @@ -247,9 +233,8 @@ void handle_getstring(int key) { if (!pos) break; - print_character(stringdata.x + (pos + 1), stringdata.y, + _gfx->printCharacter(stringdata.x + (pos + 1), stringdata.y, ' ', game.color_fg, game.color_bg); - pos--; buf[pos] = 0; break; @@ -264,18 +249,18 @@ void handle_getstring(int key) { buf[pos] = 0; /* Echo */ - print_character(stringdata.x + pos, stringdata.y, buf[pos - 1], + _gfx->printCharacter(stringdata.x + pos, stringdata.y, buf[pos - 1], game.color_fg, game.color_bg); break; } /* print cursor */ - print_character(stringdata.x + pos + 1, stringdata.y, + _gfx->printCharacter(stringdata.x + pos + 1, stringdata.y, (char)game.cursor_char, game.color_fg, game.color_bg); } -void handle_keys(int key) { +void AgiEngine::handle_keys(int key) { uint8 *p = NULL; int c = 0; static uint8 formated_entry[256]; @@ -316,8 +301,8 @@ void handle_keys(int key) { game.has_prompt = 0; game.input_buffer[game.cursor_pos = 0] = 0; debugC(3, kDebugLevelInput, "clear lines"); - _text->clear_lines(l, l + 1, bg); - _text->flush_lines(l, l + 1); + clear_lines(l, l + 1, bg); + flush_lines(l, l + 1); break; case KEY_ESCAPE: @@ -330,10 +315,10 @@ void handle_keys(int key) { break; /* erase cursor */ - print_character(game.cursor_pos + 1, l, ' ', fg, bg); + _gfx->printCharacter(game.cursor_pos + 1, l, ' ', fg, bg); game.input_buffer[--game.cursor_pos] = 0; /* Print cursor */ - print_character(game.cursor_pos + 1, l, game.cursor_char, fg, bg); + _gfx->printCharacter(game.cursor_pos + 1, l, game.cursor_char, fg, bg); break; default: /* Ignore invalid keystrokes */ @@ -348,48 +333,48 @@ void handle_keys(int key) { game.input_buffer[game.cursor_pos] = 0; /* echo */ - print_character(game.cursor_pos, l, game.input_buffer[game.cursor_pos - 1], fg, bg); + _gfx->printCharacter(game.cursor_pos, l, game.input_buffer[game.cursor_pos - 1], fg, bg); /* Print cursor */ - print_character(game.cursor_pos + 1, l, game.cursor_char, fg, bg); + _gfx->printCharacter(game.cursor_pos + 1, l, game.cursor_char, fg, bg); break; } } -int wait_key() { +int AgiEngine::wait_key() { int key; /* clear key queue */ - while (keypress()) { - get_key(); + while (_gfx->keypress()) { + _gfx->getKey(); } debugC(3, kDebugLevelInput, "waiting..."); - while (42) { - poll_timer(); /* msdos driver -> does nothing */ + for (;;) { + _gfx->pollTimer(); /* msdos driver -> does nothing */ key = do_poll_keyboard(); if (key == KEY_ENTER || key == KEY_ESCAPE || key == BUTTON_LEFT) break; - do_update(); + _gfx->doUpdate(); } return key; } -int wait_any_key() { +int AgiEngine::wait_any_key() { int key; /* clear key queue */ - while (keypress()) { - get_key(); + while (_gfx->keypress()) { + _gfx->getKey(); } debugC(3, kDebugLevelInput, "waiting..."); - while (42) { - poll_timer(); /* msdos driver -> does nothing */ + for (;;) { + _gfx->pollTimer(); /* msdos driver -> does nothing */ key = do_poll_keyboard(); if (key) break; - do_update(); + _gfx->doUpdate(); } return key; } diff --git a/engines/agi/keyboard.h b/engines/agi/keyboard.h index 1042f4e8d7..5a1937eed8 100644 --- a/engines/agi/keyboard.h +++ b/engines/agi/keyboard.h @@ -27,8 +27,6 @@ #include "common/stdafx.h" -#include "agi/agi.h" - namespace Agi { /* QNX4 has a KEY_DOWN defined which we don't need to care about */ @@ -75,18 +73,6 @@ namespace Agi { extern uint8 scancode_table[]; -void init_words(void); -void clean_input(void); -int do_poll_keyboard(void); -void clean_keyboard(void); -void handle_keys(int); -void handle_getstring(int); -int handle_controller(int); -void get_string(int, int, int, int); -uint16 agi_get_keypress(void); -int wait_key(void); -int wait_any_key(void); - } // End of namespace Agi #endif /* AGI_KEYBOARD_H */ diff --git a/engines/agi/logic.cpp b/engines/agi/logic.cpp index d22af38334..28d8b694f4 100644 --- a/engines/agi/logic.cpp +++ b/engines/agi/logic.cpp @@ -34,7 +34,7 @@ namespace Agi { * into a message list. * @param n The number of the logic resource to decode. */ -int decode_logic(int n) { +int AgiEngine::decode_logic(int n) { int ec = err_OK; int mstart, mend, mc; uint8 *m0; @@ -99,7 +99,7 @@ int decode_logic(int n) { * memory chunks allocated for this resource. * @param n The number of the logic resource to unload */ -void unload_logic(int n) { +void AgiEngine::unload_logic(int n) { if (game.dir_logic[n].flags & RES_LOADED) { free(game.logics[n].data); if (game.logics[n].num_texts) diff --git a/engines/agi/logic.h b/engines/agi/logic.h index 7c7e84ef40..5ceea0d661 100644 --- a/engines/agi/logic.h +++ b/engines/agi/logic.h @@ -25,7 +25,8 @@ #ifndef AGI_LOGIC_H #define AGI_LOGIC_H -#include "agi/agi.h" +#include "common/stdafx.h" +#include "common/scummsys.h" namespace Agi { @@ -41,9 +42,6 @@ struct agi_logic { const char **texts; /**< message list */ }; -int decode_logic(int); -void unload_logic(int); - } // End of namespace Agi #endif /* AGI_LOGIC_H */ diff --git a/engines/agi/menu.cpp b/engines/agi/menu.cpp index 3b6021986f..a127a060fd 100644 --- a/engines/agi/menu.cpp +++ b/engines/agi/menu.cpp @@ -34,8 +34,6 @@ namespace Agi { -Menu* menu; - // TODO: add constructor/destructor for agi_menu, agi_menu_option struct agi_menu_option { @@ -78,13 +76,13 @@ agi_menu_option *Menu::get_menu_option(int i, int j) { } void Menu::draw_menu_bar() { - _text->clear_lines(0, 0, MENU_BG); - _text->flush_lines(0, 0); + _vm->clear_lines(0, 0, MENU_BG); + _vm->flush_lines(0, 0); MenuList::iterator iter; for (iter = menubar.begin(); iter != menubar.end(); ++iter) { agi_menu *m = *iter; - _text->print_text(m->text, 0, m->col, 0, 40, MENU_FG, MENU_BG); + _vm->print_text(m->text, 0, m->col, 0, 40, MENU_FG, MENU_BG); } } @@ -92,8 +90,8 @@ void Menu::draw_menu_bar() { void Menu::draw_menu_hilite(int cur_menu) { agi_menu *m = get_menu(cur_menu); debugC(6, kDebugLevelMenu, "[%s]", m->text); - _text->print_text(m->text, 0, m->col, 0, 40, MENU_BG, MENU_FG); - _text->flush_lines(0, 0); + _vm->print_text(m->text, 0, m->col, 0, 40, MENU_BG, MENU_FG); + _vm->flush_lines(0, 0); } /* draw box and pulldowns. */ @@ -101,13 +99,13 @@ void Menu::draw_menu_option(int h_menu) { /* find which vertical menu it is */ agi_menu *m = get_menu(h_menu); - draw_box(m->wincol * CHAR_COLS, 1 * CHAR_LINES, (m->wincol + m->width + 2) * CHAR_COLS, + _gfx->drawBox(m->wincol * CHAR_COLS, 1 * CHAR_LINES, (m->wincol + m->width + 2) * CHAR_COLS, (1 + m->height + 2) * CHAR_LINES, MENU_BG, MENU_LINE, 0); MenuOptionList::iterator iter; for (iter = m->down.begin(); iter != m->down.end(); ++iter) { agi_menu_option* d = *iter; - _text->print_text(d->text, 0, m->wincol + 1, d->index + 2, m->width + 2, + _vm->print_text(d->text, 0, m->wincol + 1, d->index + 2, m->width + 2, d->enabled ? MENU_FG : MENU_DISABLED, MENU_BG); } } @@ -116,28 +114,28 @@ void Menu::draw_menu_option_hilite(int h_menu, int v_menu) { agi_menu *m = get_menu(h_menu); agi_menu_option *d = get_menu_option(h_menu, v_menu); - _text->print_text(d->text, 0, m->wincol + 1, v_menu + 2, m->width + 2, + _vm->print_text(d->text, 0, m->wincol + 1, v_menu + 2, m->width + 2, MENU_BG, d->enabled ? MENU_FG : MENU_DISABLED); } void Menu::new_menu_selected(int i) { - show_pic(); + _picture->show_pic(); draw_menu_bar(); draw_menu_hilite(i); draw_menu_option(i); } bool Menu::mouse_over_text(unsigned int line, unsigned int col, char *s) { - if (mouse.x < col * CHAR_COLS) + if (g_mouse.x < col * CHAR_COLS) return false; - if (mouse.x > (col + strlen(s)) * CHAR_COLS) + if (g_mouse.x > (col + strlen(s)) * CHAR_COLS) return false; - if (mouse.y < line * CHAR_LINES) + if (g_mouse.y < line * CHAR_LINES) return false; - if (mouse.y >= (line + 1) * CHAR_LINES) + if (g_mouse.y >= (line + 1) * CHAR_LINES) return false; return true; @@ -165,9 +163,13 @@ static void add_about_option() { * Public functions */ -Menu::Menu() { +Menu::Menu(AgiEngine *vm, GfxMgr *gfx, PictureMgr *picture) { + _vm = vm; + _gfx = gfx; + _picture = picture; h_index = 0; h_col = 1; + h_max_menu = 0; h_cur_menu = 0; v_cur_menu = 0; } @@ -263,22 +265,22 @@ bool Menu::keyhandler(int key) { static int menu_active = false; static int button_used = 0; - if (!getflag(F_menus_work)) + if (!_vm->getflag(F_menus_work)) return false; if (!menu_active) { - clock_val = game.clock_enabled; - game.clock_enabled = false; + clock_val = _vm->game.clock_enabled; + _vm->game.clock_enabled = false; draw_menu_bar(); } /* * Mouse handling */ - if (mouse.button) { + if (g_mouse.button) { int hmenu, vmenu; button_used = 1; /* Button has been used at least once */ - if (mouse.y <= CHAR_LINES) { + if (g_mouse.y <= CHAR_LINES) { /* on the menubar */ hmenu = 0; @@ -333,7 +335,7 @@ bool Menu::keyhandler(int key) { draw_menu_option_hilite(h_cur_menu, v_cur_menu); - if (mouse.y <= CHAR_LINES) { + if (g_mouse.y <= CHAR_LINES) { /* on the menubar */ } else { /* see which option we selected */ @@ -345,8 +347,8 @@ bool Menu::keyhandler(int key) { /* activate that option */ if (d->enabled) { debugC(6, kDebugLevelMenu | kDebugLevelInput, "event %d registered", d->event); - game.ev_keyp[d->event].occured = true; - game.ev_keyp[d->event].data = d->event; + _vm->game.ev_keyp[d->event].occured = true; + _vm->game.ev_keyp[d->event].data = d->event; goto exit_menu; } } @@ -375,7 +377,7 @@ bool Menu::keyhandler(int key) { agi_menu_option* d = get_menu_option(h_cur_menu, v_cur_menu); if (d->enabled) { debugC(6, kDebugLevelMenu | kDebugLevelInput, "event %d registered", d->event); - game.ev_keyp[d->event].occured = true; + _vm->game.ev_keyp[d->event].occured = true; goto exit_menu; } break; @@ -411,14 +413,14 @@ bool Menu::keyhandler(int key) { exit_menu: button_used = 0; - show_pic(); - _text->write_status(); - - setvar(V_key, 0); - game.keypress = 0; - game.clock_enabled = clock_val; - old_input_mode(); - debugC(3, kDebugLevelMenu, "exit_menu: input mode reset to %d", game.input_mode); + _picture->show_pic(); + _vm->write_status(); + + _vm->setvar(V_key, 0); + _vm->game.keypress = 0; + _vm->game.clock_enabled = clock_val; + _vm->old_input_mode(); + debugC(3, kDebugLevelMenu, "exit_menu: input mode reset to %d", _vm->game.input_mode); menu_active = false; return true; diff --git a/engines/agi/menu.h b/engines/agi/menu.h index f792984b74..fe33e2f225 100644 --- a/engines/agi/menu.h +++ b/engines/agi/menu.h @@ -40,9 +40,17 @@ struct agi_menu_option; typedef Common::List<agi_menu*> MenuList; typedef Common::List<agi_menu_option*> MenuOptionList; +class GfxMgr; +class PictureMgr; + class Menu { +private: + AgiEngine *_vm; + GfxMgr *_gfx; + PictureMgr *_picture; + public: - Menu(); + Menu(AgiEngine *vm, GfxMgr *gfx, PictureMgr *picture); ~Menu(); void add(const char *s); @@ -75,8 +83,6 @@ private: }; -extern Menu* menu; - } // End of namespace Agi #endif /* AGI_MENU_H */ diff --git a/engines/agi/motion.cpp b/engines/agi/motion.cpp index 79504bbdc5..d59c02b039 100644 --- a/engines/agi/motion.cpp +++ b/engines/agi/motion.cpp @@ -28,11 +28,11 @@ namespace Agi { -static int check_step(int delta, int step) { +int AgiEngine::check_step(int delta, int step) { return (-step >= delta) ? 0 : (step <= delta) ? 2 : 1; } -static int check_block(int x, int y) { +int AgiEngine::check_block(int x, int y) { if (x <= game.block.x1 || x >= game.block.x2) return false; @@ -42,7 +42,7 @@ static int check_block(int x, int y) { return true; } -static void changepos(struct vt_entry *v) { +void AgiEngine::changepos(struct vt_entry *v) { int b, x, y; int dx[9] = { 0, 0, 1, 1, 1, 0, -1, -1, -1 }; int dy[9] = { 0, -1, -1, 0, 1, 1, 1, 0, -1 }; @@ -64,23 +64,23 @@ static void changepos(struct vt_entry *v) { } } -static void motion_wander(struct vt_entry *v) { +void AgiEngine::motion_wander(struct vt_entry *v) { if (v->parm1--) { if (~v->flags & DIDNT_MOVE) return; } - v->direction = rnd->getRandomNumber(8); + v->direction = _rnd->getRandomNumber(8); if (is_ego_view(v)) { game.vars[V_ego_dir] = v->direction; while (v->parm1 < 6) { - v->parm1 = rnd->getRandomNumber(50); /* huh? */ + v->parm1 = _rnd->getRandomNumber(50); /* huh? */ } } } -static void motion_followego(struct vt_entry *v) { +void AgiEngine::motion_followego(struct vt_entry *v) { int ego_x, ego_y; int obj_x, obj_y; int dir; @@ -107,7 +107,7 @@ static void motion_followego(struct vt_entry *v) { } else if (v->flags & DIDNT_MOVE) { int d; - while ((v->direction = rnd->getRandomNumber(8)) == 0) { + while ((v->direction = _rnd->getRandomNumber(8)) == 0) { } d = (abs(ego_y - obj_y) + abs(ego_x - obj_x)) / 2; @@ -117,7 +117,7 @@ static void motion_followego(struct vt_entry *v) { return; } - while ((v->parm3 = rnd->getRandomNumber(d)) < v->step_size) { + while ((v->parm3 = _rnd->getRandomNumber(d)) < v->step_size) { } return; } @@ -142,7 +142,7 @@ static void motion_followego(struct vt_entry *v) { } } -static void motion_moveobj(struct vt_entry *v) { +void AgiEngine::motion_moveobj(struct vt_entry *v) { v->direction = get_direction(v->x_pos, v->y_pos, v->parm1, v->parm2, v->step_size); /* Update V6 if ego */ @@ -153,7 +153,7 @@ static void motion_moveobj(struct vt_entry *v) { in_destination(v); } -static void check_motion(struct vt_entry *v) { +void AgiEngine::check_motion(struct vt_entry *v) { switch (v->motion) { case MOTION_WANDER: motion_wander(v); @@ -177,7 +177,7 @@ static void check_motion(struct vt_entry *v) { /** * */ -void check_all_motions() { +void AgiEngine::check_all_motions() { struct vt_entry *v; for (v = game.view_table; v < &game.view_table[MAX_VIEWTABLE]; v++) { @@ -194,7 +194,7 @@ void check_all_motions() { * type motion that * has reached its final destination coordinates. * @param v Pointer to view table entry */ -void in_destination(struct vt_entry *v) { +void AgiEngine::in_destination(struct vt_entry *v) { if (v->motion == MOTION_MOVE_OBJ) { v->step_size = v->parm3; setflag(v->parm4, true); @@ -210,7 +210,7 @@ void in_destination(struct vt_entry *v) { * after setting the motion mode to MOTION_MOVE_OBJ. * @param v Pointer to view table entry */ -void move_obj(struct vt_entry *v) { +void AgiEngine::move_obj(struct vt_entry *v) { motion_moveobj(v); } @@ -224,7 +224,7 @@ void move_obj(struct vt_entry *v) { * @param y y coordinate of the object * @param s step size */ -int get_direction(int x0, int y0, int x, int y, int s) { +int AgiEngine::get_direction(int x0, int y0, int x, int y, int s) { int dir_table[9] = { 8, 1, 2, 7, 0, 3, 6, 5, 4 }; return dir_table[check_step(x - x0, s) + 3 * check_step(y - y0, s)]; } diff --git a/engines/agi/objects.cpp b/engines/agi/objects.cpp index 9c908c29e2..759d8b0713 100644 --- a/engines/agi/objects.cpp +++ b/engines/agi/objects.cpp @@ -28,18 +28,14 @@ namespace Agi { -extern int decode_objects(uint8 *mem, uint32 flen); - -static struct agi_object *objects; /* objects in the game */ - -int alloc_objects(int n) { - if ((objects = (agi_object *) calloc(n, sizeof(struct agi_object))) == NULL) +int AgiEngine::alloc_objects(int n) { + if ((objects = (agi_object *)calloc(n, sizeof(struct agi_object))) == NULL) return err_NotEnoughMemory; return err_OK; } -int decode_objects(uint8 *mem, uint32 flen) { +int AgiEngine::decode_objects(uint8 *mem, uint32 flen) { unsigned int i, so, padsize; padsize = game.game_flags & ID_AMIGA ? 4 : 3; @@ -92,7 +88,7 @@ int decode_objects(uint8 *mem, uint32 flen) { } -int load_objects(const char *fname) { +int AgiEngine::load_objects(const char *fname) { Common::File fp; uint32 flen; uint8 *mem; @@ -110,7 +106,7 @@ int load_objects(const char *fname) { flen = fp.pos(); fp.seek(0, SEEK_SET); - if ((mem = (uint8 *) calloc(1, flen + 32)) == NULL) { + if ((mem = (uint8 *)calloc(1, flen + 32)) == NULL) { fp.close(); return err_NotEnoughMemory; } @@ -123,7 +119,7 @@ int load_objects(const char *fname) { return err_OK; } -void unload_objects() { +void AgiEngine::unload_objects() { unsigned int i; if (objects != NULL) { @@ -136,7 +132,7 @@ void unload_objects() { } } -void object_set_location(unsigned int n, int i) { +void AgiEngine::object_set_location(unsigned int n, int i) { if (n >= game.num_objects) { report("Error: Can't access object %d.\n", n); return; @@ -144,7 +140,7 @@ void object_set_location(unsigned int n, int i) { objects[n].location = i; } -int object_get_location(unsigned int n) { +int AgiEngine::object_get_location(unsigned int n) { if (n >= game.num_objects) { report("Error: Can't access object %d.\n", n); return 0; @@ -152,7 +148,7 @@ int object_get_location(unsigned int n) { return objects[n].location; } -const char *object_name(unsigned int n) { +const char *AgiEngine::object_name(unsigned int n) { if (n >= game.num_objects) { report("Error: Can't access object %d.\n", n); return ""; diff --git a/engines/agi/op_cmd.cpp b/engines/agi/op_cmd.cpp index caa97950dd..eaf6f8c889 100644 --- a/engines/agi/op_cmd.cpp +++ b/engines/agi/op_cmd.cpp @@ -43,10 +43,18 @@ namespace Agi { #define p5 (p[5]) #define p6 (p[6]) +#define game g_agi->game +#define g_sprites g_agi->_sprites +#define g_sound g_agi->_sound +#define g_text g_agi->_text +#define g_gfx g_agi->_gfx +#define g_picture g_agi->_picture + #define ip cur_logic->cIP #define vt game.view_table[p0] static struct agi_logic *cur_logic; +static AgiEngine *g_agi; int timer_hack; /* Workaround for timer loop in MH1 */ @@ -104,7 +112,7 @@ cmd(div_v) { } cmd(random) { - _v[p2] = rnd->getRandomNumber(p1 - p0) + p0; + _v[p2] = g_agi->_rnd->getRandomNumber(p1 - p0) + p0; } cmd(lindirectn) { @@ -120,59 +128,59 @@ cmd(rindirect) { } cmd(set) { - setflag(*p, true); + g_agi->setflag(*p, true); } cmd(reset) { - setflag(*p, false); + g_agi->setflag(*p, false); } cmd(toggle) { - setflag(*p, !getflag(*p)); + g_agi->setflag(*p, !g_agi->getflag(*p)); } cmd(set_v) { - setflag(_v[p0], true); + g_agi->setflag(_v[p0], true); } cmd(reset_v) { - setflag(_v[p0], false); + g_agi->setflag(_v[p0], false); } cmd(toggle_v) { - setflag(_v[p0], !getflag(_v[p0])); + g_agi->setflag(_v[p0], !g_agi->getflag(_v[p0])); } cmd(new_room) { - new_room(p0); + g_agi->new_room(p0); } cmd(new_room_f) { - new_room(_v[p0]); + g_agi->new_room(_v[p0]); } cmd(load_view) { - agi_load_resource(rVIEW, p0); + g_agi->agiLoadResource(rVIEW, p0); } cmd(load_logic) { - agi_load_resource(rLOGIC, p0); + g_agi->agiLoadResource(rLOGIC, p0); } cmd(load_sound) { - agi_load_resource(rSOUND, p0); + g_agi->agiLoadResource(rSOUND, p0); } cmd(load_view_f) { - agi_load_resource(rVIEW, _v[p0]); + g_agi->agiLoadResource(rVIEW, _v[p0]); } cmd(load_logic_f) { - agi_load_resource(rLOGIC, _v[p0]); + g_agi->agiLoadResource(rLOGIC, _v[p0]); } cmd(discard_view) { - agi_unload_resource(rVIEW, p0); + g_agi->agiUnloadResource(rVIEW, p0); } cmd(object_on_anything) { @@ -246,11 +254,11 @@ cmd(set_upper_left) { /* do nothing (AGI 2.917) */ } cmd(start_update) { - start_update(&vt); + g_agi->start_update(&vt); } cmd(stop_update) { - stop_update(&vt); + g_agi->stop_update(&vt); } cmd(current_view) { @@ -271,30 +279,30 @@ cmd(last_cel) { } cmd(set_cel) { - set_cel(&vt, p1); + g_agi->set_cel(&vt, p1); vt.flags &= ~DONTUPDATE; } cmd(set_cel_f) { - set_cel(&vt, _v[p1]); + g_agi->set_cel(&vt, _v[p1]); vt.flags &= ~DONTUPDATE; } cmd(set_view) { debugC(4, kDebugLevelScripts, "o%d, %d", p0, p1); - set_view(&vt, p1); + g_agi->set_view(&vt, p1); } cmd(set_view_f) { - set_view(&vt, _v[p1]); + g_agi->set_view(&vt, _v[p1]); } cmd(set_loop) { - set_loop(&vt, p1); + g_agi->set_loop(&vt, p1); } cmd(set_loop_f) { - set_loop(&vt, _v[p1]); + g_agi->set_loop(&vt, _v[p1]); } cmd(number_of_loops) { @@ -348,27 +356,27 @@ cmd(get_dir) { } cmd(get_room_f) { - _v[p1] = object_get_location(_v[p0]); + _v[p1] = g_agi->object_get_location(_v[p0]); } cmd(put) { - object_set_location(p0, _v[p1]); + g_agi->object_set_location(p0, _v[p1]); } cmd(put_f) { - object_set_location(_v[p0], _v[p1]); + g_agi->object_set_location(_v[p0], _v[p1]); } cmd(drop) { - object_set_location(p0, 0); + g_agi->object_set_location(p0, 0); } cmd(get) { - object_set_location(p0, EGO_OWNED); + g_agi->object_set_location(p0, EGO_OWNED); } cmd(get_f) { - object_set_location(_v[p0], EGO_OWNED); + g_agi->object_set_location(_v[p0], EGO_OWNED); } cmd(word_to_string) { @@ -386,49 +394,49 @@ cmd(close_dialogue) { } cmd(close_window) { - _text->close_window(); + g_agi->close_window(); } cmd(status_line_on) { game.status_line = true; - _text->write_status(); + g_agi->write_status(); } cmd(status_line_off) { game.status_line = false; - _text->write_status(); + g_agi->write_status(); } cmd(show_obj) { - _sprites->show_obj(p0); + g_sprites->show_obj(p0); } cmd(show_obj_v) { - _sprites->show_obj(_v[p0]); + g_sprites->show_obj(_v[p0]); } cmd(sound) { - start_sound(p0, p1); + g_sound->start_sound(p0, p1); } cmd(stop_sound) { - stop_sound(); + g_sound->stop_sound(); } cmd(menu_input) { - new_input_mode(INPUT_MENU); + g_agi->new_input_mode(INPUT_MENU); } cmd(enable_item) { - menu->set_item(p0, true); + g_agi->menu->set_item(p0, true); } cmd(disable_item) { - menu->set_item(p0, false); + g_agi->menu->set_item(p0, false); } cmd(submit_menu) { - menu->submit(); + g_agi->menu->submit(); } cmd(set_scan_start) { @@ -440,12 +448,12 @@ cmd(reset_scan_start) { } cmd(save_game) { - game.simple_save ? savegame_simple() : savegame_dialog(); + game.simple_save ? g_agi->_saveGameMgr->savegame_simple() : g_agi->_saveGameMgr->savegame_dialog(); } cmd(load_game) { assert(1); - game.simple_save ? loadgame_simple() : loadgame_dialog(); + game.simple_save ? g_agi->_saveGameMgr->loadgame_simple() : g_agi->_saveGameMgr->loadgame_dialog(); } cmd(init_disk) { /* do nothing */ @@ -461,7 +469,7 @@ cmd(trace_info) { /* do nothing */ } cmd(show_mem) { - _text->message_box("Enough memory"); + g_agi->message_box("Enough memory"); } cmd(init_joy) { /* do nothing */ ; @@ -530,10 +538,10 @@ cmd(adj_ego_move_to_x_y) { cmd(parse) { _v[V_word_not_found] = 0; - setflag(F_entered_cli, false); - setflag(F_said_accepted_input, false); + g_agi->setflag(F_entered_cli, false); + g_agi->setflag(F_said_accepted_input, false); - dictionary_words(_text->agi_sprintf(game.strings[p0])); + g_agi->dictionary_words(g_agi->agi_sprintf(game.strings[p0])); } cmd(call) { @@ -546,7 +554,7 @@ cmd(call) { old_cIP = cur_logic->cIP; old_lognum = game.lognum; - run_logic(p0); + g_agi->run_logic(p0); game.lognum = old_lognum; cur_logic = &game.logics[game.lognum]; @@ -559,26 +567,26 @@ cmd(call_f) { cmd(draw_pic) { debugC(6, kDebugLevelScripts, "=== draw pic %d ===", _v[p0]); - _sprites->erase_both(); - decode_picture(_v[p0], true); - _sprites->blit_both(); + g_sprites->erase_both(); + g_picture->decode_picture(_v[p0], true); + g_sprites->blit_both(); game.picture_shown = 0; debugC(6, kDebugLevelScripts, "--- end of draw pic %d ---", _v[p0]); } cmd(show_pic) { debugC(6, kDebugLevelScripts, "=== show pic ==="); - setflag(F_output_mode, false); + g_agi->setflag(F_output_mode, false); cmd_close_window(NULL); - show_pic(); + g_picture->show_pic(); game.picture_shown = 1; debugC(6, kDebugLevelScripts, "--- end of show pic ---"); } cmd(load_pic) { - _sprites->erase_both(); - agi_load_resource(rPICTURE, _v[p0]); - _sprites->blit_both(); + g_sprites->erase_both(); + g_agi->agiLoadResource(rPICTURE, _v[p0]); + g_sprites->blit_both(); } cmd(discard_pic) { @@ -588,23 +596,23 @@ cmd(discard_pic) { cmd(overlay_pic) { debugC(6, kDebugLevelScripts, "--- overlay pic ---"); - _sprites->erase_both(); - decode_picture(_v[p0], false); - _sprites->blit_both(); + g_sprites->erase_both(); + g_picture->decode_picture(_v[p0], false); + g_sprites->blit_both(); game.picture_shown = 0; - _sprites->commit_both(); + g_sprites->commit_both(); } cmd(show_pri_screen) { - debug_.priority = 1; - _sprites->erase_both(); - show_pic(); - _sprites->blit_both(); - wait_key(); - debug_.priority = 0; - _sprites->erase_both(); - show_pic(); - _sprites->blit_both(); + g_agi->_debug.priority = 1; + g_sprites->erase_both(); + g_picture->show_pic(); + g_sprites->blit_both(); + g_agi->wait_key(); + g_agi->_debug.priority = 0; + g_sprites->erase_both(); + g_picture->show_pic(); + g_sprites->blit_both(); } cmd(animate_obj) { @@ -634,24 +642,24 @@ cmd(draw) { debugC(4, kDebugLevelScripts, "draw entry %d", vt.entry); vt.flags |= UPDATE; - if (agi_get_release() >= 0x3000) { - set_loop(&vt, vt.current_loop); - set_cel(&vt, vt.current_cel); + if (g_agi->agiGetRelease() >= 0x3000) { + g_agi->set_loop(&vt, vt.current_loop); + g_agi->set_cel(&vt, vt.current_cel); } - fix_position(p0); + g_agi->fix_position(p0); vt.x_pos2 = vt.x_pos; vt.y_pos2 = vt.y_pos; vt.cel_data_2 = vt.cel_data; - _sprites->erase_upd_sprites(); + g_sprites->erase_upd_sprites(); vt.flags |= DRAWN; - if (agi_get_release() <= 0x2440) /* See bug #546562 */ + if (g_agi->agiGetRelease() <= 0x2440) /* See bug #546562 */ vt.flags |= ANIMATED; - _sprites->blit_upd_sprites(); + g_sprites->blit_upd_sprites(); vt.flags &= ~DONTUPDATE; - _sprites->commit_block(vt.x_pos, vt.y_pos - vt.y_size + 1, vt.x_pos + vt.x_size - 1, vt.y_pos); + g_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); } @@ -660,17 +668,17 @@ cmd(erase) { if (~vt.flags & DRAWN) return; - _sprites->erase_upd_sprites(); + g_sprites->erase_upd_sprites(); if (vt.flags & UPDATE) { vt.flags &= ~DRAWN; } else { - _sprites->erase_nonupd_sprites(); + g_sprites->erase_nonupd_sprites(); vt.flags &= ~DRAWN; - _sprites->blit_nonupd_sprites(); + g_sprites->blit_nonupd_sprites(); } - _sprites->blit_upd_sprites(); + g_sprites->blit_upd_sprites(); - _sprites->commit_block(vt.x_pos, vt.y_pos - vt.y_size + 1, vt.x_pos + vt.x_size - 1, vt.y_pos); + g_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) { @@ -704,35 +712,35 @@ cmd(reposition) { else vt.y_pos += dy; - fix_position(p0); + g_agi->fix_position(p0); } cmd(reposition_to) { vt.x_pos = p1; vt.y_pos = p2; vt.flags |= UPDATE_POS; - fix_position(p0); + g_agi->fix_position(p0); } cmd(reposition_to_f) { vt.x_pos = _v[p1]; vt.y_pos = _v[p2]; vt.flags |= UPDATE_POS; - fix_position(p0); + g_agi->fix_position(p0); } cmd(add_to_pic) { - _sprites->add_to_pic(p0, p1, p2, p3, p4, p5, p6); + g_sprites->add_to_pic(p0, p1, p2, p3, p4, p5, p6); } cmd(add_to_pic_f) { - _sprites->add_to_pic(_v[p0], _v[p1], _v[p2], _v[p3], _v[p4], _v[p5], _v[p6]); + g_sprites->add_to_pic(_v[p0], _v[p1], _v[p2], _v[p3], _v[p4], _v[p5], _v[p6]); } cmd(force_update) { - _sprites->erase_both(); - _sprites->blit_both(); - _sprites->commit_both(); + g_sprites->erase_both(); + g_sprites->blit_both(); + g_sprites->commit_both(); } cmd(reverse_loop) { @@ -740,7 +748,7 @@ cmd(reverse_loop) { vt.cycle = CYCLE_REV_LOOP; vt.flags |= (DONTUPDATE | UPDATE | CYCLING); vt.parm1 = p1; - setflag(p1, false); + g_agi->setflag(p1, false); } cmd(end_of_loop) { @@ -748,7 +756,7 @@ cmd(end_of_loop) { vt.cycle = CYCLE_END_OF_LOOP; vt.flags |= (DONTUPDATE | UPDATE | CYCLING); vt.parm1 = p1; - setflag(p1, false); + g_agi->setflag(p1, false); } cmd(block) { @@ -799,7 +807,7 @@ cmd(follow_ego) { vt.parm1 = p1 > vt.step_size ? p1 : vt.step_size; vt.parm2 = p2; vt.parm3 = 0xff; - setflag(p2, false); + g_agi->setflag(p2, false); vt.flags |= UPDATE; } @@ -815,15 +823,15 @@ cmd(move_obj) { if (p3 != 0) vt.step_size = p3; - setflag(p4, false); + g_agi->setflag(p4, false); vt.flags |= UPDATE; if (p0 == 0) game.player_control = false; /* AGI 2.272 (ddp, xmas) doesn't call move_obj! */ - if (agi_get_release() > 0x2272) - move_obj(&vt); + if (g_agi->agiGetRelease() > 0x2272) + g_agi->move_obj(&vt); } cmd(move_obj_f) { @@ -836,15 +844,15 @@ cmd(move_obj_f) { if (_v[p3] != 0) vt.step_size = _v[p3]; - setflag(p4, false); + g_agi->setflag(p4, false); vt.flags |= UPDATE; if (p0 == 0) game.player_control = false; /* AGI 2.272 (ddp, xmas) doesn't call move_obj! */ - if (agi_get_release() > 0x2272) - move_obj(&vt); + if (g_agi->agiGetRelease() > 0x2272) + g_agi->move_obj(&vt); } cmd(wander) { @@ -868,20 +876,20 @@ cmd(pause) { const char *b[] = { "Continue", NULL }; game.clock_enabled = false; - _text->selection_box(" Game is paused. \n\n\n", b); + g_agi->selection_box(" Game is paused. \n\n\n", b); game.clock_enabled = tmp; } cmd(set_menu) { debugC(4, kDebugLevelScripts, "text %02x of %02x", p0, cur_logic->num_texts); if (cur_logic->texts != NULL && p0 < cur_logic->num_texts) - menu->add(cur_logic->texts[p0 - 1]); + g_agi->menu->add(cur_logic->texts[p0 - 1]); } cmd(set_menu_item) { debugC(4, kDebugLevelScripts, "text %02x of %02x", p0, cur_logic->num_texts); if (cur_logic->texts != NULL && p0 <= cur_logic->num_texts) - menu->add_item(cur_logic->texts[p0 - 1], p1); + g_agi->menu->add_item(cur_logic->texts[p0 - 1], p1); } cmd(version) { @@ -899,7 +907,7 @@ cmd(version) { int ver, maj, min; char msg[256]; - ver = agi_get_release(); + ver = g_agi->agiGetRelease(); maj = (ver >> 12) & 0xf; min = ver & 0xfff; @@ -908,7 +916,7 @@ cmd(version) { strncpy(q + 1 + ((r - q > 0 ? r - q : 1) / 4), ver_msg, strlen(ver_msg)); sprintf(msg, q, maj, min); - _text->message_box(msg); + g_agi->message_box(msg); } cmd(configure_screen) { @@ -926,17 +934,17 @@ cmd(text_screen) { */ if (game.color_bg) game.color_bg |= 0x08; - clear_screen(game.color_bg); + g_gfx->clearScreen(game.color_bg); } cmd(graphics) { debugC(4, kDebugLevelScripts, "switching to graphics mode"); if (!game.gfx_mode) { game.gfx_mode = true; - clear_screen(0); - show_pic(); - _text->write_status(); - _text->write_prompt(); + g_gfx->clearScreen(0); + g_picture->show_pic(); + g_agi->write_status(); + g_agi->write_prompt(); } } @@ -953,18 +961,18 @@ cmd(set_text_attribute) { } cmd(status) { - inventory(); + g_agi->inventory(); } cmd(quit) { const char *buttons[] = { "Quit", "Continue", NULL }; - stop_sound(); + g_sound->stop_sound(); if (p0) { game.quit_prog_now = true; } else { - if (_text->selection_box - (" Quit the game, or continue? \n\n\n", buttons) == 0) { + if (g_agi->selection_box + (" Quit the game, or continue? \n\n\n", buttons) == 0) { game.quit_prog_now = true; } } @@ -974,14 +982,14 @@ cmd(restart_game) { const char *buttons[] = { "Restart", "Continue", NULL }; int sel; - stop_sound(); - sel = getflag(F_auto_restart) ? 1 : - _text->selection_box(" Restart game, or continue? \n\n\n", buttons); + g_sound->stop_sound(); + sel = g_agi->getflag(F_auto_restart) ? 1 : + g_agi->selection_box(" Restart game, or continue? \n\n\n", buttons); if (sel == 0) { game.quit_prog_now = 0xff; - setflag(F_restart_game, true); - menu->enable_all(); + g_agi->setflag(F_restart_game, true); + g_agi->menu->enable_all(); } } @@ -1006,13 +1014,13 @@ cmd(distance) { cmd(accept_input) { debugC(4, kDebugLevelScripts | kDebugLevelInput, "input normal"); - new_input_mode(INPUT_NORMAL); + g_agi->new_input_mode(INPUT_NORMAL); game.input_enabled = true; } cmd(prevent_input) { debugC(4, kDebugLevelScripts | kDebugLevelInput, "no input"); - new_input_mode(INPUT_NONE); + g_agi->new_input_mode(INPUT_NONE); game.input_enabled = false; } @@ -1033,43 +1041,43 @@ cmd(get_string) { if (col > 39) col = 39; - new_input_mode(INPUT_GETSTRING); + g_agi->new_input_mode(INPUT_GETSTRING); if (cur_logic->texts != NULL && cur_logic->num_texts >= tex) { int len = strlen(cur_logic->texts[tex]); - _text->print_text(cur_logic->texts[tex], 0, col, row, len, game.color_fg, game.color_bg); - get_string(col + len - 1, row, p4, p0); + g_agi->print_text(cur_logic->texts[tex], 0, col, row, len, game.color_fg, game.color_bg); + g_agi->get_string(col + len - 1, row, p4, p0); /* SGEO: display input char */ - print_character((col + len), row, game.cursor_char, game.color_fg, game.color_bg); + g_gfx->printCharacter((col + len), row, game.cursor_char, game.color_fg, game.color_bg); } do { - main_cycle(); + g_agi->main_cycle(); } while (game.input_mode == INPUT_GETSTRING); } cmd(get_num) { debugC(4, kDebugLevelScripts, "%d %d", p0, p1); - new_input_mode(INPUT_GETSTRING); + g_agi->new_input_mode(INPUT_GETSTRING); if (cur_logic->texts != NULL && cur_logic->num_texts >= (p0 - 1)) { int len = strlen(cur_logic->texts[p0 - 1]); - _text->print_text(cur_logic->texts[p0 - 1], 0, 0, 22, len, game.color_fg, game.color_bg); - get_string(len - 1, 22, 3, MAX_STRINGS); + g_agi->print_text(cur_logic->texts[p0 - 1], 0, 0, 22, len, game.color_fg, game.color_bg); + g_agi->get_string(len - 1, 22, 3, MAX_STRINGS); /* CM: display input char */ - print_character((p3 + len), 22, game.cursor_char, game.color_fg, game.color_bg); + g_gfx->printCharacter((p3 + len), 22, game.cursor_char, game.color_fg, game.color_bg); } do { - main_cycle(); + g_agi->main_cycle(); } while (game.input_mode == INPUT_GETSTRING); _v[p1] = atoi(game.strings[MAX_STRINGS]); debugC(4, kDebugLevelScripts, "[%s] -> %d", game.strings[MAX_STRINGS], _v[p1]); - _text->clear_lines(22, 22, game.color_bg); - _text->flush_lines(22, 22); + g_agi->clear_lines(22, 22, game.color_bg); + g_agi->flush_lines(22, 22); } cmd(set_cursor_char) { @@ -1102,12 +1110,12 @@ cmd(set_string) { } cmd(display) { - _text->print_text(cur_logic->texts[p2 - 1], p1, 0, p0, 40, game.color_fg, game.color_bg); + g_agi->print_text(cur_logic->texts[p2 - 1], p1, 0, p0, 40, game.color_fg, game.color_bg); } cmd(display_f) { debugC(4, kDebugLevelScripts, "p0 = %d", p0); - _text->print_text(cur_logic->texts[_v[p2] - 1], _v[p1], 0, _v[p0], 40, game.color_fg, game.color_bg); + g_agi->print_text(cur_logic->texts[_v[p2] - 1], _v[p1], 0, _v[p0], 40, game.color_fg, game.color_bg); } cmd(clear_text_rect) { @@ -1130,8 +1138,8 @@ cmd(clear_text_rect) { if (y2 > GFX_HEIGHT) y2 = GFX_HEIGHT - 1; - draw_rectangle(x1, y1, x2, y2, c); - flush_block(x1, y1, x2, y2); + g_gfx->drawRectangle(x1, y1, x2, y2, c); + g_gfx->flushBlock(x1, y1, x2, y2); } cmd(toggle_monitor) { @@ -1150,36 +1158,36 @@ cmd(clear_lines) { /* Residence 44 calls clear.lines(24,0,0), see bug #558423 */ l = p1 ? p1 : p0; - _text->clear_lines(p0, l, p2); - _text->flush_lines(p0, l); + g_agi->clear_lines(p0, l, p2); + g_agi->flush_lines(p0, l); } cmd(print) { int n = p0 < 1 ? 1 : p0; - _text->print(cur_logic->texts[n - 1], 0, 0, 0); + g_agi->print(cur_logic->texts[n - 1], 0, 0, 0); } cmd(print_f) { int n = _v[p0] < 1 ? 1 : _v[p0]; - _text->print(cur_logic->texts[n - 1], 0, 0, 0); + g_agi->print(cur_logic->texts[n - 1], 0, 0, 0); } cmd(print_at) { int n = p0 < 1 ? 1 : p0; debugC(4, kDebugLevelScripts, "%d %d %d %d", p0, p1, p2, p3); - _text->print(cur_logic->texts[n - 1], p1, p2, p3); + g_agi->print(cur_logic->texts[n - 1], p1, p2, p3); } cmd(print_at_v) { int n = _v[p0] < 1 ? 1 : _v[p0]; - _text->print(cur_logic->texts[n - 1], p1, p2, p3); + g_agi->print(cur_logic->texts[n - 1], p1, p2, p3); } cmd(push_script) { - if (opt.agimouse) { - game.vars[27] = mouse.button; - game.vars[28] = mouse.x / 2; - game.vars[29] = mouse.y; + if (g_agi->opt.agimouse) { + game.vars[27] = g_mouse.button; + game.vars[28] = g_mouse.x / 2; + game.vars[29] = g_mouse.y; } else report("push.script\n"); } @@ -1201,8 +1209,8 @@ cmd(set_pri_base) { } cmd(mouse_posn) { - _v[p0] = WIN_TO_PIC_X(mouse.x); - _v[p1] = WIN_TO_PIC_Y(mouse.y); + _v[p0] = WIN_TO_PIC_X(g_mouse.x); + _v[p1] = WIN_TO_PIC_Y(g_mouse.y); } cmd(shake_screen) { @@ -1211,19 +1219,19 @@ cmd(shake_screen) { /* AGI Mouse 1.1 uses shake.screen values between 100 and 109 to * set the palette. */ - if (opt.agimouse && p0 >= 100 && p0 < 110) { + if (g_agi->opt.agimouse && p0 >= 100 && p0 < 110) { report("not implemented: AGI Mouse palettes\n"); return; } else - shake_start(); + g_gfx->shakeStart(); - _sprites->commit_both(); /* Fixes SQ1 demo */ + g_sprites->commit_both(); /* Fixes SQ1 demo */ for (i = 4 * p0; i; i--) { - shake_screen(i & 1); - flush_block(0, 0, GFX_WIDTH - 1, GFX_HEIGHT - 1); - main_cycle(); + g_gfx->shakeScreen(i & 1); + g_gfx->flushBlock(0, 0, GFX_WIDTH - 1, GFX_HEIGHT - 1); + g_agi->main_cycle(); } - shake_end(); + g_gfx->shakeEnd(); } static void (*agi_command[183]) (uint8 *) = { @@ -1418,16 +1426,17 @@ static void (*agi_command[183]) (uint8 *) = { * Execute a logic script * @param n Number of the logic resource to execute */ -int run_logic(int n) { +int AgiEngine::run_logic(int n) { uint8 op = 0; uint8 p[CMD_BSIZE] = { 0 }; uint8 *code = NULL; + g_agi = this; int num = 0; /* If logic not loaded, load it */ if (~game.dir_logic[n].flags & RES_LOADED) { debugC(4, kDebugLevelScripts, "logic %d not loaded!", n); - agi_load_resource(rLOGIC, n); + agiLoadResource(rLOGIC, n); } game.lognum = n; @@ -1438,17 +1447,17 @@ int run_logic(int n) { timer_hack = 0; while (ip < game.logics[n].size && !game.quit_prog_now) { - if (debug_.enabled) { - if (debug_.steps > 0) { - if (debug_.logic0 || n) { + if (g_agi->_debug.enabled) { + if (g_agi->_debug.steps > 0) { + if (g_agi->_debug.logic0 || n) { debug_console(n, lCOMMAND_MODE, NULL); - debug_.steps--; + g_agi->_debug.steps--; } } else { _sprites->blit_both(); do { main_cycle(); - } while (!debug_.steps && debug_.enabled); + } while (!g_agi->_debug.steps && g_agi->_debug.enabled); _sprites->erase_both(); } } @@ -1464,8 +1473,8 @@ int run_logic(int n) { * but AGI engine can't do that :( */ if (timer_hack > 20) { - poll_timer(); - update_timer(); + g_gfx->pollTimer(); + g_agi->update_timer(); timer_hack = 0; } break; @@ -1488,8 +1497,10 @@ int run_logic(int n) { return 0; /* after executing new.room() */ } -void execute_agi_command(uint8 op, uint8 *p) { +void AgiEngine::execute_agi_command(uint8 op, uint8 *p) { debugC(2, kDebugLevelScripts, "%s(%d %d %d)", logic_names_cmd[op].name, p[0], p[1], p[2]); + g_agi = this; + agi_command[op] (p); } diff --git a/engines/agi/op_dbg.cpp b/engines/agi/op_dbg.cpp index 79d2d2403d..d62c12f5f6 100644 --- a/engines/agi/op_dbg.cpp +++ b/engines/agi/op_dbg.cpp @@ -29,6 +29,9 @@ namespace Agi { +static AgiEngine *g_agi; +#define game g_agi->game + #define ip (game.logics[lognum].cIP) #define code (game.logics[lognum].data) @@ -266,8 +269,9 @@ struct agi_logicnames logic_names_cmd[] = { _L(NULL, 0, 0x00) }; -void debug_console(int lognum, int mode, const char *str) { - struct agi_logicnames *x; +void AgiEngine::debug_console(int lognum, int mode, const char *str) { + g_agi = this; + agi_logicnames *x; uint8 a, c, z; if (str) { @@ -284,7 +288,7 @@ void debug_console(int lognum, int mode, const char *str) { case 0xFF: x = logic_names_if; - if (debug_.opcodes) { + if (g_agi->_debug.opcodes) { report("%02X %02X %02X %02X %02X %02X %02X %02X %02X\n" " ", (uint8) * (code + (0 + ip)) & 0xFF, @@ -304,7 +308,7 @@ void debug_console(int lognum, int mode, const char *str) { a = (unsigned char)(x + *(code + ip))->num_args; c = (unsigned char)(x + *(code + ip))->arg_mask; - if (debug_.opcodes) { + if (g_agi->_debug.opcodes) { report("%02X %02X %02X %02X %02X %02X %02X %02X %02X\n" " ", (uint8) * (code + (0 + ip)) & 0xFF, diff --git a/engines/agi/op_test.cpp b/engines/agi/op_test.cpp index 8ead659263..ecd3eb7c2f 100644 --- a/engines/agi/op_test.cpp +++ b/engines/agi/op_test.cpp @@ -39,15 +39,18 @@ static uint8 test_controller(uint8); static uint8 test_keypressed(void); static uint8 test_compare_strings(uint8, uint8); +static AgiEngine *g_agi; +#define game g_agi->game + #define ip (game.logics[lognum].cIP) #define code (game.logics[lognum].data) -#define test_equal(v1,v2) (getvar(v1) == (v2)) -#define test_less(v1,v2) (getvar(v1) < (v2)) -#define test_greater(v1,v2) (getvar(v1) > (v2)) -#define test_isset(flag) (getflag (flag)) -#define test_has(obj) (object_get_location (obj) == EGO_OWNED) -#define test_obj_in_room(obj,v) (object_get_location (obj) == getvar (v)) +#define test_equal(v1, v2) (g_agi->getvar(v1) == (v2)) +#define test_less(v1, v2) (g_agi->getvar(v1) < (v2)) +#define test_greater(v1, v2) (g_agi->getvar(v1) > (v2)) +#define test_isset(flag) (g_agi->getflag(flag)) +#define test_has(obj) (g_agi->object_get_location(obj) == EGO_OWNED) +#define test_obj_in_room(obj, v) (g_agi->object_get_location(obj) == g_agi->getvar(v)) extern int timer_hack; /* For the timer loop in MH1 logic 153 */ @@ -111,7 +114,7 @@ static uint8 test_keypressed() { if (!x) { int mode = game.input_mode; game.input_mode = INPUT_NONE; - main_cycle(); + g_agi->main_cycle(); game.input_mode = mode; } @@ -164,7 +167,7 @@ static uint8 test_said(uint8 nwords, uint8 *cc) { int c, n = game.num_ego_words; int z = 0; - if (getflag(F_said_accepted_input) || !getflag(F_entered_cli)) + if (g_agi->getflag(F_said_accepted_input) || !g_agi->getflag(F_entered_cli)) return false; /* FR: @@ -212,12 +215,13 @@ static uint8 test_said(uint8 nwords, uint8 *cc) { if (nwords != 0 && READ_LE_UINT16(cc) != 9999) return false; - setflag(F_said_accepted_input, true); + g_agi->setflag(F_said_accepted_input, true); return true; } -int test_if_code(int lognum) { +int AgiEngine::test_if_code(int lognum) { + g_agi = this; int ec = true; int retval = true; uint8 op = 0; @@ -227,7 +231,7 @@ int test_if_code(int lognum) { uint8 p[16] = { 0 }; while (retval && !game.quit_prog_now) { - if (debug_.enabled && (debug_.logic0 || lognum)) + if (g_agi->_debug.enabled && (g_agi->_debug.logic0 || lognum)) debug_console(lognum, lTEST_MODE, NULL); last_ip = ip; @@ -406,7 +410,7 @@ int test_if_code(int lognum) { ip += READ_LE_UINT16(code + ip) + 2; } - if (debug_.enabled && (debug_.logic0 || lognum)) + if (g_agi->_debug.enabled && (g_agi->_debug.logic0 || lognum)) debug_console(lognum, 0xFF, retval ? "=true" : "=false"); return retval; diff --git a/engines/agi/opcodes.h b/engines/agi/opcodes.h index 4a8951d072..85d5014c83 100644 --- a/engines/agi/opcodes.h +++ b/engines/agi/opcodes.h @@ -39,15 +39,6 @@ extern struct agi_logicnames logic_names_test[]; extern struct agi_logicnames logic_names_cmd[]; extern struct agi_logicnames logic_names_if[]; -void debug_console(int, int, const char *); -int test_if_code(int); -void new_room(int); -void execute_agi_command(uint8, uint8 *); - -#ifdef PATCH_LOGIC -void patch_logic(int); -#endif - } // End of namespace Agi #endif /* AGI_OPCODES_H */ diff --git a/engines/agi/patches.cpp b/engines/agi/patches.cpp index b41dc24b0d..806ee7c491 100644 --- a/engines/agi/patches.cpp +++ b/engines/agi/patches.cpp @@ -104,7 +104,7 @@ static const uint8 mh1data_fix[] = { 0x0C, 0x05, 0x16, 0x5A, 0x12, 0x99 }; -void patch_logic(int n) { +void AgiEngine::patch_logic(int n) { switch (n) { #if 0 /* ALT-X in the questions takes care of that */ diff --git a/engines/agi/picture.cpp b/engines/agi/picture.cpp index 00bde8ac87..526fde2c5d 100644 --- a/engines/agi/picture.cpp +++ b/engines/agi/picture.cpp @@ -43,7 +43,7 @@ static uint8 scr_on; static uint8 scr_colour; static uint8 pri_colour; -static const uint8 circles[][15] = { /* agi circle bitmaps */ +static uint8 circles[][15] = { /* agi circle bitmaps */ {0x80}, {0xfc}, {0x5f, 0xf4}, @@ -54,14 +54,14 @@ static const uint8 circles[][15] = { /* agi circle bitmaps */ {0x18, 0x3c, 0x7e, 0x7e, 0x7e, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7e, 0x7e, 0x7e, 0x3c, 0x18} }; -static const uint8 splatter_map[32] = { /* splatter brush bitmaps */ +static uint8 splatter_map[32] = { /* splatter brush bitmaps */ 0x20, 0x94, 0x02, 0x24, 0x90, 0x82, 0xa4, 0xa2, 0x82, 0x09, 0x0a, 0x22, 0x12, 0x10, 0x42, 0x14, 0x91, 0x4a, 0x91, 0x11, 0x08, 0x12, 0x25, 0x10, 0x22, 0xa8, 0x14, 0x24, 0x00, 0x50, 0x24, 0x04 }; -static const uint8 splatter_start[128] = { /* starting bit position */ +static uint8 splatter_start[128] = { /* starting bit position */ 0x00, 0x18, 0x30, 0xc4, 0xdc, 0x65, 0xeb, 0x48, 0x60, 0xbd, 0x89, 0x05, 0x0a, 0xf4, 0x7d, 0x7d, 0x85, 0xb0, 0x8e, 0x95, 0x1f, 0x22, 0x0d, 0xdf, @@ -79,16 +79,14 @@ static const uint8 splatter_start[128] = { /* starting bit position */ 0x06, 0x6f, 0xc6, 0x4a, 0xa4, 0x75, 0x97, 0xe1 }; -static void fix_pixel_bothsides(int x, int y); - -static void put_virt_pixel(int x, int y, int res) { +void PictureMgr::put_virt_pixel(int x, int y, int res) { uint8 *p; int width = _WIDTH * res; if (x < 0 || y < 0 || x >= width || y >= _HEIGHT) return; - p = res > 1 ? &game.hires[y * width + x] : &game.sbuf[y * width + x]; + p = res > 1 ? &_vm->game.hires[y * width + x] : &_vm->game.sbuf[y * width + x]; if (pri_on) *p = (pri_colour << 4) | (*p & 0x0f); @@ -128,7 +126,7 @@ static INLINE uint16 _POP() { * @param y2 y coordinate of end point * @param res horizontal resolution multiplier */ -static void draw_line(int x1, int y1, int x2, int y2, int res) { +void PictureMgr::draw_line(int x1, int y1, int x2, int y2, int res) { int i, x, y, deltaX, deltaY, stepX, stepY, errorX, errorY, detdelta; int width = _WIDTH * res; @@ -242,7 +240,7 @@ static void draw_line(int x1, int y1, int x2, int y2, int res) { * Draws short lines relative to last position. (drawing action 0xF7) * @param res horizontal resolution multiplier */ -static void dynamic_draw_line(int res) { +void PictureMgr::dynamic_draw_line(int res) { int x1, y1, disp, dx, dy; x1 = next_byte * res; @@ -250,7 +248,7 @@ static void dynamic_draw_line(int res) { put_virt_pixel(x1, y1, res); - while (42) { + for (;;) { if ((disp = next_byte) >= 0xf0) break; @@ -276,7 +274,7 @@ static void dynamic_draw_line(int res) { ** ** Draws long lines to actual locations (cf. relative) (drawing action 0xF6) **************************************************************************/ -static void absolute_draw_line(int res) { +void PictureMgr::absolute_draw_line(int res) { int x1, y1, x2, y2; x1 = next_byte * res; @@ -302,7 +300,7 @@ static void absolute_draw_line(int res) { /************************************************************************** ** okToFill **************************************************************************/ -static INLINE int is_ok_fill_here(int x, int y) { +INLINE int PictureMgr::is_ok_fill_here(int x, int y) { uint8 p; if (x < 0 || x >= _WIDTH || y < 0 || y >= _HEIGHT) @@ -311,7 +309,7 @@ static INLINE int is_ok_fill_here(int x, int y) { if (!scr_on && !pri_on) return false; - p = game.sbuf[y * _WIDTH + x]; + p = _vm->game.sbuf[y * _WIDTH + x]; if (!pri_on && scr_on && scr_colour != 15) return (p & 0x0f) == 15; @@ -325,7 +323,7 @@ static INLINE int is_ok_fill_here(int x, int y) { /************************************************************************** ** agi_fill **************************************************************************/ -static void fill_scanline(int x, int y) { +void PictureMgr::fill_scanline(int x, int y) { unsigned int c; int newspan_up, newspan_down; @@ -358,7 +356,7 @@ static void fill_scanline(int x, int y) { } } -static void agi_fill(unsigned int x, unsigned int y) { +void PictureMgr::agi_fill(unsigned int x, unsigned int y) { _PUSH(x + 320 * y); while (42) { @@ -382,7 +380,7 @@ static void agi_fill(unsigned int x, unsigned int y) { ** ** Draws an xCorner (drawing action 0xF5) **************************************************************************/ -static void x_corner(int res) { +void PictureMgr::x_corner(int res) { int x1, x2, y1, y2; x1 = next_byte * res; @@ -415,7 +413,7 @@ static void x_corner(int res) { ** ** Draws an yCorner (drawing action 0xF4) **************************************************************************/ -static void y_corner(int res) { +void PictureMgr::y_corner(int res) { int x1, x2, y1, y2; x1 = next_byte * res; @@ -449,7 +447,7 @@ static void y_corner(int res) { ** ** AGI flood fill. (drawing action 0xF8) **************************************************************************/ -static void fill() { +void PictureMgr::fill() { int x1, y1; while ((x1 = next_byte) < 0xF0 && (y1 = next_byte) < 0xf0) @@ -465,15 +463,15 @@ static void fill() { ** on the pattern code. **************************************************************************/ -static int plot_pattern_point(int x, int y, int bitpos, int res) { +int PictureMgr::plot_pattern_point(int x, int y, int bitpos, int res) { if (pat_code & 0x20) { if ((splatter_map[bitpos >> 3] >> (7 - (bitpos & 7))) & 1) { if (res > 1) { /* extra randomness in hi-res brush fill */ - if (rnd->getRandomNumber(3)) + if (_vm->_rnd->getRandomNumber(3)) put_virt_pixel(x * 2, y, 2); - if (!rnd->getRandomNumber(3)) + if (!_vm->_rnd->getRandomNumber(3)) put_virt_pixel(x * 2 + 1, y, 2); } else { put_virt_pixel(x, y, 1); @@ -497,7 +495,7 @@ static int plot_pattern_point(int x, int y, int bitpos, int res) { return bitpos; } -static void plot_pattern(int x, int y, int res) { +void PictureMgr::plot_pattern(int x, int y, int res) { int32 circlePos = 0; uint32 x1, y1, pensize, bitpos = splatter_start[pat_num]; @@ -527,7 +525,7 @@ static void plot_pattern(int x, int y, int res) { ** ** Plots points and various brush patterns. **************************************************************************/ -static void plot_brush(int res) { +void PictureMgr::plot_brush(int res) { int x1, y1; while (42) { @@ -549,7 +547,7 @@ static void plot_brush(int res) { foffs--; } -static void fix_pixel_bothsides(int x, int y) { +void PictureMgr::fix_pixel_bothsides(int x, int y) { uint8 *p, *s; if (x >= (_WIDTH * 2) - 2) @@ -559,7 +557,7 @@ static void fix_pixel_bothsides(int x, int y) { * with lines, and we want to keep this effect in the * hi-res pic. */ - p = &game.hires[y * (_WIDTH * 2) + x]; + p = &_vm->game.hires[y * (_WIDTH * 2) + x]; if ((*(p - 2) & 0x0f) == scr_colour) put_virt_pixel(x - 1, y, 2); if ((*(p + 2) & 0x0f) == scr_colour) @@ -570,7 +568,7 @@ static void fix_pixel_bothsides(int x, int y) { * in some scenes like in front of Lefty's in LSL1, to draw * the pole. Note: it adds artifacts in some cases. */ - s = &game.sbuf[y * _WIDTH + x / 2]; + s = &_vm->game.sbuf[y * _WIDTH + x / 2]; if ((*(p - 1) & 0x0f) != (*(s - 1) & 0x0f)) put_virt_pixel(x - 1, y, 2); } @@ -578,7 +576,7 @@ static void fix_pixel_bothsides(int x, int y) { /************************************************************************** ** okToFill **************************************************************************/ -static INLINE int hires_fill_here(int x, int y) { +INLINE int PictureMgr::hires_fill_here(int x, int y) { uint8 *p, *s; if (x < 0 || x >= _WIDTH || y < 0 || y >= _HEIGHT) @@ -587,8 +585,8 @@ static INLINE int hires_fill_here(int x, int y) { if (!scr_on && !pri_on) return false; - p = &game.hires[(int32) y * (_WIDTH * 2) + x * 2]; - s = &game.sbuf[y * _WIDTH + x]; + p = &_vm->game.hires[(int32) y * (_WIDTH * 2) + x * 2]; + s = &_vm->game.sbuf[y * _WIDTH + x]; if (scr_on) { if (scr_colour == 0x0f) @@ -611,33 +609,33 @@ static INLINE int hires_fill_here(int x, int y) { return true; } -static void fix_pixel_left(int x, int y) { +void PictureMgr::fix_pixel_left(int x, int y) { uint8 *p; if (!scr_on) return; - p = &game.hires[y * (_WIDTH * 2) + x * 2 + 1]; + p = &_vm->game.hires[y * (_WIDTH * 2) + x * 2 + 1]; if ((*p & 0x0f) == 0x0f) put_virt_pixel(2 * x + 1, y, 2); else if ((*p & 0x0f) == (*(p - 1) & 0x0f)) put_virt_pixel(2 * x + 1, y, 2); } -static void fix_pixel_right(int x, int y) { +void PictureMgr::fix_pixel_right(int x, int y) { int idx = y * (_WIDTH * 2) + x * 2; if (idx >= 160 * 168) return; - if (scr_on && (game.hires[idx] & 0x0f) == 0x0f) + if (scr_on && (_vm->game.hires[idx] & 0x0f) == 0x0f) put_virt_pixel(2 * x, y, 2); } -static void fix_pixel_here(int x, int y) { +void PictureMgr::fix_pixel_here(int x, int y) { uint8 p; - p = game.hires[y * (_WIDTH * 2) + x * 2 + 1]; + p = _vm->game.hires[y * (_WIDTH * 2) + x * 2 + 1]; if (scr_on && (p & 0x0f) == 0x0f) put_virt_pixel(2 * x + 1, y, 2); } @@ -645,7 +643,7 @@ static void fix_pixel_here(int x, int y) { /************************************************************************** ** agiFill **************************************************************************/ -static void hires_fill_scanline(int x, int y) { +void PictureMgr::hires_fill_scanline(int x, int y) { unsigned int c; int newspan_up, newspan_down; @@ -683,7 +681,7 @@ static void hires_fill_scanline(int x, int y) { fix_pixel_right(c, y); } -static void _hires_fill(unsigned int x, unsigned int y) { +void PictureMgr::_hires_fill(unsigned int x, unsigned int y) { _PUSH(x + 320 * y); while (42) { @@ -707,7 +705,7 @@ static void _hires_fill(unsigned int x, unsigned int y) { ** ** AGI flood fill. (drawing action 0xF8) **************************************************************************/ -static void hires_fill() { +void PictureMgr::hires_fill() { int x1, y1; while ((x1 = next_byte) < 0xf0 && (y1 = next_byte) < 0xf0) { @@ -721,28 +719,28 @@ static void hires_fill() { * Show AGI picture. * This function copies a ``hidden'' AGI picture to the output device. */ -void show_hires_pic() { +void PictureMgr::show_hires_pic() { int y, offset; int32 i; i = 0; - offset = game.line_min_print * CHAR_LINES; + offset = _vm->game.line_min_print * CHAR_LINES; for (y = 0; y < _HEIGHT; y++) { - put_pixels_hires(0, y + offset, _WIDTH * 2, &game.hires[i]); + _gfx->putPixelsHires(0, y + offset, _WIDTH * 2, &_vm->game.hires[i]); i += _WIDTH * 2; } - flush_screen(); + _gfx->flushScreen(); } -void fix_hires_picture() { +void PictureMgr::fix_hires_picture() { uint8 *p, *b; int i; - p = game.hires; - b = game.sbuf; + p = _vm->game.hires; + b = _vm->game.sbuf; - for (i = 0; p < &game.hires[_WIDTH * _HEIGHT * 2] - 1; p++, i++) { + for (i = 0; p < &_vm->game.hires[_WIDTH * _HEIGHT * 2] - 1; p++, i++) { if ((*p & 0x0f) == 0x0f && (*b & 0x0f) != 0x0f) { if ((*(p + 1) & 0x0f) != 0x0f) *p = *(p + 1); @@ -756,7 +754,7 @@ void fix_hires_picture() { } } -static void draw_picture() { +void PictureMgr::draw_picture() { uint8 act; int drawing; int save_foffs; @@ -873,7 +871,7 @@ static void draw_picture() { /** * */ -uint8 *convert_v3_pic(uint8 *src, uint32 len) { +uint8 *PictureMgr::convert_v3_pic(uint8 *src, uint32 len) { uint8 d, old = 0, x, *in, *xdata, *out, mode = 0; uint32 i, ulen; @@ -922,7 +920,7 @@ uint8 *convert_v3_pic(uint8 *src, uint32 len) { * @param n AGI picture resource number * @param clear clear AGI screen before drawing */ -int decode_picture(int n, int clear) { +int PictureMgr::decode_picture(int n, int clear) { debugC(8, kDebugLevelResources, "(%d)", n); pat_code = 0; @@ -931,13 +929,13 @@ int decode_picture(int n, int clear) { scr_colour = 0xF; pri_colour = 0x4; - data = game.pictures[n].rdata; - flen = game.dir_pic[n].len; + data = _vm->game.pictures[n].rdata; + flen = _vm->game.dir_pic[n].len; foffs = 0; if (clear) { - memset(game.sbuf, 0x4f, _WIDTH * _HEIGHT); - memset(game.hires, 0x4f, _WIDTH * 2 * _HEIGHT); + memset(_vm->game.sbuf, 0x4f, _WIDTH * _HEIGHT); + memset(_vm->game.hires, 0x4f, _WIDTH * 2 * _HEIGHT); } draw_picture(); @@ -945,8 +943,8 @@ int decode_picture(int n, int clear) { fix_hires_picture(); if (clear) - clear_image_stack(); - record_image_stack_call(ADD_PIC, n, clear, 0, 0, 0, 0, 0); + _vm->clear_image_stack(); + _vm->record_image_stack_call(ADD_PIC, n, clear, 0, 0, 0, 0, 0); return err_OK; } @@ -957,11 +955,11 @@ int decode_picture(int n, int clear) { * resource data. * @param n AGI picture resource number */ -int unload_picture(int n) { +int PictureMgr::unload_picture(int n) { /* remove visual buffer & priority buffer if they exist */ - if (game.dir_pic[n].flags & RES_LOADED) { - free(game.pictures[n].rdata); - game.dir_pic[n].flags &= ~RES_LOADED; + if (_vm->game.dir_pic[n].flags & RES_LOADED) { + free(_vm->game.pictures[n].rdata); + _vm->game.dir_pic[n].flags &= ~RES_LOADED; } return err_OK; @@ -971,24 +969,24 @@ int unload_picture(int n) { * Show AGI picture. * This function copies a ``hidden'' AGI picture to the output device. */ -void show_pic() { +void PictureMgr::show_pic() { int i, y; int offset; debugC(8, kDebugLevelMain, "Show picture!"); - if (opt.hires) { + if (_vm->opt.hires) { show_hires_pic(); return; } i = 0; - offset = game.line_min_print * CHAR_LINES; + offset = _vm->game.line_min_print * CHAR_LINES; for (y = 0; y < _HEIGHT; y++) { - put_pixels_a(0, y + offset, _WIDTH, &game.sbuf[i]); + _gfx->putPixelsA(0, y + offset, _WIDTH, &_vm->game.sbuf[i]); i += _WIDTH; } - flush_screen(); + _gfx->flushScreen(); } } // End of namespace Agi diff --git a/engines/agi/picture.h b/engines/agi/picture.h index 6700f436b3..97e331a1a5 100644 --- a/engines/agi/picture.h +++ b/engines/agi/picture.h @@ -37,10 +37,51 @@ struct agi_picture { uint8 *rdata; /**< raw vector image data */ }; -int decode_picture(int, int); -int unload_picture(int); -void show_pic(void); -uint8 *convert_v3_pic(uint8 *src, uint32 len); +class AgiEngine; +class GfxMgr; + +class PictureMgr { + AgiEngine *_vm; + GfxMgr *_gfx; + +private: + + void draw_line(int x1, int y1, int x2, int y2, int res); + void put_virt_pixel(int x, int y, int res); + void dynamic_draw_line(int res); + void absolute_draw_line(int res); + INLINE int is_ok_fill_here(int x, int y); + void fill_scanline(int x, int y); + void agi_fill(unsigned int x, unsigned int y); + void x_corner(int res); + void y_corner(int res); + void fill(); + int plot_pattern_point(int x, int y, int bitpos, int res); + void plot_pattern(int x, int y, int res); + void plot_brush(int res); + void fix_pixel_left(int x, int y); + void fix_pixel_bothsides(int x, int y); + void fix_pixel_right(int x, int y); + void fix_pixel_here(int x, int y); + void hires_fill_scanline(int x, int y); + void _hires_fill(unsigned int x, unsigned int y); + void hires_fill(); + INLINE int hires_fill_here(int x, int y); + void show_hires_pic(); + void fix_hires_picture(); + void draw_picture(); + +public: + PictureMgr(AgiEngine *agi, GfxMgr *gfx) { + _vm = agi; + _gfx = gfx; + } + + int decode_picture(int, int); + int unload_picture(int); + void show_pic(); + uint8 *convert_v3_pic(uint8 *src, uint32 len); +}; } // End of namespace Agi diff --git a/engines/agi/predictive.cpp b/engines/agi/predictive.cpp index 6fed021fb3..d75a5a38b9 100644 --- a/engines/agi/predictive.cpp +++ b/engines/agi/predictive.cpp @@ -33,7 +33,7 @@ namespace Agi { #define kModeNum 1 #define kModeAbc 2 -bool TextMan::predictiveDialog(void) { +bool AgiEngine::predictiveDialog(void) { int key, active = 0; bool rc = false; int x; @@ -70,10 +70,10 @@ bool TextMan::predictiveDialog(void) { } draw_window(50, 40, 269, 159); - draw_rectangle(62, 54, 249, 66, MSG_BOX_TEXT); - flush_block(62, 54, 249, 66); + _gfx->drawRectangle(62, 54, 249, 66, MSG_BOX_TEXT); + _gfx->flushBlock(62, 54, 249, 66); - print_character(3, 11, game.cursor_char, MSG_BOX_COLOUR, MSG_BOX_TEXT); + _gfx->printCharacter(3, 11, game.cursor_char, MSG_BOX_COLOUR, MSG_BOX_TEXT); bx[15] = 73; // Zero/space by[15] = 120; @@ -103,8 +103,8 @@ bool TextMan::predictiveDialog(void) { } /* clear key queue */ - while (keypress()) { - get_key(); + while (_gfx->keypress()) { + _gfx->getKey(); } _wordPosition = 0; @@ -131,9 +131,9 @@ bool TextMan::predictiveDialog(void) { color2 = 7; } if (i == 14) { - draw_button(bx[i], by[i], modes[mode], i == active, 0, color1, color2); + _gfx->drawButton(bx[i], by[i], modes[mode], i == active, 0, color1, color2); } else { - draw_button(bx[i], by[i], buttons[i], i == active, 0, color1, color2); + _gfx->drawButton(bx[i], by[i], buttons[i], i == active, 0, color1, color2); } } @@ -147,11 +147,11 @@ bool TextMan::predictiveDialog(void) { temp[i] = ' '; print_text(temp, 0, 8, 7, MAXWORDLEN, 15, 0); - flush_block(62, 54, 249, 66); + _gfx->flushBlock(62, 54, 249, 66); } } - poll_timer(); /* msdos driver -> does nothing */ + _gfx->pollTimer(); /* msdos driver -> does nothing */ key = do_poll_keyboard(); switch (key) { case KEY_ENTER: @@ -162,7 +162,7 @@ bool TextMan::predictiveDialog(void) { goto getout; case BUTTON_LEFT: for (int i = 0; buttons[i]; i++) { - if (test_button(bx[i], by[i], buttons[i])) { + if (_gfx->testButton(bx[i], by[i], buttons[i])) { needRefresh = true; active = i; @@ -237,7 +237,7 @@ bool TextMan::predictiveDialog(void) { needRefresh = true; break; } - do_update(); + _gfx->doUpdate(); } press: @@ -266,7 +266,7 @@ static char *rtrim(char *t) { #define MAXLINELEN 80 -void TextMan::loadDict(void) { +void AgiEngine::loadDict(void) { Common::File in; char buf[MAXLINELEN]; @@ -307,7 +307,7 @@ void TextMan::loadDict(void) { debug(0, "Loaded %d keys", _dict.size()); } -bool TextMan::matchWord(void) { +bool AgiEngine::matchWord(void) { _addIsActive = false; if (!_currentCode.size()) { diff --git a/engines/agi/savegame.cpp b/engines/agi/savegame.cpp index dea7977e5d..5d07c08280 100644 --- a/engines/agi/savegame.cpp +++ b/engines/agi/savegame.cpp @@ -28,6 +28,7 @@ */ #include "common/stdafx.h" +#include "common/file.h" #include "agi/agi.h" #include "agi/graphics.h" @@ -39,148 +40,24 @@ namespace Agi { -#if defined(WIN32) -#define MKDIR(a,b) mkdir(a) -#else -#define MKDIR(a,b) mkdir(a,b) -#endif - -/* Image stack support */ -struct image_stack_element { - uint8 type; - uint8 pad; - int16 parm1; - int16 parm2; - int16 parm3; - int16 parm4; - int16 parm5; - int16 parm6; - int16 parm7; -}; - -#define INITIAL_IMAGE_STACK_SIZE 32 -static int stack_size = 0; -static struct image_stack_element *image_stack = NULL; -static int image_stack_pointer = 0; - -void clear_image_stack(void) { - image_stack_pointer = 0; -} - -void release_image_stack(void) { - if (image_stack) - free(image_stack); - image_stack = NULL; - stack_size = image_stack_pointer = 0; -} - -void record_image_stack_call(uint8 type, int16 p1, int16 p2, int16 p3, - int16 p4, int16 p5, int16 p6, int16 p7) { - struct image_stack_element *pnew; - - if (image_stack_pointer == stack_size) { - if (stack_size == 0) { /* first call */ - image_stack = (struct image_stack_element *) - malloc(INITIAL_IMAGE_STACK_SIZE * sizeof(struct image_stack_element)); - stack_size = INITIAL_IMAGE_STACK_SIZE; - } else { /* has to grow */ - struct image_stack_element *new_stack; - new_stack = (struct image_stack_element *) - malloc(2 * stack_size * sizeof(struct image_stack_element)); - memcpy(new_stack, image_stack, stack_size * sizeof(struct image_stack_element)); - free(image_stack); - image_stack = new_stack; - stack_size *= 2; - } - } - - pnew = &image_stack[image_stack_pointer]; - image_stack_pointer++; - - pnew->type = type; - pnew->parm1 = p1; - pnew->parm2 = p2; - pnew->parm3 = p3; - pnew->parm4 = p4; - pnew->parm5 = p5; - pnew->parm6 = p6; - pnew->parm7 = p7; -} - -void replay_image_stack_call(uint8 type, int16 p1, int16 p2, int16 p3, - int16 p4, int16 p5, int16 p6, int16 p7) { - switch (type) { - case ADD_PIC: - debugC(8, kDebugLevelMain, "--- decoding picture %d ---", p1); - agi_load_resource(rPICTURE, p1); - decode_picture(p1, p2); - break; - case ADD_VIEW: - agi_load_resource(rVIEW, p1); - _sprites->add_to_pic(p1, p2, p3, p4, p5, p6, p7); - break; - } -} - -/* */ - static const char *strSig = "AGI:"; -// FIXME: The following wrapper methods are not needed, since class File -// (resp. class Stream) already offers similar methods. - -static void write_uint8(Common::File *f, int8 val) { - f->write(&val, 1); -} - -static void write_sint16(Common::File *f, int16 val) { - static uint8 buf[2]; - buf[0] = (uint8) ((val >> 8) & 255); - buf[1] = (uint8) (val & 255); - f->write(buf, 2); -} - -static void write_uint16(Common::File *f, uint16 val) { - static uint8 buf[2]; - buf[0] = (uint8) ((val >> 8) & 255); - buf[1] = (uint8) (val & 255); - f->write(buf, 2); -} - -static uint8 read_uint8(Common::File *f) { - static uint8 buf[1]; - f->read(buf, 1); - return buf[0]; -} - -static uint16 read_uint16(Common::File *f) { - static uint8 buf[2]; - f->read(buf, 2); - return (buf[0] << 8) | buf[1]; -} - -static int16 read_sint16(Common::File *f) { - static uint8 buf[2]; - f->read(buf, 2); - return (int16) ((buf[0] << 8) | buf[1]); -} - -static void write_string(Common::File *f, const char *s) { - write_sint16(f, (int16) strlen(s)); +void SaveGameMgr::write_string(Common::File *f, const char *s) { + f->writeSint16BE((int16)strlen(s)); f->write(s, strlen(s)); } -static void read_string(Common::File *f, char *s) { - int16 size = read_sint16(f); +void SaveGameMgr::read_string(Common::File *f, char *s) { + int16 size = f->readSint16BE(); f->read(s, size); s[size] = (char)0; } -static void write_bytes(Common::File *f, const char *s, int16 size) { +void SaveGameMgr::write_bytes(Common::File *f, const char *s, int16 size) { f->write(s, size); } -static void read_bytes(Common::File *f, char *s, int16 size) { +void SaveGameMgr::read_bytes(Common::File *f, char *s, int16 size) { f->read(s, size); } @@ -190,9 +67,9 @@ static void read_bytes(Common::File *f, char *s, int16 size) { */ #define SAVEGAME_VERSION 1 -int save_game(char *s, const char *d) { +int SaveGameMgr::save_game(char *s, const char *d) { int16 i; - struct image_stack_element *ptr = image_stack; + struct image_stack_element *ptr = _vm->image_stack; Common::File f; // FIXME: Do *not* use Common::File to access savegames, it is not portable! @@ -204,78 +81,78 @@ int save_game(char *s, const char *d) { write_bytes(&f, strSig, 8); write_string(&f, d); - write_uint8(&f, (uint8) SAVEGAME_VERSION); - write_uint8(&f, (uint8) game.state); + f.writeByte((uint8)SAVEGAME_VERSION); + f.writeByte((uint8)_vm->game.state); /* game.name */ - write_string(&f, game.id); + write_string(&f, _vm->game.id); /* game.crc */ for (i = 0; i < MAX_FLAGS; i++) - write_uint8(&f, game.flags[i]); + f.writeByte(_vm->game.flags[i]); for (i = 0; i < MAX_VARS; i++) - write_uint8(&f, game.vars[i]); + f.writeByte(_vm->game.vars[i]); - write_sint16(&f, (int8) game.horizon); - write_sint16(&f, (int16) game.line_status); - write_sint16(&f, (int16) game.line_user_input); - write_sint16(&f, (int16) game.line_min_print); + f.writeSint16BE((int8)_vm->game.horizon); + f.writeSint16BE((int16)_vm->game.line_status); + f.writeSint16BE((int16)_vm->game.line_user_input); + f.writeSint16BE((int16)_vm->game.line_min_print); /* game.cursor_pos */ /* game.input_buffer */ /* game.echo_buffer */ /* game.keypress */ - write_sint16(&f, (int16) game.input_mode); - write_sint16(&f, (int16) game.lognum); - - write_sint16(&f, (int16) game.player_control); - write_sint16(&f, (int16) game.quit_prog_now); - write_sint16(&f, (int16) game.status_line); - write_sint16(&f, (int16) game.clock_enabled); - write_sint16(&f, (int16) game.exit_all_logics); - write_sint16(&f, (int16) game.picture_shown); - write_sint16(&f, (int16) game.has_prompt); - write_sint16(&f, (int16) game.game_flags); + f.writeSint16BE((int16)_vm->game.input_mode); + f.writeSint16BE((int16)_vm->game.lognum); + + f.writeSint16BE((int16)_vm->game.player_control); + f.writeSint16BE((int16)_vm->game.quit_prog_now); + f.writeSint16BE((int16)_vm->game.status_line); + f.writeSint16BE((int16)_vm->game.clock_enabled); + f.writeSint16BE((int16)_vm->game.exit_all_logics); + f.writeSint16BE((int16)_vm->game.picture_shown); + f.writeSint16BE((int16)_vm->game.has_prompt); + f.writeSint16BE((int16)_vm->game.game_flags); /* Reversed to keep compatibility with old savegames */ - write_sint16(&f, (int16)!game.input_enabled); + f.writeSint16BE((int16)!_vm->game.input_enabled); for (i = 0; i < _HEIGHT; i++) - write_uint8(&f, game.pri_table[i]); + f.writeByte(_vm->game.pri_table[i]); /* game.msg_box_ticks */ /* game.block */ /* game.window */ /* game.has_window */ - write_sint16(&f, (int16)game.gfx_mode); - write_uint8(&f, game.cursor_char); - write_sint16(&f, (int16)game.color_fg); - write_sint16(&f, (int16)game.color_bg); + f.writeSint16BE((int16)_vm->game.gfx_mode); + f.writeByte(_vm->game.cursor_char); + f.writeSint16BE((int16)_vm->game.color_fg); + f.writeSint16BE((int16)_vm->game.color_bg); /* game.hires */ /* game.sbuf */ /* game.ego_words */ /* game.num_ego_words */ - write_sint16(&f, (int16)game.num_objects); - for (i = 0; i < (int16)game.num_objects; i++) - write_sint16(&f, (int16)object_get_location(i)); + f.writeSint16BE((int16)_vm->game.num_objects); + for (i = 0; i < (int16)_vm->game.num_objects; i++) + f.writeSint16BE((int16)_vm->object_get_location(i)); /* game.ev_keyp */ for (i = 0; i < MAX_STRINGS; i++) - write_string(&f, game.strings[i]); + write_string(&f, _vm->game.strings[i]); /* record info about loaded resources */ for (i = 0; i < MAX_DIRS; i++) { - write_uint8(&f, game.dir_logic[i].flags); - write_sint16(&f, (int16)game.logics[i].sIP); - write_sint16(&f, (int16)game.logics[i].cIP); + f.writeByte(_vm->game.dir_logic[i].flags); + f.writeSint16BE((int16)_vm->game.logics[i].sIP); + f.writeSint16BE((int16)_vm->game.logics[i].cIP); } for (i = 0; i < MAX_DIRS; i++) - write_uint8(&f, game.dir_pic[i].flags); + f.writeByte(_vm->game.dir_pic[i].flags); for (i = 0; i < MAX_DIRS; i++) - write_uint8(&f, game.dir_view[i].flags); + f.writeByte(_vm->game.dir_view[i].flags); for (i = 0; i < MAX_DIRS; i++) - write_uint8(&f, game.dir_sound[i].flags); + f.writeByte(_vm->game.dir_sound[i].flags); /* game.pictures */ /* game.logics */ @@ -283,73 +160,73 @@ int save_game(char *s, const char *d) { /* game.sounds */ for (i = 0; i < MAX_VIEWTABLE; i++) { - struct vt_entry *v = &game.view_table[i]; + struct vt_entry *v = &_vm->game.view_table[i]; - write_uint8(&f, v->step_time); - write_uint8(&f, v->step_time_count); - write_uint8(&f, v->entry); - write_sint16(&f, v->x_pos); - write_sint16(&f, v->y_pos); - write_uint8(&f, v->current_view); + f.writeByte(v->step_time); + f.writeByte(v->step_time_count); + f.writeByte(v->entry); + f.writeSint16BE(v->x_pos); + f.writeSint16BE(v->y_pos); + f.writeByte(v->current_view); /* v->view_data */ - write_uint8(&f, v->current_loop); - write_uint8(&f, v->num_loops); + f.writeByte(v->current_loop); + f.writeByte(v->num_loops); /* v->loop_data */ - write_uint8(&f, v->current_cel); - write_uint8(&f, v->num_cels); + f.writeByte(v->current_cel); + f.writeByte(v->num_cels); /* v->cel_data */ /* v->cel_data_2 */ - write_sint16(&f, v->x_pos2); - write_sint16(&f, v->y_pos2); + f.writeSint16BE(v->x_pos2); + f.writeSint16BE(v->y_pos2); /* v->s */ - write_sint16(&f, v->x_size); - write_sint16(&f, v->y_size); - write_uint8(&f, v->step_size); - write_uint8(&f, v->cycle_time); - write_uint8(&f, v->cycle_time_count); - write_uint8(&f, v->direction); + f.writeSint16BE(v->x_size); + f.writeSint16BE(v->y_size); + f.writeByte(v->step_size); + f.writeByte(v->cycle_time); + f.writeByte(v->cycle_time_count); + f.writeByte(v->direction); - write_uint8(&f, v->motion); - write_uint8(&f, v->cycle); - write_uint8(&f, v->priority); + f.writeByte(v->motion); + f.writeByte(v->cycle); + f.writeByte(v->priority); - write_uint16(&f, v->flags); + f.writeUint16BE(v->flags); - write_uint8(&f, v->parm1); - write_uint8(&f, v->parm2); - write_uint8(&f, v->parm3); - write_uint8(&f, v->parm4); + f.writeByte(v->parm1); + f.writeByte(v->parm2); + f.writeByte(v->parm3); + f.writeByte(v->parm4); } /* Save image stack */ - for (i = 0; i < image_stack_pointer; i++) { - ptr = &image_stack[i]; - write_uint8(&f, ptr->type); - write_sint16(&f, ptr->parm1); - write_sint16(&f, ptr->parm2); - write_sint16(&f, ptr->parm3); - write_sint16(&f, ptr->parm4); - write_sint16(&f, ptr->parm5); - write_sint16(&f, ptr->parm6); - write_sint16(&f, ptr->parm7); + for (i = 0; i < _vm->image_stack_pointer; i++) { + ptr = &_vm->image_stack[i]; + f.writeByte(ptr->type); + f.writeSint16BE(ptr->parm1); + f.writeSint16BE(ptr->parm2); + f.writeSint16BE(ptr->parm3); + f.writeSint16BE(ptr->parm4); + f.writeSint16BE(ptr->parm5); + f.writeSint16BE(ptr->parm6); + f.writeSint16BE(ptr->parm7); } - write_uint8(&f, 0); + f.writeByte(0); f.close(); return err_OK; } -int load_game(char *s) { +int SaveGameMgr::load_game(char *s) { int i, ver, vt_entries = MAX_VIEWTABLE; uint8 t; int16 parm[7]; @@ -372,61 +249,62 @@ int load_game(char *s) { read_string(&f, description); - ver = read_uint8(&f); + ver = f.readByte(); if (ver == 0) vt_entries = 64; - game.state = read_uint8(&f); + _vm->game.state = f.readByte(); /* game.name - not saved */ read_string(&f, id); - if (strcmp(id, game.id)) { + if (strcmp(id, _vm->game.id)) { f.close(); return err_BadFileOpen; } /* game.crc - not saved */ for (i = 0; i < MAX_FLAGS; i++) - game.flags[i] = read_uint8(&f); + _vm->game.flags[i] = f.readByte(); for (i = 0; i < MAX_VARS; i++) - game.vars[i] = read_uint8(&f); + _vm->game.vars[i] = f.readByte(); - game.horizon = read_sint16(&f); - game.line_status = read_sint16(&f); - game.line_user_input = read_sint16(&f); - game.line_min_print = read_sint16(&f); + _vm->game.horizon = f.readSint16BE(); + _vm->game.line_status = f.readSint16BE(); + _vm->game.line_user_input = f.readSint16BE(); + _vm->game.line_min_print = f.readSint16BE(); /* These are never saved */ - game.cursor_pos = 0; - game.input_buffer[0] = 0; - game.echo_buffer[0] = 0; - game.keypress = 0; - - game.input_mode = read_sint16(&f); - game.lognum = read_sint16(&f); - - game.player_control = read_sint16(&f); - game.quit_prog_now = read_sint16(&f); - game.status_line = read_sint16(&f); - game.clock_enabled = read_sint16(&f); - game.exit_all_logics = read_sint16(&f); - game.picture_shown = read_sint16(&f); - game.has_prompt = read_sint16(&f); - game.game_flags = read_sint16(&f); - game.input_enabled = !read_sint16(&f); + _vm->game.cursor_pos = 0; + _vm->game.input_buffer[0] = 0; + _vm->game.echo_buffer[0] = 0; + _vm->game.keypress = 0; + + _vm->game.input_mode = f.readSint16BE(); + _vm->game.lognum = f.readSint16BE(); + + _vm->game.player_control = f.readSint16BE(); + _vm->game.quit_prog_now = f.readSint16BE(); + _vm->game.status_line = f.readSint16BE(); + _vm->game.clock_enabled = f.readSint16BE(); + _vm->game.exit_all_logics = f.readSint16BE(); + _vm->game.picture_shown = f.readSint16BE(); + _vm->game.has_prompt = f.readSint16BE(); + _vm->game.game_flags = f.readSint16BE(); + _vm->game.input_enabled = !f.readSint16BE(); for (i = 0; i < _HEIGHT; i++) - game.pri_table[i] = read_uint8(&f); + _vm->game.pri_table[i] = f.readByte(); + + if (_vm->game.has_window) + _vm->close_window(); - if (game.has_window) - _text->close_window(); - game.msg_box_ticks = 0; - game.block.active = false; + _vm->game.msg_box_ticks = 0; + _vm->game.block.active = false; /* game.window - fixed by close_window() */ /* game.has_window - fixed by close_window() */ - game.gfx_mode = read_sint16(&f); - game.cursor_char = read_uint8(&f); - game.color_fg = read_sint16(&f); - game.color_bg = read_sint16(&f); + _vm->game.gfx_mode = f.readSint16BE(); + _vm->game.cursor_char = f.readByte(); + _vm->game.color_fg = f.readSint16BE(); + _vm->game.color_bg = f.readSint16BE(); /* game.hires - rebuilt from image stack */ /* game.sbuf - rebuilt from image stack */ @@ -434,46 +312,46 @@ int load_game(char *s) { /* game.ego_words - fixed by clean_input */ /* game.num_ego_words - fixed by clean_input */ - game.num_objects = read_sint16(&f); - for (i = 0; i < (int16) game.num_objects; i++) - object_set_location(i, read_sint16(&f)); + _vm->game.num_objects = f.readSint16BE(); + for (i = 0; i < (int16)_vm->game.num_objects; i++) + _vm->object_set_location(i, f.readSint16BE()); /* Those are not serialized */ for (i = 0; i < MAX_DIRS; i++) { - game.ev_keyp[i].occured = false; + _vm->game.ev_keyp[i].occured = false; } for (i = 0; i < MAX_STRINGS; i++) - read_string(&f, game.strings[i]); + read_string(&f, _vm->game.strings[i]); for (i = 0; i < MAX_DIRS; i++) { - if (read_uint8(&f) & RES_LOADED) - agi_load_resource(rLOGIC, i); + if (f.readByte() & RES_LOADED) + _vm->agiLoadResource(rLOGIC, i); else - agi_unload_resource(rLOGIC, i); - game.logics[i].sIP = read_sint16(&f); - game.logics[i].cIP = read_sint16(&f); + _vm->agiUnloadResource(rLOGIC, i); + _vm->game.logics[i].sIP = f.readSint16BE(); + _vm->game.logics[i].cIP = f.readSint16BE(); } for (i = 0; i < MAX_DIRS; i++) { - if (read_uint8(&f) & RES_LOADED) - agi_load_resource(rPICTURE, i); + if (f.readByte() & RES_LOADED) + _vm->agiLoadResource(rPICTURE, i); else - agi_unload_resource(rPICTURE, i); + _vm->agiUnloadResource(rPICTURE, i); } for (i = 0; i < MAX_DIRS; i++) { - if (read_uint8(&f) & RES_LOADED) - agi_load_resource(rVIEW, i); + if (f.readByte() & RES_LOADED) + _vm->agiLoadResource(rVIEW, i); else - agi_unload_resource(rVIEW, i); + _vm->agiUnloadResource(rVIEW, i); } for (i = 0; i < MAX_DIRS; i++) { - if (read_uint8(&f) & RES_LOADED) - agi_load_resource(rSOUND, i); + if (f.readByte() & RES_LOADED) + _vm->agiLoadResource(rSOUND, i); else - agi_unload_resource(rSOUND, i); + _vm->agiUnloadResource(rSOUND, i); } /* game.pictures - loaded above */ @@ -482,69 +360,69 @@ int load_game(char *s) { /* game.sounds - loaded above */ for (i = 0; i < vt_entries; i++) { - struct vt_entry *v = &game.view_table[i]; + struct vt_entry *v = &_vm->game.view_table[i]; - v->step_time = read_uint8(&f); - v->step_time_count = read_uint8(&f); - v->entry = read_uint8(&f); - v->x_pos = read_sint16(&f); - v->y_pos = read_sint16(&f); - v->current_view = read_uint8(&f); + v->step_time = f.readByte(); + v->step_time_count = f.readByte(); + v->entry = f.readByte(); + v->x_pos = f.readSint16BE(); + v->y_pos = f.readSint16BE(); + v->current_view = f.readByte(); /* v->view_data - fixed below */ - v->current_loop = read_uint8(&f); - v->num_loops = read_uint8(&f); + v->current_loop = f.readByte(); + v->num_loops = f.readByte(); /* v->loop_data - fixed below */ - v->current_cel = read_uint8(&f); - v->num_cels = read_uint8(&f); + v->current_cel = f.readByte(); + v->num_cels = f.readByte(); /* v->cel_data - fixed below */ /* v->cel_data_2 - fixed below */ - v->x_pos2 = read_sint16(&f); - v->y_pos2 = read_sint16(&f); + v->x_pos2 = f.readSint16BE(); + v->y_pos2 = f.readSint16BE(); /* v->s - fixed below */ - v->x_size = read_sint16(&f); - v->y_size = read_sint16(&f); - v->step_size = read_uint8(&f); - v->cycle_time = read_uint8(&f); - v->cycle_time_count = read_uint8(&f); - v->direction = read_uint8(&f); + v->x_size = f.readSint16BE(); + v->y_size = f.readSint16BE(); + v->step_size = f.readByte(); + v->cycle_time = f.readByte(); + v->cycle_time_count = f.readByte(); + v->direction = f.readByte(); - v->motion = read_uint8(&f); - v->cycle = read_uint8(&f); - v->priority = read_uint8(&f); + v->motion = f.readByte(); + v->cycle = f.readByte(); + v->priority = f.readByte(); - v->flags = read_uint16(&f); + v->flags = f.readUint16BE(); - v->parm1 = read_uint8(&f); - v->parm2 = read_uint8(&f); - v->parm3 = read_uint8(&f); - v->parm4 = read_uint8(&f); + v->parm1 = f.readByte(); + v->parm2 = f.readByte(); + v->parm3 = f.readByte(); + v->parm4 = f.readByte(); } for (i = vt_entries; i < MAX_VIEWTABLE; i++) { - memset(&game.view_table[i], 0, sizeof(struct vt_entry)); + memset(&_vm->game.view_table[i], 0, sizeof(struct vt_entry)); } /* Fix some pointers in viewtable */ for (i = 0; i < MAX_VIEWTABLE; i++) { - struct vt_entry *v = &game.view_table[i]; + struct vt_entry *v = &_vm->game.view_table[i]; - if (game.dir_view[v->current_view].offset == _EMPTY) + if (_vm->game.dir_view[v->current_view].offset == _EMPTY) continue; - if (!(game.dir_view[v->current_view].flags & RES_LOADED)) - agi_load_resource(rVIEW, v->current_view); + if (!(_vm->game.dir_view[v->current_view].flags & RES_LOADED)) + _vm->agiLoadResource(rVIEW, v->current_view); - set_view(v, v->current_view); /* Fix v->view_data */ - set_loop(v, v->current_loop); /* Fix v->loop_data */ - set_cel(v, v->current_cel); /* Fix v->cel_data */ + _vm->set_view(v, v->current_view); /* Fix v->view_data */ + _vm->set_loop(v, v->current_loop); /* Fix v->loop_data */ + _vm->set_cel(v, v->current_cel); /* Fix v->cel_data */ v->cel_data_2 = v->cel_data; v->s = NULL; /* not sure if it is used... */ } @@ -552,37 +430,37 @@ int load_game(char *s) { _sprites->erase_both(); /* Clear input line */ - clear_screen(0); - _text->write_status(); + _gfx->clearScreen(0); + _vm->write_status(); /* Recreate background from saved image stack */ - clear_image_stack(); - while ((t = read_uint8(&f)) != 0) { + _vm->clear_image_stack(); + while ((t = f.readByte()) != 0) { for (i = 0; i < 7; i++) - parm[i] = read_sint16(&f); - replay_image_stack_call(t, parm[0], parm[1], parm[2], + parm[i] = f.readSint16BE(); + _vm->replay_image_stack_call(t, parm[0], parm[1], parm[2], parm[3], parm[4], parm[5], parm[6]); } f.close(); - setflag(F_restore_just_ran, true); + _vm->setflag(F_restore_just_ran, true); - game.has_prompt = 0; /* force input line repaint if necessary */ - clean_input(); + _vm->game.has_prompt = 0; /* force input line repaint if necessary */ + _vm->clean_input(); _sprites->erase_both(); _sprites->blit_both(); _sprites->commit_both(); - show_pic(); - do_update(); + _picture->show_pic(); + _gfx->doUpdate(); return err_OK; } #define NUM_SLOTS 12 -static int select_slot() { +int SaveGameMgr::select_slot() { int i, key, active = 0; int rc = -1; int hm = 2, vm = 3; /* box margins */ @@ -593,7 +471,7 @@ static int select_slot() { Common::File f; char sig[8]; // FIXME: Do *not* use Common::File to access savegames, it is not portable! - sprintf(name, "%s/%05X_%s_%02d.sav", _savePath, game.crc, game.id, i); + sprintf(name, "%s/%05X_%s_%02d.sav", _vm->_savePath, _vm->game.crc, _vm->game.id, i); f.open(name); if (!f.isOpen()) { strcpy(desc[i], " (empty slot)"); @@ -608,29 +486,22 @@ static int select_slot() { } } - while (42) { + for (;;) { char dstr[64]; for (i = 0; i < NUM_SLOTS; i++) { -#ifndef PALMOS_68K sprintf(dstr, "[%-32.32s]", desc[i]); -#else - dstr[0] = '['; - memcpy(dstr + 1, desc[i], 32); - dstr[33] = ']'; - dstr[34] = 0; -#endif - _text->print_text(dstr, 0, hm + 1, vm + 4 + i, + _vm->print_text(dstr, 0, hm + 1, vm + 4 + i, (40 - 2 * hm) - 1, i == active ? MSG_BOX_COLOUR : MSG_BOX_TEXT, i == active ? MSG_BOX_TEXT : MSG_BOX_COLOUR); } - poll_timer(); /* msdos driver -> does nothing */ - key = do_poll_keyboard(); + _gfx->pollTimer(); /* msdos driver -> does nothing */ + key = _vm->do_poll_keyboard(); switch (key) { case KEY_ENTER: rc = active; - strncpy(game.strings[MAX_STRINGS], desc[i], MAX_STRINGLEN); + strncpy(_vm->game.strings[MAX_STRINGS], desc[i], MAX_STRINGLEN); goto press; case KEY_ESCAPE: rc = -1; @@ -647,27 +518,27 @@ static int select_slot() { active = NUM_SLOTS - 1; break; } - do_update(); + _gfx->doUpdate(); } press: debugC(8, kDebugLevelMain | kDebugLevelInput, "Button pressed: %d", rc); getout: - _text->close_window(); + _vm->close_window(); return rc; } -int savegame_simple() { +int SaveGameMgr::savegame_simple() { char path[MAX_PATH]; - sprintf(path, "%s/%05X_%s_%02d.sav", _savePath, game.crc, game.id, 0); + sprintf(path, "%s/%05X_%s_%02d.sav", _vm->_savePath, _vm->game.crc, _vm->game.id, 0); save_game(path, "Default savegame"); return err_OK; } -int savegame_dialog() { +int SaveGameMgr::savegame_dialog() { char path[MAX_PATH]; char *desc; const char *buttons[] = { "Do as I say!", "I regret", NULL }; @@ -682,12 +553,12 @@ int savegame_dialog() { vp = vm * CHAR_LINES; w = (40 - 2 * hm) - 1; - sprintf(path, "%s/%05X_%s_%02d.sav", _savePath, game.crc, game.id, slot); + sprintf(path, "%s/%05X_%s_%02d.sav", _vm->_savePath, _vm->game.crc, _vm->game.id, slot); - _text->draw_window(hp, vp, GFX_WIDTH - hp, GFX_HEIGHT - vp); - _text->print_text("Select a slot in which you wish to save the game:", + _vm->draw_window(hp, vp, GFX_WIDTH - hp, GFX_HEIGHT - vp); + _vm->print_text("Select a slot in which you wish to save the game:", 0, hm + 1, vm + 1, w, MSG_BOX_TEXT, MSG_BOX_COLOUR); - _text->print_text("Press ENTER to select, ESC cancels", + _vm->print_text("Press ENTER to select, ESC cancels", 0, hm + 1, vm + 17, w, MSG_BOX_TEXT, MSG_BOX_COLOUR); slot = select_slot(); @@ -695,65 +566,65 @@ int savegame_dialog() { return err_OK; /* Get savegame description */ - _text->draw_window(hp, vp + 5 * CHAR_LINES, GFX_WIDTH - hp, + _vm->draw_window(hp, vp + 5 * CHAR_LINES, GFX_WIDTH - hp, GFX_HEIGHT - vp - 9 * CHAR_LINES); - _text->print_text("Enter a description for this game:", + _vm->print_text("Enter a description for this game:", 0, hm + 1, vm + 6, w, MSG_BOX_TEXT, MSG_BOX_COLOUR); - draw_rectangle(3 * CHAR_COLS, 11 * CHAR_LINES - 1, + _gfx->drawRectangle(3 * CHAR_COLS, 11 * CHAR_LINES - 1, 37 * CHAR_COLS, 12 * CHAR_LINES, MSG_BOX_TEXT); - flush_block(3 * CHAR_COLS, 11 * CHAR_LINES - 1, + _gfx->flushBlock(3 * CHAR_COLS, 11 * CHAR_LINES - 1, 37 * CHAR_COLS, 12 * CHAR_LINES); - get_string(2, 11, 33, MAX_STRINGS); - print_character(3, 11, game.cursor_char, MSG_BOX_COLOUR, MSG_BOX_TEXT); + _vm->get_string(2, 11, 33, MAX_STRINGS); + _gfx->printCharacter(3, 11, _vm->game.cursor_char, MSG_BOX_COLOUR, MSG_BOX_TEXT); do { - main_cycle(); - } while (game.input_mode == INPUT_GETSTRING); - _text->close_window(); + _vm->main_cycle(); + } while (_vm->game.input_mode == INPUT_GETSTRING); + _vm->close_window(); - desc = game.strings[MAX_STRINGS]; + desc = _vm->game.strings[MAX_STRINGS]; sprintf(dstr, "Are you sure you want to save the game " "described as:\n\n%s\n\nin slot %d?\n\n\n", desc, slot); - rc = _text->selection_box(dstr, buttons); + rc = _vm->selection_box(dstr, buttons); if (rc != 0) { - _text->message_box("Game NOT saved."); + _vm->message_box("Game NOT saved."); return err_OK; } - sprintf(path, "%s/%05X_%s_%02d.sav", _savePath, game.crc, game.id, slot); + sprintf(path, "%s/%05X_%s_%02d.sav", _vm->_savePath, _vm->game.crc, _vm->game.id, slot); debugC(8, kDebugLevelMain | kDebugLevelResources, "file is [%s]", path); save_game(path, desc); - _text->message_box("Game saved."); + _vm->message_box("Game saved."); return err_OK; } -int loadgame_simple() { +int SaveGameMgr::loadgame_simple() { char path[MAX_PATH]; int rc = 0; - sprintf(path, "%s/%05X_%s_%02d.sav", _savePath, game.crc, game.id, 0); + sprintf(path, "%s/%05X_%s_%02d.sav", _vm->_savePath, _vm->game.crc, _vm->game.id, 0); _sprites->erase_both(); - stop_sound(); - _text->close_window(); + _sound->stop_sound(); + _vm->close_window(); if ((rc = load_game(path)) == err_OK) { - _text->message_box("Game restored."); - game.exit_all_logics = 1; - menu->enable_all(); + _vm->message_box("Game restored."); + _vm->game.exit_all_logics = 1; + _vm->menu->enable_all(); } else { - _text->message_box("Error restoring game."); + _vm->message_box("Error restoring game."); } return rc; } -int loadgame_dialog() { +int SaveGameMgr::loadgame_dialog() { char path[MAX_PATH]; int rc, slot = 0; int hm, vm, hp, vp; /* box margins */ @@ -765,32 +636,32 @@ int loadgame_dialog() { vp = vm * CHAR_LINES; w = (40 - 2 * hm) - 1; - sprintf(path, "%s/%05X_%s_%02d.sav", _savePath, game.crc, game.id, slot); + sprintf(path, "%s/%05X_%s_%02d.sav", _vm->_savePath, _vm->game.crc, _vm->game.id, slot); _sprites->erase_both(); - stop_sound(); + _sound->stop_sound(); - _text->draw_window(hp, vp, GFX_WIDTH - hp, GFX_HEIGHT - vp); - _text->print_text("Select a game which you wish to\nrestore:", + _vm->draw_window(hp, vp, GFX_WIDTH - hp, GFX_HEIGHT - vp); + _vm->print_text("Select a game which you wish to\nrestore:", 0, hm + 1, vm + 1, w, MSG_BOX_TEXT, MSG_BOX_COLOUR); - _text->print_text("Press ENTER to select, ESC cancels", + _vm->print_text("Press ENTER to select, ESC cancels", 0, hm + 1, vm + 17, w, MSG_BOX_TEXT, MSG_BOX_COLOUR); slot = select_slot(); if (slot < 0) { - _text->message_box("Game NOT restored."); + _vm->message_box("Game NOT restored."); return err_OK; } - sprintf(path, "%s/%05X_%s_%02d.sav", _savePath, game.crc, game.id, slot); + sprintf(path, "%s/%05X_%s_%02d.sav", _vm->_savePath, _vm->game.crc, _vm->game.id, slot); if ((rc = load_game(path)) == err_OK) { - _text->message_box("Game restored."); - game.exit_all_logics = 1; - menu->enable_all(); + _vm->message_box("Game restored."); + _vm->game.exit_all_logics = 1; + _vm->menu->enable_all(); } else { - _text->message_box("Error restoring game."); + _vm->message_box("Error restoring game."); } return rc; diff --git a/engines/agi/savegame.h b/engines/agi/savegame.h index dea12243c8..9d7ce30cda 100644 --- a/engines/agi/savegame.h +++ b/engines/agi/savegame.h @@ -27,23 +27,52 @@ #include "agi/agi.h" -namespace Agi { +class Common::File; -int savegame_dialog(void); -int loadgame_dialog(void); -int savegame_simple(void); -int loadgame_simple(void); +namespace Agi { -/* Image stack support */ #define ADD_PIC 1 #define ADD_VIEW 2 -void clear_image_stack(void); -void record_image_stack_call(uint8 type, int16 p1, int16 p2, int16 p3, - int16 p4, int16 p5, int16 p6, int16 p7); -void replay_image_stack_call(uint8 type, int16 p1, int16 p2, int16 p3, - int16 p4, int16 p5, int16 p6, int16 p7); -void release_image_stack(void); +class AgiEngine; +class SpritesMgr; +class GfxMgr; +class SoundMgr; +class PictureMgr; + +class SaveGameMgr { +private: + + AgiEngine *_vm; + SpritesMgr *_sprites; + GfxMgr *_gfx; + SoundMgr *_sound; + PictureMgr *_picture; + + void write_string(Common::File *f, const char *s); + void read_string(Common::File *f, char *s); + void write_bytes(Common::File *f, const char *s, int16 size); + void read_bytes(Common::File *f, char *s, int16 size); + int save_game(char *s, const char *d); + int load_game(char *s); + int select_slot(); + +public: + SaveGameMgr(AgiEngine *agi, SpritesMgr *sprites, + GfxMgr *gfx, + SoundMgr *sound, PictureMgr *picture) { + _vm = agi; + _sprites = sprites; + _gfx = gfx; + _sound = sound; + _picture = picture; + } + + int savegame_dialog(); + int loadgame_dialog(); + int savegame_simple(); + int loadgame_simple(); +}; } // End of namespace Agi diff --git a/engines/agi/sound.cpp b/engines/agi/sound.cpp index 15598ba153..f2a7776627 100644 --- a/engines/agi/sound.cpp +++ b/engines/agi/sound.cpp @@ -27,6 +27,7 @@ #include "sound/mixer.h" #include "agi/agi.h" +#include "agi/sound.h" namespace Agi { @@ -96,15 +97,11 @@ static int playing_sound = -1; static uint8 *song; static uint8 env; -struct sound_driver *snd; - -extern struct sound_driver sound_dummy; - static void stop_note(int i); static void play_note(int i, int freq, int vol); -int16 *snd_buffer; +static int16 *snd_buffer; static int16 *waveform; static int16 waveform_ramp[WAVEFORM_SIZE] = { @@ -160,20 +157,20 @@ static int note_to_period(int note) { #endif /* USE_IIGS_SOUND */ -void unload_sound(int resnum) { - if (game.dir_sound[resnum].flags & RES_LOADED) { - if (game.sounds[resnum].flags & SOUND_PLAYING) +void SoundMgr::unload_sound(int resnum) { + if (_vm->game.dir_sound[resnum].flags & RES_LOADED) { + if (_vm->game.sounds[resnum].flags & SOUND_PLAYING) /* FIXME: Stop playing */ ; /* Release RAW data for sound */ - free(game.sounds[resnum].rdata); - game.sounds[resnum].rdata = NULL; - game.dir_sound[resnum].flags &= ~RES_LOADED; + free(_vm->game.sounds[resnum].rdata); + _vm->game.sounds[resnum].rdata = NULL; + _vm->game.dir_sound[resnum].flags &= ~RES_LOADED; } } -void decode_sound(int resnum) { +void SoundMgr::decode_sound(int resnum) { #ifdef USE_IIGS_SOUND int type, size; int16 *buf; @@ -198,29 +195,29 @@ void decode_sound(int resnum) { #endif /* USE_IIGS_SOUND */ } -void start_sound(int resnum, int flag) { +void SoundMgr::start_sound(int resnum, int flag) { int i, type; #ifdef USE_IIGS_SOUND struct sound_iigs_sample *smp; #endif - if (game.sounds[resnum].flags & SOUND_PLAYING) + if (_vm->game.sounds[resnum].flags & SOUND_PLAYING) return; stop_sound(); - if (game.sounds[resnum].rdata == NULL) + if (_vm->game.sounds[resnum].rdata == NULL) return; - type = READ_LE_UINT16(game.sounds[resnum].rdata); + type = READ_LE_UINT16(_vm->game.sounds[resnum].rdata); if (type != AGI_SOUND_SAMPLE && type != AGI_SOUND_MIDI && type != AGI_SOUND_4CHN) return; - game.sounds[resnum].flags |= SOUND_PLAYING; - game.sounds[resnum].type = type; + _vm->game.sounds[resnum].flags |= SOUND_PLAYING; + _vm->game.sounds[resnum].type = type; playing_sound = resnum; - song = (uint8 *) game.sounds[resnum].rdata; + song = (uint8 *)_vm->game.sounds[resnum].rdata; switch (type) { #ifdef USE_IIGS_SOUND @@ -278,18 +275,18 @@ void start_sound(int resnum, int flag) { /* Nat Budin reports that the flag should be reset when sound starts */ - setflag(endflag, false); + _vm->setflag(endflag, false); /* FIXME: should wait for sound time instead of setting the flag * immediately */ - if (opt.nosound) { - setflag(endflag, true); + if (_vm->opt.nosound) { + _vm->setflag(endflag, true); stop_sound(); } } -void stop_sound() { +void SoundMgr::stop_sound() { int i; endflag = -1; @@ -297,21 +294,21 @@ void stop_sound() { stop_note(i); if (playing_sound != -1) { - game.sounds[playing_sound].flags &= ~SOUND_PLAYING; + _vm->game.sounds[playing_sound].flags &= ~SOUND_PLAYING; playing_sound = -1; } } static int16 *buffer; -int init_sound() { +int SoundMgr::init_sound() { int r = -1; - buffer = snd_buffer = (int16 *) calloc(2, BUFFER_SIZE); + buffer = snd_buffer = (int16 *)calloc(2, BUFFER_SIZE); env = false; - switch (opt.soundemu) { + switch (_vm->opt.soundemu) { case SOUND_EMU_NONE: waveform = waveform_ramp; env = true; @@ -341,34 +338,27 @@ int init_sound() { return r; } -void deinit_sound(void) { +void SoundMgr::deinit_sound(void) { debugC(3, kDebugLevelSound, "()"); - if (snd) - snd->deinit(); free(snd_buffer); } -static void stop_note(int i) { +void SoundMgr::stop_note(int i) { chn[i].adsr = AGI_SOUND_ENV_RELEASE; #ifdef USE_CHORUS /* Stop chorus ;) */ if (chn[i].type == AGI_SOUND_4CHN && - opt.soundemu == SOUND_EMU_NONE && i < 3) { + _vm->opt.soundemu == SOUND_EMU_NONE && i < 3) { stop_note(i + 4); } #endif - -#ifdef __TURBOC__ - if (i == 0) - nosound(); -#endif } -static void play_note(int i, int freq, int vol) { - if (!getflag(F_sound_on)) +void SoundMgr::play_note(int i, int freq, int vol) { + if (!_vm->getflag(F_sound_on)) vol = 0; - else if (vol && opt.soundemu == SOUND_EMU_PC) + else if (vol && _vm->opt.soundemu == SOUND_EMU_PC) vol = 160; chn[i].phase = 0; @@ -380,7 +370,7 @@ static void play_note(int i, int freq, int vol) { #ifdef USE_CHORUS /* Add chorus ;) */ if (chn[i].type == AGI_SOUND_4CHN && - opt.soundemu == SOUND_EMU_NONE && i < 3) { + _vm->opt.soundemu == SOUND_EMU_NONE && i < 3) { int newfreq = freq * 1007 / 1000; if (freq == newfreq) newfreq++; @@ -388,15 +378,11 @@ static void play_note(int i, int freq, int vol) { } #endif -#ifdef __TURBOC__ - if (i == 0) - sound(freq); -#endif } #ifdef USE_IIGS_SOUND -void play_midi_sound() { +void SoundMgr::play_midi_sound() { uint8 *p; uint8 parm1, parm2; static uint8 cmd, ch; @@ -457,17 +443,17 @@ void play_midi_sound() { } } -void play_sample_sound() { +void SoundMgr::play_sample_sound() { play_note(0, 11025 * 10, 200); playing = 1; } #endif /* USE_IIGS_SOUND */ -void play_agi_sound() { +void SoundMgr::play_agi_sound() { int i, freq; - for (playing = i = 0; i < (opt.soundemu == SOUND_EMU_PC ? 1 : 4); i++) { + for (playing = i = 0; i < (_vm->opt.soundemu == SOUND_EMU_PC ? 1 : 4); i++) { playing |= !chn[i].end; if (chn[i].end) @@ -490,7 +476,7 @@ void play_agi_sound() { chn[i].env = 0; #ifdef USE_CHORUS /* chorus */ - if (chn[i].type == AGI_SOUND_4CHN && opt.soundemu == SOUND_EMU_NONE && i < 3) { + if (chn[i].type == AGI_SOUND_4CHN && _vm->opt.soundemu == SOUND_EMU_NONE && i < 3) { chn[i + 4].vol = 0; chn[i + 4].env = 0; } @@ -501,7 +487,7 @@ void play_agi_sound() { } } -void play_sound() { +void SoundMgr::play_sound() { int i; if (endflag == -1) @@ -521,16 +507,16 @@ void play_sound() { for (i = 0; i < NUM_CHANNELS; chn[i++].vol = 0); if (endflag != -1) - setflag(endflag, true); + _vm->setflag(endflag, true); if (playing_sound != -1) - game.sounds[playing_sound].flags &= ~SOUND_PLAYING; + _vm->game.sounds[playing_sound].flags &= ~SOUND_PLAYING; playing_sound = -1; endflag = -1; } } -uint32 mix_sound(void) { +uint32 SoundMgr::mix_sound(void) { register int i, p; int16 *src; int c, b, m; @@ -573,7 +559,7 @@ uint32 mix_sound(void) { } else { /* Add white noise */ for (i = 0; i < BUFFER_SIZE; i++) { - b = rnd->getRandomNumber(255) - 128; + b = _vm->_rnd->getRandomNumber(255) - 128; snd_buffer[i] += (b * m) >> 4; } } @@ -608,7 +594,7 @@ uint32 mix_sound(void) { #ifdef USE_IIGS_SOUND #if 0 -int load_instruments(char *fname) { +int SoundMgr::load_instruments(char *fname) { Common::File fp; int i, j, k; struct sound_instrument ai; @@ -694,57 +680,57 @@ int load_instruments(char *fname) { return err_OK; } -void unload_instruments() { +void Sound::unload_instruments() { free(instruments); } #endif #endif /* USE_IIGS_SOUND */ -static void fill_audio(void *udata, int16 * stream, uint len) { - len <<= 2; - +static void fillAudio(void *udata, int16 *stream, uint len) { + SoundMgr *soundMgr = (SoundMgr *)udata; uint32 p = 0; static uint32 n = 0, s = 0; + len <<= 2; + debugC(5, kDebugLevelSound, "(%p, %p, %d)", (void *)udata, (void *)stream, len); - memcpy(stream, (uint8 *) buffer + s, p = n); + memcpy(stream, (uint8 *)buffer + s, p = n); for (n = 0, len -= p; n < len; p += n, len -= n) { - play_sound(); - n = mix_sound() << 1; + soundMgr->play_sound(); + n = soundMgr->mix_sound() << 1; if (len < n) { - memcpy((uint8 *) stream + p, buffer, len); + memcpy((uint8 *)stream + p, buffer, len); s = len; n -= s; return; } else { - memcpy((uint8 *) stream + p, buffer, n); + memcpy((uint8 *)stream + p, buffer, n); } } - play_sound(); - n = mix_sound() << 1; - memcpy((uint8 *) stream + p, buffer, s = len); + soundMgr->play_sound(); + n = soundMgr->mix_sound() << 1; + memcpy((uint8 *)stream + p, buffer, s = len); n -= s; } -AGIMusic::AGIMusic(Audio::Mixer *pMixer) { +SoundMgr::SoundMgr(AgiEngine *agi, Audio::Mixer *pMixer) { + _vm = agi; _mixer = pMixer; _sampleRate = pMixer->getOutputRate(); _mixer->setupPremix(this); } -void AGIMusic::premixerCall(int16 *data, uint len) { - Agi::fill_audio(NULL, data, len); +void SoundMgr::premixerCall(int16 *data, uint len) { + fillAudio(this, data, len); } -void AGIMusic::setVolume(uint8 volume) { +void SoundMgr::setVolume(uint8 volume) { // TODO } -AGIMusic::~AGIMusic(void) { +SoundMgr::~SoundMgr() { _mixer->setupPremix(NULL); } -AGIMusic *g_agi_music; - } // End of namespace Agi diff --git a/engines/agi/sound.h b/engines/agi/sound.h index ac7afaafe4..90420ac673 100644 --- a/engines/agi/sound.h +++ b/engines/agi/sound.h @@ -25,7 +25,11 @@ #ifndef AGI_SOUND_H #define AGI_SOUND_H -#include "agi/agi.h" +#include "sound/audiostream.h" + +namespace Audio { +class Mixer; +} // End of namespace Audio namespace Agi { @@ -46,15 +50,6 @@ namespace Agi { #define NUM_CHANNELS 7 /**< number of sound channels */ /** - * AGI engine sound driver structure. - */ -struct sound_driver { - char *description; - int (*init) (int16 * buffer); - void (*deinit) (void); -}; - -/** * AGI sound resource structure. */ struct agi_sound { @@ -102,38 +97,18 @@ struct channel_info { uint32 env; }; -void decode_sound(int); -void unload_sound(int); -void play_sound(void); -int init_sound(void); -void deinit_sound(void); -void start_sound(int, int); -void stop_sound(void); -uint32 mix_sound(void); -int load_instruments(char *fname); - -extern struct sound_driver *snd; - -#endif /* AGI_SOUND_H */ - -} // End of namespace Agi +class AgiEngine; -#include "sound/audiostream.h" +class SoundMgr : public Audio::AudioStream { + AgiEngine *_vm; -namespace Audio { -class Mixer; -} // End of namespace Audio - -namespace Agi { - -class AGIMusic : public Audio::AudioStream { public: - AGIMusic(Audio::Mixer * pMixer); - ~AGIMusic(void); + SoundMgr(AgiEngine *agi, Audio::Mixer *pMixer); + ~SoundMgr(); virtual void setVolume(uint8 volume); // AudioStream API - int readBuffer(int16 * buffer, const int numSamples) { + int readBuffer(int16 *buffer, const int numSamples) { premixerCall(buffer, numSamples / 2); return numSamples; } @@ -152,10 +127,27 @@ public: } private: - Audio::Mixer * _mixer; + Audio::Mixer *_mixer; uint32 _sampleRate; - void premixerCall(int16 * buf, uint len); + void premixerCall(int16 *buf, uint len); + +public: + + void decode_sound(int); + void unload_sound(int); + void play_sound(); + int init_sound(); + void deinit_sound(); + void start_sound(int, int); + void stop_sound(); + void stop_note(int i); + void play_note(int i, int freq, int vol); + void play_agi_sound(); + uint32 mix_sound(); + int load_instruments(char *fname); }; } // End of namespace Agi + +#endif /* AGI_SOUND_H */ diff --git a/engines/agi/sprite.cpp b/engines/agi/sprite.cpp index 4653093c77..333bea2753 100644 --- a/engines/agi/sprite.cpp +++ b/engines/agi/sprite.cpp @@ -46,8 +46,6 @@ struct sprite { uint8 *hires; /**< buffer for hi-res background */ }; -SpritesMan *_sprites; - /* * Sprite pool replaces dynamic allocation */ @@ -57,7 +55,7 @@ SpritesMan *_sprites; #define POOL_SIZE 68000 /* Gold Rush mine room needs > 50000 */ /* Speeder bike challenge needs > 67000 */ -void *SpritesMan::pool_alloc(int size) { +void *SpritesMgr::pool_alloc(int size) { uint8 *x; /* Adjust size to 32-bit boundary to prevent data misalignment @@ -80,7 +78,7 @@ void *SpritesMan::pool_alloc(int size) { /* Note: it's critical that pool_release() is called in the exact reverse order of pool_alloc() */ -void SpritesMan::pool_release(void *s) { +void SpritesMgr::pool_release(void *s) { pool_top = (uint8 *)s; } @@ -90,7 +88,7 @@ void SpritesMan::pool_release(void *s) { /* Blit one pixel considering the priorities */ -void SpritesMan::blit_pixel(uint8 *p, uint8 *end, uint8 col, int spr, int width, int *hidden) { +void SpritesMgr::blit_pixel(uint8 *p, uint8 *end, uint8 col, int spr, int width, int *hidden) { int epr = 0, pr = 0; /* effective and real priorities */ /* CM: priority 15 overrides control lines and is ignored when @@ -138,7 +136,7 @@ void SpritesMan::blit_pixel(uint8 *p, uint8 *end, uint8 col, int spr, int width, #define X_FACT 2 /* Horizontal hires factor */ -int SpritesMan::blit_hires_cel(int x, int y, int spr, view_cel *c) { +int SpritesMgr::blit_hires_cel(int x, int y, int spr, view_cel *c) { uint8 *q = NULL; uint8 *h0, *h, *end; int i, j, t, m, col; @@ -148,9 +146,9 @@ int SpritesMan::blit_hires_cel(int x, int y, int spr, view_cel *c) { t = c->transparency; m = c->mirror; spr <<= 4; - h0 = &game.hires[(x + y * _WIDTH + m * (c->width - 1)) * X_FACT]; + h0 = &_vm->game.hires[(x + y * _WIDTH + m * (c->width - 1)) * X_FACT]; - end = game.hires + _WIDTH * X_FACT * _HEIGHT; + end = _vm->game.hires + _WIDTH * X_FACT * _HEIGHT; for (i = 0; i < c->height; i++) { h = h0; @@ -170,7 +168,7 @@ int SpritesMan::blit_hires_cel(int x, int y, int spr, view_cel *c) { return hidden; } -int SpritesMan::blit_cel(int x, int y, int spr, view_cel *c) { +int SpritesMgr::blit_cel(int x, int y, int spr, view_cel *c) { uint8 *p0, *p, *q = NULL, *end; int i, j, t, m, col; int hidden = true; @@ -185,16 +183,16 @@ int SpritesMan::blit_cel(int x, int y, int spr, view_cel *c) { if (x >= _WIDTH) x = _WIDTH - 1; - if (opt.hires) + if (_vm->opt.hires) blit_hires_cel(x, y, spr, c); q = c->data; t = c->transparency; m = c->mirror; spr <<= 4; - p0 = &game.sbuf[x + y * _WIDTH + m * (c->width - 1)]; + p0 = &_vm->game.sbuf[x + y * _WIDTH + m * (c->width - 1)]; - end = game.sbuf + _WIDTH * _HEIGHT; + end = _vm->game.sbuf + _WIDTH * _HEIGHT; for (i = 0; i < c->height; i++) { p = p0; @@ -214,7 +212,7 @@ int SpritesMan::blit_cel(int x, int y, int spr, view_cel *c) { return hidden; } -void SpritesMan::objs_savearea(sprite *s) { +void SpritesMgr::objs_savearea(sprite *s) { int y; int16 x_pos = s->x_pos, y_pos = s->y_pos; int16 x_size = s->x_size, y_size = s->y_size; @@ -240,9 +238,9 @@ void SpritesMan::objs_savearea(sprite *s) { if (x_size <= 0 || y_size <= 0) return; - p0 = &game.sbuf[x_pos + y_pos * _WIDTH]; + p0 = &_vm->game.sbuf[x_pos + y_pos * _WIDTH]; q = s->buffer; - h0 = &game.hires[(x_pos + y_pos * _WIDTH) * 2]; + h0 = &_vm->game.hires[(x_pos + y_pos * _WIDTH) * 2]; k = s->hires; for (y = 0; y < y_size; y++) { memcpy(q, p0, x_size); @@ -254,7 +252,7 @@ void SpritesMan::objs_savearea(sprite *s) { } } -void SpritesMan::objs_restorearea(sprite *s) { +void SpritesMgr::objs_restorearea(sprite *s) { int y, offset; int16 x_pos = s->x_pos, y_pos = s->y_pos; int16 x_size = s->x_size, y_size = s->y_size; @@ -280,19 +278,19 @@ void SpritesMan::objs_restorearea(sprite *s) { if (x_size <= 0 || y_size <= 0) return; - p0 = &game.sbuf[x_pos + y_pos * _WIDTH]; + p0 = &_vm->game.sbuf[x_pos + y_pos * _WIDTH]; q = s->buffer; - h0 = &game.hires[(x_pos + y_pos * _WIDTH) * 2]; + h0 = &_vm->game.hires[(x_pos + y_pos * _WIDTH) * 2]; k = s->hires; - offset = game.line_min_print * CHAR_LINES; + offset = _vm->game.line_min_print * CHAR_LINES; for (y = 0; y < y_size; y++) { memcpy(p0, q, x_size); - put_pixels_a(x_pos, y_pos + y + offset, x_size, p0); + _gfx->putPixelsA(x_pos, y_pos + y + offset, x_size, p0); q += x_size; p0 += _WIDTH; memcpy(h0, k, x_size * 2); - if (opt.hires) { - put_pixels_hires(x_pos * 2, y_pos + y + offset, x_size * 2, h0); + if (_vm->opt.hires) { + _gfx->putPixelsHires(x_pos * 2, y_pos + y + offset, x_size * 2, h0); } k += x_size * 2; h0 += _WIDTH * 2; @@ -303,9 +301,9 @@ void SpritesMan::objs_restorearea(sprite *s) { /** * Condition to determine whether a sprite will be in the 'updating' list. */ -static bool test_updating(vt_entry *v) { +bool SpritesMgr::test_updating(vt_entry *v, AgiEngine *agi) { /* Sanity check (see bug #779302) */ - if (~game.dir_view[v->current_view].flags & RES_LOADED) + if (~agi->game.dir_view[v->current_view].flags & RES_LOADED) return false; return (v->flags & (ANIMATED | UPDATE | DRAWN)) == (ANIMATED | UPDATE | DRAWN); @@ -314,9 +312,9 @@ static bool test_updating(vt_entry *v) { /** * Condition to determine whether a sprite will be in the 'non-updating' list. */ -static bool test_not_updating(vt_entry *v) { +bool SpritesMgr::test_not_updating(vt_entry *v, AgiEngine *agi) { /* Sanity check (see bug #779302) */ - if (~game.dir_view[v->current_view].flags & RES_LOADED) + if (~agi->game.dir_view[v->current_view].flags & RES_LOADED) return false; return (v->flags & (ANIMATED | UPDATE | DRAWN)) == (ANIMATED | DRAWN); @@ -325,14 +323,14 @@ static bool test_not_updating(vt_entry *v) { /** * Convert sprite priority to y value. */ -INLINE int SpritesMan::prio_to_y(int p) { +INLINE int SpritesMgr::prio_to_y(int p) { int i; if (p == 0) return -1; for (i = 167; i >= 0; i--) { - if (game.pri_table[i] < p) + if (_vm->game.pri_table[i] < p) return i; } @@ -342,7 +340,7 @@ INLINE int SpritesMan::prio_to_y(int p) { /** * Create and initialize a new sprite structure. */ -sprite *SpritesMan::new_sprite(vt_entry *v) { +sprite *SpritesMgr::new_sprite(vt_entry *v) { sprite *s; s = (sprite *)pool_alloc(sizeof(sprite)); if (s == NULL) @@ -363,7 +361,7 @@ sprite *SpritesMan::new_sprite(vt_entry *v) { /** * Insert sprite in the specified sprite list. */ -void SpritesMan::spr_addlist(SpriteList& l, vt_entry *v) { +void SpritesMgr::spr_addlist(SpriteList& l, vt_entry *v) { sprite *s = new_sprite(v); l.push_back(s); } @@ -371,7 +369,7 @@ void SpritesMan::spr_addlist(SpriteList& l, vt_entry *v) { /** * Sort sprites from lower y values to build a sprite list. */ -void SpritesMan::build_list(SpriteList& l, bool (*test) (vt_entry *)) { +void SpritesMgr::build_list(SpriteList& l, bool (*test) (vt_entry *, AgiEngine *)) { int i, j, k; vt_entry *v; vt_entry *entry[0x100]; @@ -382,8 +380,8 @@ void SpritesMan::build_list(SpriteList& l, bool (*test) (vt_entry *)) { * condition and their y values */ i = 0; - for (v = game.view_table; v < &game.view_table[MAX_VIEWTABLE]; v++) { - if ((*test)(v)) { + for (v = _vm->game.view_table; v < &_vm->game.view_table[MAX_VIEWTABLE]; v++) { + if ((*test)(v, _vm)) { entry[i] = v; y_val[i] = v->flags & FIXED_PRIORITY ? prio_to_y(v->priority) : v->y_pos; i++; @@ -410,21 +408,21 @@ void SpritesMan::build_list(SpriteList& l, bool (*test) (vt_entry *)) { /** * Build list of updating sprites. */ -void SpritesMan::build_upd_blitlist() { +void SpritesMgr::build_upd_blitlist() { build_list(spr_upd, test_updating); } /** * Build list of non-updating sprites. */ -void SpritesMan::build_nonupd_blitlist() { +void SpritesMgr::build_nonupd_blitlist() { build_list(spr_nonupd, test_not_updating); } /** * Clear the given sprite list. */ -void SpritesMan::free_list(SpriteList& l) { +void SpritesMgr::free_list(SpriteList& l) { SpriteList::iterator iter; for (iter = l.reverse_begin(); iter != l.end(); ) { sprite* s = *iter; @@ -439,7 +437,7 @@ void SpritesMan::free_list(SpriteList& l) { * Copy sprites from the pic buffer to the screen buffer, and check if * sprites of the given list have moved. */ -void SpritesMan::commit_sprites(SpriteList& l) { +void SpritesMgr::commit_sprites(SpriteList& l) { SpriteList::iterator iter; for (iter = l.begin(); iter != l.end(); ++iter) { sprite *s = *iter; @@ -489,7 +487,7 @@ void SpritesMan::commit_sprites(SpriteList& l) { /** * Erase all sprites in the given list. */ -void SpritesMan::erase_sprites(SpriteList& l) { +void SpritesMgr::erase_sprites(SpriteList& l) { SpriteList::iterator iter; for (iter = l.reverse_begin(); iter != l.end(); --iter) { sprite *s = *iter; @@ -502,7 +500,7 @@ void SpritesMan::erase_sprites(SpriteList& l) { /** * Blit all sprites in the given list. */ -void SpritesMan::blit_sprites(SpriteList& l) { +void SpritesMgr::blit_sprites(SpriteList& l) { int hidden; SpriteList::iterator iter; for (iter = l.begin(); iter != l.end(); ++iter) { @@ -511,7 +509,7 @@ void SpritesMan::blit_sprites(SpriteList& l) { debugC(8, kDebugLevelSprites, "s->v->entry = %d (prio %d)", s->v->entry, s->v->priority); hidden = blit_cel(s->x_pos, s->y_pos, s->v->priority, s->v->cel_data); if (s->v->entry == 0) { /* if ego, update f1 */ - setflag(F_ego_invisible, hidden); + _vm->setflag(F_ego_invisible, hidden); } } } @@ -520,16 +518,16 @@ void SpritesMan::blit_sprites(SpriteList& l) { * Public functions */ -void SpritesMan::commit_upd_sprites() { +void SpritesMgr::commit_upd_sprites() { commit_sprites(spr_upd); } -void SpritesMan::commit_nonupd_sprites() { +void SpritesMgr::commit_nonupd_sprites() { commit_sprites(spr_nonupd); } /* check moves in both lists */ -void SpritesMan::commit_both() { +void SpritesMgr::commit_both() { commit_upd_sprites(); commit_nonupd_sprites(); } @@ -543,7 +541,7 @@ void SpritesMan::commit_both() { * @see erase_nonupd_sprites() * @see erase_both() */ -void SpritesMan::erase_upd_sprites() { +void SpritesMgr::erase_upd_sprites() { erase_sprites(spr_upd); } @@ -556,7 +554,7 @@ void SpritesMan::erase_upd_sprites() { * @see erase_upd_sprites() * @see erase_both() */ -void SpritesMan::erase_nonupd_sprites() { +void SpritesMgr::erase_nonupd_sprites() { erase_sprites(spr_nonupd); } @@ -569,7 +567,7 @@ void SpritesMan::erase_nonupd_sprites() { * @see erase_upd_sprites() * @see erase_nonupd_sprites() */ -void SpritesMan::erase_both() { +void SpritesMgr::erase_both() { erase_upd_sprites(); erase_nonupd_sprites(); } @@ -582,7 +580,7 @@ void SpritesMan::erase_both() { * @see blit_nonupd_sprites() * @see blit_both() */ -void SpritesMan::blit_upd_sprites() { +void SpritesMgr::blit_upd_sprites() { debugC(7, kDebugLevelSprites, "blit updating"); build_upd_blitlist(); blit_sprites(spr_upd); @@ -596,7 +594,7 @@ void SpritesMan::blit_upd_sprites() { * @see blit_upd_sprites() * @see blit_both() */ -void SpritesMan::blit_nonupd_sprites() { +void SpritesMgr::blit_nonupd_sprites() { debugC(7, kDebugLevelSprites, "blit non-updating"); build_nonupd_blitlist(); blit_sprites(spr_nonupd); @@ -610,7 +608,7 @@ void SpritesMan::blit_nonupd_sprites() { * @see blit_upd_sprites() * @see blit_nonupd_sprites() */ -void SpritesMan::blit_both() { +void SpritesMgr::blit_both() { blit_nonupd_sprites(); blit_upd_sprites(); } @@ -628,23 +626,23 @@ void SpritesMan::blit_both() { * @param pri priority to use * @param mar if < 4, create a margin around the the base of the cel */ -void SpritesMan::add_to_pic(int view, int loop, int cel, int x, int y, int pri, int mar) { +void SpritesMgr::add_to_pic(int view, int loop, int cel, int x, int y, int pri, int mar) { view_cel *c = NULL; int x1, y1, x2, y2, y3; uint8 *p1, *p2; debugC(3, kDebugLevelSprites, "v=%d, l=%d, c=%d, x=%d, y=%d, p=%d, m=%d", view, loop, cel, x, y, pri, mar); - record_image_stack_call(ADD_VIEW, view, loop, cel, x, y, pri, mar); + _vm->record_image_stack_call(ADD_VIEW, view, loop, cel, x, y, pri, mar); /* * Was hardcoded to 8, changed to pri_table[y] to fix Gold * Rush (see bug #587558) */ if (pri == 0) - pri = game.pri_table[y]; + pri = _vm->game.pri_table[y]; - c = &game.views[view].loop[loop].cel[cel]; + c = &_vm->game.views[view].loop[loop].cel[cel]; x1 = x; y1 = y - c->height + 1; @@ -685,8 +683,8 @@ void SpritesMan::add_to_pic(int view, int loop, int cel, int x, int y, int pri, // don't let box extend below y. if (y3 > y2) y3 = y2; - p1 = &game.sbuf[x1 + y3 * _WIDTH]; - p2 = &game.sbuf[x2 + y3 * _WIDTH]; + p1 = &_vm->game.sbuf[x1 + y3 * _WIDTH]; + p2 = &_vm->game.sbuf[x2 + y3 * _WIDTH]; for (y = y3; y <= y2; y++) { if ((*p1 >> 4) >= 4) @@ -698,8 +696,8 @@ void SpritesMan::add_to_pic(int view, int loop, int cel, int x, int y, int pri, } debugC(4, kDebugLevelSprites, "pri box: %d %d %d %d (%d)", x1, y3, x2, y2, mar); - p1 = &game.sbuf[x1 + y3 * _WIDTH]; - p2 = &game.sbuf[x1 + y2 * _WIDTH]; + p1 = &_vm->game.sbuf[x1 + y3 * _WIDTH]; + p2 = &_vm->game.sbuf[x1 + y2 * _WIDTH]; for (x = x1; x <= x2; x++) { if ((*p1 >> 4) >= 4) *p1 = (mar << 4) | (*p1 & 0x0f); @@ -722,13 +720,13 @@ void SpritesMan::add_to_pic(int view, int loop, int cel, int x, int y, int pri, * a message box with the object description. * @param n Number of the object to show */ -void SpritesMan::show_obj(int n) { +void SpritesMgr::show_obj(int n) { view_cel *c; sprite s; int x1, y1, x2, y2; - agi_load_resource(rVIEW, n); - if (!(c = &game.views[n].loop[0].cel[0])) + _vm->agiLoadResource(rVIEW, n); + if (!(c = &_vm->game.views[n].loop[0].cel[0])) return; x1 = (_WIDTH - c->width) / 2; @@ -746,7 +744,7 @@ void SpritesMan::show_obj(int n) { objs_savearea(&s); blit_cel(x1, y1, s.x_size, c); commit_block(x1, y1, x2, y2); - _text->message_box(game.views[n].descr); + _vm->message_box(_vm->game.views[n].descr); objs_restorearea(&s); commit_block(x1, y1, x2, y2); @@ -756,12 +754,12 @@ void SpritesMan::show_obj(int n) { free(s.hires); } -void SpritesMan::commit_block(int x1, int y1, int x2, int y2) { +void SpritesMgr::commit_block(int x1, int y1, int x2, int y2) { int i, w, offset; uint8 *q; uint8 *h; - if (!game.picture_shown) + if (!_vm->game.picture_shown) return; /* Clipping */ @@ -785,32 +783,30 @@ void SpritesMan::commit_block(int x1, int y1, int x2, int y2) { debugC(7, kDebugLevelSprites, "%d, %d, %d, %d", x1, y1, x2, y2); w = x2 - x1 + 1; - q = &game.sbuf[x1 + _WIDTH * y1]; - h = &game.hires[(x1 + _WIDTH * y1) * 2]; - offset = game.line_min_print * CHAR_LINES; + q = &_vm->game.sbuf[x1 + _WIDTH * y1]; + h = &_vm->game.hires[(x1 + _WIDTH * y1) * 2]; + offset = _vm->game.line_min_print * CHAR_LINES; for (i = y1; i <= y2; i++) { - put_pixels_a(x1, i + offset, w, q); + _gfx->putPixelsA(x1, i + offset, w, q); q += _WIDTH; - if (opt.hires) { - put_pixels_hires(x1 * 2, i + offset, w * 2, h); + if (_vm->opt.hires) { + _gfx->putPixelsHires(x1 * 2, i + offset, w * 2, h); } h += _WIDTH * 2; } - flush_block_a(x1, y1 + offset, x2, y2 + offset); + _gfx->flushBlockA(x1, y1 + offset, x2, y2 + offset); } -SpritesMan::SpritesMan() { -// if ((sprite_pool = (uint8 *)malloc(POOL_SIZE)) == NULL) -// return err_NotEnoughMemory; +SpritesMgr::SpritesMgr(AgiEngine *agi, GfxMgr *gfx) { + _vm = agi; + _gfx = gfx; sprite_pool = (uint8 *)malloc(POOL_SIZE); pool_top = sprite_pool; - -// return err_OK; } -SpritesMan::~SpritesMan() { +SpritesMgr::~SpritesMgr() { free(sprite_pool); } diff --git a/engines/agi/sprite.h b/engines/agi/sprite.h index 5f65d9e237..ad6318bc07 100644 --- a/engines/agi/sprite.h +++ b/engines/agi/sprite.h @@ -33,8 +33,15 @@ namespace Agi { struct sprite; typedef Common::List<sprite*> SpriteList; -class SpritesMan { +class AgiEngine; +class GfxMgr; +class Obejcts; + +class SpritesMgr { private: + GfxMgr *_gfx; + AgiEngine *_vm; + uint8 *sprite_pool; uint8 *pool_top; @@ -56,17 +63,19 @@ private: 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, bool (*test) (vt_entry *)); + void build_list(SpriteList& l, bool (*test) (vt_entry *, AgiEngine *)); 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); + static bool test_updating(vt_entry *v, AgiEngine *); + static bool test_not_updating(vt_entry *v, AgiEngine *); public: - SpritesMan(); - ~SpritesMan(); + SpritesMgr(AgiEngine *agi, GfxMgr *gfx); + ~SpritesMgr(); int init_sprites(void); void deinit_sprites(void); @@ -84,8 +93,6 @@ public: void commit_block(int, int, int, int); }; -extern SpritesMan *_sprites; - } // End of namespace Agi #endif /* AGI_SPRITE_H */ diff --git a/engines/agi/text.cpp b/engines/agi/text.cpp index 1b93f361cf..10b6d2692d 100644 --- a/engines/agi/text.cpp +++ b/engines/agi/text.cpp @@ -30,9 +30,7 @@ namespace Agi { -TextMan *_text; - -void TextMan::print_text2(int l, const char *msg, int foff, int xoff, int yoff, +void AgiEngine::print_text2(int l, const char *msg, int foff, int xoff, int yoff, int len, int fg, int bg) { int x1, y1; int maxx, minx, ofoff; @@ -49,7 +47,7 @@ void TextMan::print_text2(int l, const char *msg, int foff, int xoff, int yoff, /* FR: strings with len == 1 were not printed */ if (len == 1) { - put_text_character(l, xoff + foff, yoff, *msg, fg, bg); + _gfx->putTextCharacter(l, xoff + foff, yoff, *msg, fg, bg); maxx = 1; minx = 0; ofoff = foff; @@ -75,7 +73,7 @@ void TextMan::print_text2(int l, const char *msg, int foff, int xoff, int yoff, if (xpos >= GFX_WIDTH) continue; - put_text_character(l, xpos, ypos, *m, fg, bg); + _gfx->putTextCharacter(l, xpos, ypos, *m, fg, bg); if (x1 > maxx) maxx = x1; @@ -104,18 +102,18 @@ void TextMan::print_text2(int l, const char *msg, int foff, int xoff, int yoff, minx *= CHAR_COLS; if (update) { - schedule_update(foff + xoff + minx, yoff, ofoff + xoff + maxx + CHAR_COLS - 1, + _gfx->scheduleUpdate(foff + xoff + minx, yoff, ofoff + xoff + maxx + CHAR_COLS - 1, yoff + y1 * CHAR_LINES + CHAR_LINES + 1); /* Making synchronous text updates reduces CPU load * when updating status line and input area */ - do_update(); + _gfx->doUpdate(); } } /* len is in characters, not pixels!! */ -void TextMan::blit_textbox(const char *p, int y, int x, int len) { +void AgiEngine::blit_textbox(const char *p, int y, int x, int len) { /* if x | y = -1, then centre the box */ int xoff, yoff, lin, h, w; char *msg, *m; @@ -163,10 +161,10 @@ void TextMan::blit_textbox(const char *p, int y, int x, int len) { free(msg); - do_update(); + _gfx->doUpdate(); } -void TextMan::erase_textbox() { +void AgiEngine::erase_textbox() { if (!game.window.active) { debugC(3, kDebugLevelText, "no window active"); return; @@ -175,13 +173,13 @@ void TextMan::erase_textbox() { debugC(4, kDebugLevelText, "x1=%d, y1=%d, x2=%d, y2=%d", game.window.x1, game.window.y1, game.window.x2, game.window.y2); - restore_block(game.window.x1, game.window.y1, + _gfx->restoreBlock(game.window.x1, game.window.y1, game.window.x2, game.window.y2, game.window.buffer); free(game.window.buffer); game.window.active = false; - do_update(); + _gfx->doUpdate(); } /* @@ -191,7 +189,7 @@ void TextMan::erase_textbox() { /** * Print text in the AGI engine screen. */ -void TextMan::print_text(const char *msg, int f, int x, int y, int len, int fg, int bg) { +void AgiEngine::print_text(const char *msg, int f, int x, int y, int len, int fg, int bg) { f *= CHAR_COLS; x *= CHAR_COLS; y *= CHAR_LINES; @@ -203,7 +201,7 @@ void TextMan::print_text(const char *msg, int f, int x, int y, int len, int fg, /** * Print text in the AGI engine console. */ -void TextMan::print_text_console(const char *msg, int x, int y, int len, int fg, int bg) { +void AgiEngine::print_text_console(const char *msg, int x, int y, int len, int fg, int bg) { x *= CHAR_COLS; y *= 10; @@ -215,7 +213,7 @@ void TextMan::print_text_console(const char *msg, int x, int y, int len, int fg, * @param str String to wrap. * @param len Length of line. */ -char *TextMan::word_wrap_string(char *str, int *len) { +char *AgiEngine::word_wrap_string(char *str, int *len) { /* If the message has a long word (longer than 31 character) then * loop in line 239 (for (; *v != ' '; v--, c--);) can wrap * around 0 and write large number in c. This causes returned @@ -230,7 +228,7 @@ char *TextMan::word_wrap_string(char *str, int *len) { e = msg + strlen(msg); maxc = 0; - while (42) { + for (;;) { debugC(3, kDebugLevelText, "[%s], %d", msg, maxc); if (strchr(v, ' ') == NULL && (int)strlen(v) > l) { debugC(1, kDebugLevelText | kDebugLevelMain, "Word too long in message"); @@ -277,7 +275,7 @@ char *TextMan::word_wrap_string(char *str, int *len) { /** * Remove existing window, if any. */ -void TextMan::close_window() { +void AgiEngine::close_window() { debugC(4, kDebugLevelText, "close window"); _sprites->erase_both(); erase_textbox(); /* remove window, if any */ @@ -292,7 +290,7 @@ void TextMan::close_window() { * centered in the screen and waits until a key is pressed. * @param p The text to be displayed */ -int TextMan::message_box(const char *s) { +int AgiEngine::message_box(const char *s) { int k; _sprites->erase_both(); @@ -312,7 +310,7 @@ int TextMan::message_box(const char *s) { * @param p The text to be displayed * @param b NULL-terminated list of button labels */ -int TextMan::selection_box(const char *m, const char **b) { +int AgiEngine::selection_box(const char *m, const char **b) { int x, y, i, s; int key, active = 0; int rc = -1; @@ -347,16 +345,16 @@ int TextMan::selection_box(const char *m, const char **b) { _sprites->blit_both(); /* clear key queue */ - while (keypress()) { - get_key(); + while (_gfx->keypress()) { + _gfx->getKey(); } debugC(4, kDebugLevelText, "waiting..."); - while (42) { + for (;;) { for (i = 0; b[i]; i++) - draw_button(bx[i], by[i], b[i], i == active, 0); + _gfx->drawButton(bx[i], by[i], b[i], i == active, 0); - poll_timer(); /* msdos driver -> does nothing */ + _gfx->pollTimer(); /* msdos driver -> does nothing */ key = do_poll_keyboard(); switch (key) { case KEY_ENTER: @@ -367,7 +365,7 @@ int TextMan::selection_box(const char *m, const char **b) { goto getout; case BUTTON_LEFT: for (i = 0; b[i]; i++) { - if (test_button(bx[i], by[i], b[i])) { + if (_gfx->testButton(bx[i], by[i], b[i])) { rc = active = i; goto press; } @@ -379,13 +377,13 @@ int TextMan::selection_box(const char *m, const char **b) { active %= i; break; } - do_update(); + _gfx->doUpdate(); } - press: +press: debugC(4, kDebugLevelText, "Button pressed: %d", rc); - getout: +getout: close_window(); debugC(2, kDebugLevelText, "Result = %d", rc); @@ -395,7 +393,7 @@ int TextMan::selection_box(const char *m, const char **b) { /** * */ -int TextMan::print(const char *p, int lin, int col, int len) { +int AgiEngine::print(const char *p, int lin, int col, int len) { if (p == NULL) return 0; @@ -451,17 +449,13 @@ int TextMan::print(const char *p, int lin, int col, int len) { /** * */ -void TextMan::print_status(const char *message, ...) { +void AgiEngine::print_status(const char *message, ...) { char x[42]; va_list args; va_start(args, message); -#ifdef HAVE_VSNPRINTF - vsnprintf(x, 41, message, args); -#else vsprintf(x, message, args); -#endif va_end(args); @@ -469,7 +463,7 @@ void TextMan::print_status(const char *message, ...) { print_text(x, 0, 0, game.line_status, 40, STATUS_FG, STATUS_BG); } -char *TextMan::safe_strcat(char *s, const char *t) { +char *AgiEngine::safe_strcat(char *s, const char *t) { if (t != NULL) strcat(s, t); @@ -484,7 +478,7 @@ char *TextMan::safe_strcat(char *s, const char *t) { * @param n logic number */ #define MAX_LEN 768 -char *TextMan::agi_sprintf(const char *s) { +char *AgiEngine::agi_sprintf(const char *s) { static char y[MAX_LEN]; char x[MAX_LEN]; char z[16], *p; @@ -555,7 +549,7 @@ char *TextMan::agi_sprintf(const char *s) { break; default: - literal: +literal: assert(p < x + MAX_LEN); *p++ = *s++; *p = 0; @@ -570,14 +564,14 @@ char *TextMan::agi_sprintf(const char *s) { /** * Write the status line. */ -void TextMan::write_status() { +void AgiEngine::write_status() { char x[64]; - if (debug_.statusline) { + if (_debug.statusline) { print_status("%3d(%03d) %3d,%3d(%3d,%3d) ", getvar(0), getvar(1), game.view_table[0].x_pos, - game.view_table[0].y_pos, WIN_TO_PIC_X(mouse.x), - WIN_TO_PIC_Y(mouse.y)); + game.view_table[0].y_pos, WIN_TO_PIC_X(g_mouse.x), + WIN_TO_PIC_Y(g_mouse.y)); return; } @@ -595,7 +589,7 @@ void TextMan::write_status() { /** * Print user input prompt. */ -void TextMan::write_prompt() { +void AgiEngine::write_prompt() { int l, fg, bg, pos; if (!game.input_enabled || game.input_mode != INPUT_NORMAL) @@ -612,10 +606,10 @@ void TextMan::write_prompt() { debugC(4, kDebugLevelText, "prompt = '%s'", agi_sprintf(game.strings[0])); print_text(game.strings[0], 0, 0, l, 1, fg, bg); print_text((char *)game.input_buffer, 0, 1, l, pos + 1, fg, bg); - print_character(pos + 1, l, game.cursor_char, fg, bg); + _gfx->printCharacter(pos + 1, l, game.cursor_char, fg, bg); flush_lines(l, l); - do_update(); + _gfx->doUpdate(); } /** @@ -624,7 +618,7 @@ void TextMan::write_prompt() { * @param l2 end line * @param c color */ -void TextMan::clear_lines(int l1, int l2, int c) { +void AgiEngine::clear_lines(int l1, int l2, int c) { /* do we need to adjust for +8 on topline? * inc for endline so it matches the correct num * ie, from 22 to 24 is 3 lines, not 2 lines. @@ -634,34 +628,34 @@ void TextMan::clear_lines(int l1, int l2, int c) { l2 *= CHAR_LINES; l2 += CHAR_LINES - 1; - draw_rectangle(0, l1, GFX_WIDTH - 1, l2, c); + _gfx->drawRectangle(0, l1, GFX_WIDTH - 1, l2, c); } /** * */ -void TextMan::flush_lines(int l1, int l2) { +void AgiEngine::flush_lines(int l1, int l2) { l1 *= CHAR_LINES; l2 *= CHAR_LINES; l2 += CHAR_LINES - 1; - flush_block(0, l1, GFX_WIDTH - 1, l2); + _gfx->flushBlock(0, l1, GFX_WIDTH - 1, l2); } /** * */ -void TextMan::draw_window(int x1, int y1, int x2, int y2) { +void AgiEngine::draw_window(int x1, int y1, int x2, int y2) { game.window.active = true; game.window.x1 = x1; game.window.y1 = y1; game.window.x2 = x2; game.window.y2 = y2; - game.window.buffer = (uint8 *) malloc((x2 - x1 + 1) * (y2 - y1 + 1)); + game.window.buffer = (uint8 *)malloc((x2 - x1 + 1) * (y2 - y1 + 1)); debugC(4, kDebugLevelText, "x1=%d, y1=%d, x2=%d, y2=%d", x1, y1, x2, y2); - save_block(x1, y1, x2, y2, game.window.buffer); - draw_box(x1, y1, x2, y2, MSG_BOX_COLOUR, MSG_BOX_LINE, 2); + _gfx->saveBlock(x1, y1, x2, y2, game.window.buffer); + _gfx->drawBox(x1, y1, x2, y2, MSG_BOX_COLOUR, MSG_BOX_LINE, 2); } } // End of namespace Agi diff --git a/engines/agi/text.h b/engines/agi/text.h index 3fbcce1289..5c3d5144dc 100644 --- a/engines/agi/text.h +++ b/engines/agi/text.h @@ -22,68 +22,3 @@ * */ -#ifndef AGI_TEXT_H -#define AGI_TEXT_H - -#include "agi/agi.h" -#include "common/hash-str.h" - -namespace Agi { - -#define MAXWORDLEN 24 - -typedef Common::String String; - -class TextMan { -public: - int message_box(const char *); - int selection_box(const char *, const char **); - void close_window(void); - void draw_window(int, int, int, int); - void print_text(const char *, int, int, int, int, int, int); - void print_text_console(const char *, int, int, int, int, int); - int print(const char *, int, int, int); - char *word_wrap_string(char *, int *); - char *agi_sprintf(const char *); - void write_status(void); - void write_prompt(void); - void clear_lines(int, int, int); - void flush_lines(int, int); - bool predictiveDialog(void); - -private: - void print_status(const char *message, ...); - void print_text2(int l, const char *msg, int foff, int xoff, int yoff, int len, int fg, int bg); - void blit_textbox(const char *p, int y, int x, int len); - void erase_textbox(); - char *safe_strcat(char *s, const char *t); - - void loadDict(void); - - bool matchWord(void); - -private: - typedef Common::HashMap<String, String, Common::CaseSensitiveString_Hash, Common::CaseSensitiveString_EqualTo> DictMap; - - DictMap _dict; - Common::StringList _dictKeys; - - String _currentCode; - String _currentWord; - String _matchedWord; - - int _wordNumber; - - uint _wordPosition; - - bool _nextIsActive; - bool _addIsActive; - -public: - char _predictiveResult[40]; -}; - -extern TextMan *_text; -} // End of namespace Agi - -#endif /* AGI_TEXT_H */ diff --git a/engines/agi/view.cpp b/engines/agi/view.cpp index 24eeda7e13..cdb98bd45e 100644 --- a/engines/agi/view.cpp +++ b/engines/agi/view.cpp @@ -27,7 +27,7 @@ namespace Agi { -static void _set_cel(vt_entry *v, int n) { +void AgiEngine::_set_cel(vt_entry *v, int n) { view_loop *current_vl; view_cel *current_vc; @@ -42,7 +42,7 @@ static void _set_cel(vt_entry *v, int n) { return; if (!(v->flags & UPDATE) - && (agi_get_release() >= 0x3000)) + && (agiGetRelease() >= 0x3000)) return; current_vc = ¤t_vl->cel[n]; @@ -51,7 +51,7 @@ static void _set_cel(vt_entry *v, int n) { v->y_size = current_vc->height; } -static void _set_loop(vt_entry *v, int n) { +void AgiEngine::_set_loop(vt_entry *v, int n) { view_loop *current_vl; debugC(7, kDebugLevelResources, "vt entry #%d, loop = %d", v->entry, n); @@ -68,13 +68,13 @@ static void _set_loop(vt_entry *v, int n) { if (v->current_cel >= v->num_cels) v->current_cel = 0; - if (!(v->flags & UPDATE) && (agi_get_release() >= 0x3000)) + if (!(v->flags & UPDATE) && (agiGetRelease() >= 0x3000)) return; v->loop_data = &game.views[v->current_view].loop[n]; } -static void update_view(vt_entry *v) { +void AgiEngine::update_view(vt_entry *v) { int cel, last_cel; if (v->flags & DONTUPDATE) { @@ -133,7 +133,7 @@ static void update_view(vt_entry *v) { * and fills the corresponding views array element. * @param n number of view resource to decode */ -int decode_view(int n) { +int AgiEngine::decode_view(int n) { int loop, cel; uint8 *v, *lptr; uint16 lofs, cofs; @@ -204,7 +204,7 @@ int decode_view(int n) { * Unloads all data in a view resource * @param n number of view resource */ -void unload_view(int n) { +void AgiEngine::unload_view(int n) { int x; debugC(5, kDebugLevelResources, "discard view %d", n); @@ -231,7 +231,7 @@ void unload_view(int n) { * @param v pointer to view table entry * @param n number of cel */ -void set_cel(vt_entry *v, int n) { +void AgiEngine::set_cel(vt_entry *v, int n) { assert(v->view_data != NULL); assert(v->num_cels >= n); @@ -257,7 +257,7 @@ void set_cel(vt_entry *v, int n) { * @param v pointer to view table entry * @param n number of loop */ -void set_loop(vt_entry *v, int n) { +void AgiEngine::set_loop(vt_entry *v, int n) { assert(v->view_data != NULL); assert(v->num_loops >= n); _set_loop(v, n); @@ -269,7 +269,7 @@ void set_loop(vt_entry *v, int n) { * @param v pointer to view table entry * @param n number of AGI view resource */ -void set_view(vt_entry *v, int n) { +void AgiEngine::set_view(vt_entry *v, int n) { v->view_data = &game.views[n]; v->current_view = n; v->num_loops = v->view_data->num_loops; @@ -280,7 +280,7 @@ void set_view(vt_entry *v, int n) { * Set the view table entry as updating. * @param v pointer to view table entry */ -void start_update(vt_entry *v) { +void AgiEngine::start_update(vt_entry *v) { if (~v->flags & UPDATE) { _sprites->erase_both(); v->flags |= UPDATE; @@ -292,7 +292,7 @@ void start_update(vt_entry *v) { * Set the view table entry as non-updating. * @param v pointer to view table entry */ -void stop_update(vt_entry *v) { +void AgiEngine::stop_update(vt_entry *v) { if (v->flags & UPDATE) { _sprites->erase_both(); v->flags &= ~UPDATE; @@ -316,7 +316,7 @@ static int loop_table_4[] = { * This function is called at the end of each interpreter cycle * to update the view table entries and blit the sprites. */ -void update_viewtable() { +void AgiEngine::update_viewtable() { vt_entry *v; int i, loop; @@ -340,7 +340,7 @@ void update_viewtable() { break; default: /* for KQ4 */ - if (agi_get_release() == 0x3086) + if (agiGetRelease() == 0x3086) loop = loop_table_4[v->direction]; break; } @@ -348,7 +348,7 @@ void update_viewtable() { /* AGI 2.272 (ddp, xmas) doesn't test step_time_count! */ if (loop != 4 && loop != v->current_loop) { - if (agi_get_release() <= 0x2272 || + if (agiGetRelease() <= 0x2272 || v->step_time_count == 1) { set_loop(v, loop); } @@ -375,7 +375,7 @@ void update_viewtable() { } } -bool is_ego_view(const vt_entry* v) { +bool AgiEngine::is_ego_view(const vt_entry* v) { return v == game.view_table; } diff --git a/engines/agi/view.h b/engines/agi/view.h index 893e8bc970..8671c65d04 100644 --- a/engines/agi/view.h +++ b/engines/agi/view.h @@ -25,6 +25,9 @@ #ifndef AGI_VIEW_H #define AGI_VIEW_H +#include "common/stdafx.h" +#include "common/scummsys.h" + namespace Agi { struct view_cel { @@ -117,28 +120,6 @@ struct vt_entry { uint8 parm4; }; /* struct vt_entry */ -/* Motion */ -void check_all_motions(void); -void move_obj(vt_entry *); -void in_destination(vt_entry *); -void fix_position(int); -void update_position(void); - -/* View table management */ -void set_cel(vt_entry *, int); -void set_loop(vt_entry *, int); -void set_view(vt_entry *, int); -void start_update(vt_entry *); -void stop_update(vt_entry *); -void update_viewtable(void); - -void unload_view(int); -int decode_view(int); -void add_to_pic(int, int, int, int, int, int, int); -void draw_obj(int); - -bool is_ego_view(const vt_entry *v); - } // End of namespace Agi #endif /* AGI_VIEW_H */ diff --git a/engines/agi/words.cpp b/engines/agi/words.cpp index 43f049cda3..e9279e6a1d 100644 --- a/engines/agi/words.cpp +++ b/engines/agi/words.cpp @@ -44,7 +44,7 @@ static char *my_strndup(char *src, int n) { return tmp; } -int load_words(const char *fname) { +int AgiEngine::load_words(const char *fname) { Common::File fp; uint32 flen; uint8 *mem = NULL; @@ -75,7 +75,7 @@ int load_words(const char *fname) { return err_OK; } -void unload_words() { +void AgiEngine::unload_words() { if (words != NULL) { free(words); words = NULL; @@ -89,7 +89,7 @@ void unload_words() { * * Thomas Åkesson, November 2001 */ -int find_word(char *word, int *flen) { +int AgiEngine::find_word(char *word, int *flen) { int mchr = 0; /* matched chars */ int len, fchr, id = -1; uint8 *p = words; @@ -140,7 +140,7 @@ int find_word(char *word, int *flen) { return id; } -void dictionary_words(char *msg) { +void AgiEngine::dictionary_words(char *msg) { char *p = NULL; char *q = NULL; int wid, wlen; |