diff options
Diffstat (limited to 'engines/agi/op_cmd.cpp')
-rw-r--r-- | engines/agi/op_cmd.cpp | 1432 |
1 files changed, 717 insertions, 715 deletions
diff --git a/engines/agi/op_cmd.cpp b/engines/agi/op_cmd.cpp index d7e3ba416c..a60080186c 100644 --- a/engines/agi/op_cmd.cpp +++ b/engines/agi/op_cmd.cpp @@ -43,221 +43,201 @@ 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_gfx g_agi->_gfx -#define g_picture g_agi->_picture +#define ip _curLogic->cIP +#define vt _game.viewTable[p0] +#define vt_v _game.viewTable[_game.vars[p0]] -#define ip curLogic->cIP -#define vt game.viewTable[p0] -#define vt_v game.viewTable[game.vars[p0]] +#define _v _game.vars -static struct AgiLogic *curLogic; - -int timerHack; // Workaround for timer loop in MH1 - -#define _v game.vars -#define cmd(x) static void cmd_##x (AgiEngine *g_agi, uint8 *p) - -cmd(increment) { +void AgiEngine::cmd_increment(uint8 *p) { if (_v[p0] != 0xff) ++_v[p0]; } -cmd(decrement) { +void AgiEngine::cmd_decrement(uint8 *p) { if (_v[p0] != 0) --_v[p0]; } -cmd(assignn) { +void AgiEngine::cmd_assignn(uint8 *p) { _v[p0] = p1; - // WORKAROUND for a bug in fan game "Get outta SQ" + // WORKAROUND for a bug in fan _game "Get outta SQ" // Total number of points is stored in variable 7, which - // is then incorrectly assigned to 0. Thus, when the game + // is then incorrectly assigned to 0. Thus, when the _game // is restarted, "Points 0 of 0" is shown. We set the // variable to the correct value here // Fixes bug #1942476 - "AGI: Fan(Get Outta SQ) - Score // is lost on restart" - if (g_agi->getGameID() == GID_GETOUTTASQ && p0 == 7) + if (getGameID() == GID_GETOUTTASQ && p0 == 7) _v[p0] = 8; } -cmd(addn) { +void AgiEngine::cmd_addn(uint8 *p) { _v[p0] += p1; } -cmd(subn) { +void AgiEngine::cmd_subn(uint8 *p) { _v[p0] -= p1; } -cmd(assignv) { +void AgiEngine::cmd_assignv(uint8 *p) { _v[p0] = _v[p1]; } -cmd(addv) { +void AgiEngine::cmd_addv(uint8 *p) { _v[p0] += _v[p1]; } -cmd(subv) { +void AgiEngine::cmd_subv(uint8 *p) { _v[p0] -= _v[p1]; } -cmd(mul_n) { +void AgiEngine::cmd_mul_n(uint8 *p) { _v[p0] *= p1; } -cmd(mul_v) { +void AgiEngine::cmd_mul_v(uint8 *p) { _v[p0] *= _v[p1]; } -cmd(div_n) { +void AgiEngine::cmd_div_n(uint8 *p) { _v[p0] /= p1; } -cmd(div_v) { +void AgiEngine::cmd_div_v(uint8 *p) { _v[p0] /= _v[p1]; } -cmd(random) { - _v[p2] = g_agi->_rnd->getRandomNumber(p1 - p0) + p0; +void AgiEngine::cmd_random(uint8 *p) { + _v[p2] = _rnd->getRandomNumber(p1 - p0) + p0; } -cmd(lindirectn) { +void AgiEngine::cmd_lindirectn(uint8 *p) { _v[_v[p0]] = p1; } -cmd(lindirectv) { +void AgiEngine::cmd_lindirectv(uint8 *p) { _v[_v[p0]] = _v[p1]; } -cmd(rindirect) { +void AgiEngine::cmd_rindirect(uint8 *p) { _v[p0] = _v[_v[p1]]; } -cmd(set) { - g_agi->setflag(*p, true); +void AgiEngine::cmd_set(uint8 *p) { + setflag(*p, true); } -cmd(reset) { - g_agi->setflag(*p, false); +void AgiEngine::cmd_reset(uint8 *p) { + setflag(*p, false); } -cmd(toggle) { - g_agi->setflag(*p, !g_agi->getflag(*p)); +void AgiEngine::cmd_toggle(uint8 *p) { + setflag(*p, !getflag(*p)); } -cmd(set_v) { - g_agi->setflag(_v[p0], true); +void AgiEngine::cmd_set_v(uint8 *p) { + setflag(_v[p0], true); } -cmd(reset_v) { - g_agi->setflag(_v[p0], false); +void AgiEngine::cmd_reset_v(uint8 *p) { + setflag(_v[p0], false); } -cmd(toggle_v) { - g_agi->setflag(_v[p0], !g_agi->getflag(_v[p0])); +void AgiEngine::cmd_toggle_v(uint8 *p) { + setflag(_v[p0], !getflag(_v[p0])); } -cmd(new_room) { - g_agi->newRoom(p0); +void AgiEngine::cmd_new_room(uint8 *p) { + newRoom(p0); // WORKAROUND: Works around intro skipping bug (#1737343) in Gold Rush. // Intro was skipped because the enter-keypress finalizing the entering // of the copy protection string (Copy protection is in logic.128) was // left over to the intro scene (Starts with room 73 i.e. logic.073). // The intro scene checks for any keys pressed and if it finds any it - // jumps to the game's start (Room 1 i.e. logic.001). We clear the + // jumps to the _game's start (Room 1 i.e. logic.001). We clear the // keyboard buffer when the intro sequence's first room (Room 73) is // loaded so that no keys from the copy protection scene can be left - // over to cause the intro to skip to the game's start. - if (g_agi->getGameID() == GID_GOLDRUSH && p0 == 73) - game.keypress = 0; + // over to cause the intro to skip to the _game's start. + if (getGameID() == GID_GOLDRUSH && p0 == 73) + _game.keypress = 0; } -cmd(new_room_f) { - g_agi->newRoom(_v[p0]); +void AgiEngine::cmd_new_room_f(uint8 *p) { + newRoom(_v[p0]); } -cmd(load_view) { - g_agi->agiLoadResource(rVIEW, p0); +void AgiEngine::cmd_load_view(uint8 *p) { + agiLoadResource(rVIEW, p0); } -cmd(load_logic) { - g_agi->agiLoadResource(rLOGIC, p0); +void AgiEngine::cmd_load_logic(uint8 *p) { + agiLoadResource(rLOGIC, p0); } -cmd(load_sound) { - g_agi->agiLoadResource(rSOUND, p0); +void AgiEngine::cmd_load_sound(uint8 *p) { + agiLoadResource(rSOUND, p0); } -cmd(load_view_f) { - g_agi->agiLoadResource(rVIEW, _v[p0]); +void AgiEngine::cmd_load_view_f(uint8 *p) { + agiLoadResource(rVIEW, _v[p0]); } -cmd(load_logic_f) { - g_agi->agiLoadResource(rLOGIC, _v[p0]); +void AgiEngine::cmd_load_logic_f(uint8 *p) { + agiLoadResource(rLOGIC, _v[p0]); } -cmd(discard_view) { - g_agi->agiUnloadResource(rVIEW, p0); +void AgiEngine::cmd_discard_view(uint8 *p) { + agiUnloadResource(rVIEW, p0); } -cmd(object_on_anything) { +void AgiEngine::cmd_object_on_anything(uint8 *p) { vt.flags &= ~(ON_WATER | ON_LAND); } -cmd(object_on_land) { - debugC(4, kDebugLevelScripts, "p0 = %d", p0); +void AgiEngine::cmd_object_on_land(uint8 *p) { vt.flags |= ON_LAND; } -cmd(object_on_water) { - debugC(4, kDebugLevelScripts, "p0 = %d", p0); +void AgiEngine::cmd_object_on_water(uint8 *p) { vt.flags |= ON_WATER; } -cmd(observe_horizon) { - debugC(4, kDebugLevelScripts, "p0 = %d", p0); +void AgiEngine::cmd_observe_horizon(uint8 *p) { vt.flags &= ~IGNORE_HORIZON; } -cmd(ignore_horizon) { - debugC(4, kDebugLevelScripts, "p0 = %d", p0); +void AgiEngine::cmd_ignore_horizon(uint8 *p) { vt.flags |= IGNORE_HORIZON; } -cmd(observe_objs) { - debugC(4, kDebugLevelScripts, "p0 = %d", p0); +void AgiEngine::cmd_observe_objs(uint8 *p) { vt.flags &= ~IGNORE_OBJECTS; } -cmd(ignore_objs) { - debugC(4, kDebugLevelScripts, "p0 = %d", p0); +void AgiEngine::cmd_ignore_objs(uint8 *p) { vt.flags |= IGNORE_OBJECTS; } -cmd(observe_blocks) { - debugC(4, kDebugLevelScripts, "p0 = %d", p0); +void AgiEngine::cmd_observe_blocks(uint8 *p) { vt.flags &= ~IGNORE_BLOCKS; } -cmd(ignore_blocks) { - debugC(4, kDebugLevelScripts, "p0 = %d", p0); +void AgiEngine::cmd_ignore_blocks(uint8 *p) { vt.flags |= IGNORE_BLOCKS; } -cmd(set_horizon) { - debugC(4, kDebugLevelScripts, "p0 = %d", p0); - game.horizon = p0; +void AgiEngine::cmd_set_horizon(uint8 *p) { + _game.horizon = p0; } -cmd(get_priority) { +void AgiEngine::cmd_get_priority(uint8 *p) { _v[p1] = vt.priority; } -cmd(set_priority) { +void AgiEngine::cmd_set_priority(uint8 *p) { vt.flags |= FIXED_PRIORITY; vt.priority = p1; @@ -268,259 +248,256 @@ cmd(set_priority) { // It seems that in this scene, ego's priority is set to 8, but the priority of // the last dwarf with the soup bowls (view 152) is also set to 8, which causes // the dwarf to be drawn behind ego - // With this workaround, when the game scripts set the priority of view 152 + // With this workaround, when the _game scripts set the priority of view 152 // (seventh dwarf with soup bowls), ego's priority is set to 7 - // The game script itself sets priotity 8 for ego before she starts walking, + // The _game script itself sets priotity 8 for ego before she starts walking, // and then releases the fixed priority set on ego after ego is seated // Therefore, this workaround only affects that specific part of this scene // Ego is set to object 19 by script 54 - if (g_agi->getGameID() == GID_KQ4 && vt.currentView == 152) { - game.viewTable[19].flags |= FIXED_PRIORITY; - game.viewTable[19].priority = 7; + if (getGameID() == GID_KQ4 && vt.currentView == 152) { + _game.viewTable[19].flags |= FIXED_PRIORITY; + _game.viewTable[19].priority = 7; } } -cmd(set_priority_f) { +void AgiEngine::cmd_set_priority_f(uint8 *p) { vt.flags |= FIXED_PRIORITY; vt.priority = _v[p1]; } -cmd(release_priority) { +void AgiEngine::cmd_release_priority(uint8 *p) { vt.flags &= ~FIXED_PRIORITY; } -cmd(set_upper_left) { // do nothing (AGI 2.917) +void AgiEngine::cmd_set_upper_left(uint8 *p) { // do nothing (AGI 2.917) } -cmd(start_update) { - g_agi->startUpdate(&vt); +void AgiEngine::cmd_start_update(uint8 *p) { + startUpdate(&vt); } -cmd(stop_update) { - g_agi->stopUpdate(&vt); +void AgiEngine::cmd_stop_update(uint8 *p) { + stopUpdate(&vt); } -cmd(current_view) { +void AgiEngine::cmd_current_view(uint8 *p) { _v[p1] = vt.currentView; } -cmd(current_cel) { +void AgiEngine::cmd_current_cel(uint8 *p) { _v[p1] = vt.currentCel; debugC(4, kDebugLevelScripts, "v%d=%d", p1, _v[p1]); } -cmd(current_loop) { +void AgiEngine::cmd_current_loop(uint8 *p) { _v[p1] = vt.currentLoop; } -cmd(last_cel) { +void AgiEngine::cmd_last_cel(uint8 *p) { _v[p1] = vt.loopData->numCels - 1; } -cmd(set_cel) { - g_agi->setCel(&vt, p1); +void AgiEngine::cmd_set_cel(uint8 *p) { + setCel(&vt, p1); vt.flags &= ~DONTUPDATE; } -cmd(set_cel_f) { - g_agi->setCel(&vt, _v[p1]); +void AgiEngine::cmd_set_cel_f(uint8 *p) { + setCel(&vt, _v[p1]); vt.flags &= ~DONTUPDATE; } -cmd(set_view) { - debugC(4, kDebugLevelScripts, "o%d, %d", p0, p1); - g_agi->setView(&vt, p1); +void AgiEngine::cmd_set_view(uint8 *p) { + setView(&vt, p1); } -cmd(set_view_f) { - g_agi->setView(&vt, _v[p1]); +void AgiEngine::cmd_set_view_f(uint8 *p) { + setView(&vt, _v[p1]); } -cmd(set_loop) { - g_agi->setLoop(&vt, p1); +void AgiEngine::cmd_set_loop(uint8 *p) { + setLoop(&vt, p1); } -cmd(set_loop_f) { - g_agi->setLoop(&vt, _v[p1]); +void AgiEngine::cmd_set_loop_f(uint8 *p) { + setLoop(&vt, _v[p1]); } -cmd(number_of_loops) { +void AgiEngine::cmd_number_of_loops(uint8 *p) { _v[p1] = vt.numLoops; } -cmd(fix_loop) { +void AgiEngine::cmd_fix_loop(uint8 *p) { vt.flags |= FIX_LOOP; } -cmd(release_loop) { +void AgiEngine::cmd_release_loop(uint8 *p) { vt.flags &= ~FIX_LOOP; } -cmd(step_size) { +void AgiEngine::cmd_step_size(uint8 *p) { vt.stepSize = _v[p1]; } -cmd(step_time) { +void AgiEngine::cmd_step_time(uint8 *p) { vt.stepTime = vt.stepTimeCount = _v[p1]; } -cmd(cycle_time) { +void AgiEngine::cmd_cycle_time(uint8 *p) { vt.cycleTime = vt.cycleTimeCount = _v[p1]; } -cmd(stop_cycling) { +void AgiEngine::cmd_stop_cycling(uint8 *p) { vt.flags &= ~CYCLING; } -cmd(start_cycling) { +void AgiEngine::cmd_start_cycling(uint8 *p) { vt.flags |= CYCLING; } -cmd(normal_cycle) { +void AgiEngine::cmd_normal_cycle(uint8 *p) { vt.cycle = CYCLE_NORMAL; vt.flags |= CYCLING; } -cmd(reverse_cycle) { +void AgiEngine::cmd_reverse_cycle(uint8 *p) { vt.cycle = CYCLE_REVERSE; vt.flags |= CYCLING; } -cmd(set_dir) { +void AgiEngine::cmd_set_dir(uint8 *p) { vt.direction = _v[p1]; } -cmd(get_dir) { +void AgiEngine::cmd_get_dir(uint8 *p) { _v[p1] = vt.direction; } -cmd(get_room_f) { - _v[p1] = g_agi->objectGetLocation(_v[p0]); +void AgiEngine::cmd_get_room_f(uint8 *p) { + _v[p1] = objectGetLocation(_v[p0]); } -cmd(put) { - g_agi->objectSetLocation(p0, _v[p1]); +void AgiEngine::cmd_put(uint8 *p) { + objectSetLocation(p0, _v[p1]); } -cmd(put_f) { - g_agi->objectSetLocation(_v[p0], _v[p1]); +void AgiEngine::cmd_put_f(uint8 *p) { + objectSetLocation(_v[p0], _v[p1]); } -cmd(drop) { - g_agi->objectSetLocation(p0, 0); +void AgiEngine::cmd_drop(uint8 *p) { + objectSetLocation(p0, 0); } -cmd(get) { - g_agi->objectSetLocation(p0, EGO_OWNED); +void AgiEngine::cmd_get(uint8 *p) { + objectSetLocation(p0, EGO_OWNED); } -cmd(get_f) { - g_agi->objectSetLocation(_v[p0], EGO_OWNED); +void AgiEngine::cmd_get_f(uint8 *p) { + objectSetLocation(_v[p0], EGO_OWNED); } -cmd(word_to_string) { - strcpy(game.strings[p0], game.egoWords[p1].word); +void AgiEngine::cmd_word_to_string(uint8 *p) { + strcpy(_game.strings[p0], _game.egoWords[p1].word); } -cmd(open_dialogue) { - debugC(4, kDebugLevelScripts, "p0 = %d", p0); - game.hasWindow = true; +void AgiEngine::cmd_open_dialogue(uint8 *p) { + _game.hasWindow = true; } -cmd(close_dialogue) { - debugC(4, kDebugLevelScripts, "p0 = %d", p0); - game.hasWindow = false; +void AgiEngine::cmd_close_dialogue(uint8 *p) { + _game.hasWindow = false; } -cmd(close_window) { - g_agi->closeWindow(); +void AgiEngine::cmd_close_window(uint8 *p) { + closeWindow(); } -cmd(status_line_on) { - game.statusLine = true; - g_agi->writeStatus(); +void AgiEngine::cmd_status_line_on(uint8 *p) { + _game.statusLine = true; + writeStatus(); } -cmd(status_line_off) { - game.statusLine = false; - g_agi->writeStatus(); +void AgiEngine::cmd_status_line_off(uint8 *p) { + _game.statusLine = false; + writeStatus(); } -cmd(show_obj) { - g_sprites->showObj(p0); +void AgiEngine::cmd_show_obj(uint8 *p) { + _sprites->showObj(p0); } -cmd(show_obj_v) { - g_sprites->showObj(_v[p0]); +void AgiEngine::cmd_show_obj_v(uint8 *p) { + _sprites->showObj(_v[p0]); } -cmd(sound) { - g_sound->startSound(p0, p1); +void AgiEngine::cmd_sound(uint8 *p) { + _sound->startSound(p0, p1); } -cmd(stop_sound) { - g_sound->stopSound(); +void AgiEngine::cmd_stop_sound(uint8 *p) { + _sound->stopSound(); } -cmd(menu_input) { - g_agi->newInputMode(INPUT_MENU); +void AgiEngine::cmd_menu_input(uint8 *p) { + newInputMode(INPUT_MENU); } -cmd(enable_item) { - g_agi->_menu->setItem(p0, true); +void AgiEngine::cmd_enable_item(uint8 *p) { + _menu->setItem(p0, true); } -cmd(disable_item) { - g_agi->_menu->setItem(p0, false); +void AgiEngine::cmd_disable_item(uint8 *p) { + _menu->setItem(p0, false); } -cmd(submit_menu) { - g_agi->_menu->submit(); +void AgiEngine::cmd_submit_menu(uint8 *p) { + _menu->submit(); } -cmd(set_scan_start) { - curLogic->sIP = curLogic->cIP; +void AgiEngine::cmd_set_scan_start(uint8 *p) { + _curLogic->sIP = _curLogic->cIP; } -cmd(reset_scan_start) { - curLogic->sIP = 2; +void AgiEngine::cmd_reset_scan_start(uint8 *p) { + _curLogic->sIP = 2; } -cmd(save_game) { - game.simpleSave ? g_agi->saveGameSimple() : g_agi->saveGameDialog(); +void AgiEngine::cmd_save_game(uint8 *p) { + _game.simpleSave ? saveGameSimple() : saveGameDialog(); } -cmd(load_game) { +void AgiEngine::cmd_load_game(uint8 *p) { assert(1); - game.simpleSave ? g_agi->loadGameSimple() : g_agi->loadGameDialog(); + _game.simpleSave ? loadGameSimple() : loadGameDialog(); } -cmd(init_disk) { // do nothing +void AgiEngine::cmd_init_disk(uint8 *p) { // do nothing } -cmd(log) { // do nothing +void AgiEngine::cmd_log(uint8 *p) { // do nothing } -cmd(trace_on) { // do nothing +void AgiEngine::cmd_trace_on(uint8 *p) { // do nothing } -cmd(trace_info) { // do nothing +void AgiEngine::cmd_trace_info(uint8 *p) { // do nothing } -cmd(show_mem) { - g_agi->messageBox("Enough memory"); +void AgiEngine::cmd_show_mem(uint8 *p) { + messageBox("Enough memory"); } -cmd(init_joy) { // do nothing +void AgiEngine::cmd_init_joy(uint8 *p) { // do nothing } -cmd(script_size) { +void AgiEngine::cmd_script_size(uint8 *p) { report("script.size(%d)\n", p0); } -cmd(cancel_line) { - g_agi->_game.inputBuffer[0] = 0; - g_agi->writePrompt(); +void AgiEngine::cmd_cancel_line(uint8 *p) { + _game.inputBuffer[0] = 0; + writePrompt(); } // This implementation is based on observations of Amiga's Gold Rush. @@ -533,7 +510,7 @@ cmd(cancel_line) { // 4051 (When ego is stationary), // 471 (When walking on the first screen's bridge), // 71 (When walking around, using the mouse or the keyboard). -cmd(obj_status_f) { +void AgiEngine::cmd_obj_status_f(uint8 *p) { const char *cycleDesc; // Object's cycle description line const char *motionDesc; // Object's motion description line char msg[256]; // The whole object status message @@ -594,7 +571,7 @@ cmd(obj_status_f) { vt_v.stepSize, cycleDesc, motionDesc); - g_agi->messageBox(msg); + messageBox(msg); } // unknown commands: @@ -605,49 +582,49 @@ cmd(obj_status_f) { // unk_174: Change priority table (used in KQ4) -- j5 // unk_177: Disable menus completely -- j5 // unk_181: Deactivate keypressed control (default control of ego) -cmd(set_simple) { - if (!(g_agi->getFeatures() & (GF_AGI256 | GF_AGI256_2))) { - game.simpleSave = true; +void AgiEngine::cmd_set_simple(uint8 *p) { + if (!(getFeatures() & (GF_AGI256 | GF_AGI256_2))) { + _game.simpleSave = true; } else { // AGI256 and AGI256-2 use this unknown170 command to load 256 color pictures. - // Load the picture. Similar to cmd(load_pic). - g_sprites->eraseBoth(); - g_agi->agiLoadResource(rPICTURE, _v[p0]); + // Load the picture. Similar to void AgiEngine::cmd_load_pic(uint8 *p). + _sprites->eraseBoth(); + agiLoadResource(rPICTURE, _v[p0]); - // Draw the picture. Similar to cmd(draw_pic). - g_picture->decodePicture(_v[p0], false, true); - g_sprites->blitBoth(); - game.pictureShown = 0; + // Draw the picture. Similar to void AgiEngine::cmd_draw_pic(uint8 *p). + _picture->decodePicture(_v[p0], false, true); + _sprites->blitBoth(); + _game.pictureShown = 0; - // Show the picture. Similar to cmd(show_pic). - g_agi->setflag(fOutputMode, false); - cmd_close_window(g_agi, NULL); - g_picture->showPic(); - game.pictureShown = 1; + // Show the picture. Similar to void AgiEngine::cmd_show_pic(uint8 *p). + setflag(fOutputMode, false); + closeWindow(); + _picture->showPic(); + _game.pictureShown = 1; // Simulate slowww computer. Many effects rely on this - g_agi->pause(kPausePicture); + pause(kPausePicture); } } -cmd(pop_script) { - if (g_agi->getVersion() >= 0x2915) { +void AgiEngine::cmd_pop_script(uint8 *p) { + if (getVersion() >= 0x2915) { report("pop.script\n"); } } -cmd(hold_key) { - if (g_agi->getVersion() >= 0x3098) { - g_agi->_egoHoldKey = true; +void AgiEngine::cmd_hold_key(uint8 *p) { + if (getVersion() >= 0x3098) { + _egoHoldKey = true; } } -cmd(discard_sound) { - if (g_agi->getVersion() >= 0x2936) { +void AgiEngine::cmd_discard_sound(uint8 *p) { + if (getVersion() >= 0x2936) { report("discard.sound\n"); } } -cmd(hide_mouse) { +void AgiEngine::cmd_hide_mouse(uint8 *p) { // WORKAROUND: Turns off current movement that's being caused with the mouse. // This fixes problems with too many popup boxes appearing in the Amiga // Gold Rush's copy protection failure scene (i.e. the hanging scene, logic.192). @@ -655,34 +632,34 @@ cmd(hide_mouse) { // to walk somewhere else than to the right using the mouse. // FIXME: Write a proper implementation using disassembly and // apply it to other games as well if applicable. - game.viewTable[0].flags &= ~ADJ_EGO_XY; + _game.viewTable[0].flags &= ~ADJ_EGO_XY; g_system->showMouse(false); } -cmd(allow_menu) { - if (g_agi->getVersion() >= 0x3098) { - g_agi->setflag(fMenusWork, ((p0 != 0) ? true : false)); +void AgiEngine::cmd_allow_menu(uint8 *p) { + if (getVersion() >= 0x3098) { + setflag(fMenusWork, ((p0 != 0) ? true : false)); } } -cmd(show_mouse) { +void AgiEngine::cmd_show_mouse(uint8 *p) { g_system->showMouse(true); } -cmd(fence_mouse) { - g_agi->_game.mouseFence.moveTo(p0, p1); - g_agi->_game.mouseFence.setWidth(p2 - p0); - g_agi->_game.mouseFence.setHeight(p3 - p1); +void AgiEngine::cmd_fence_mouse(uint8 *p) { + _game.mouseFence.moveTo(p0, p1); + _game.mouseFence.setWidth(p2 - p0); + _game.mouseFence.setHeight(p3 - p1); } -cmd(release_key) { - if (g_agi->getVersion() >= 0x3098) { - g_agi->_egoHoldKey = false; +void AgiEngine::cmd_release_key(uint8 *p) { + if (getVersion() >= 0x3098) { + _egoHoldKey = false; } } -cmd(adj_ego_move_to_x_y) { +void AgiEngine::cmd_adj_ego_move_to_x_y(uint8 *p) { int8 x, y; switch (logicNamesCmd[182].numArgs) { @@ -704,56 +681,57 @@ cmd(adj_ego_move_to_x_y) { // onto the ladder so this is more like it (Although that may be caused // by something else because this command doesn't do any flag manipulations // in the Amiga version - checked it with disassembly). - if (x != game.adjMouseX || y != game.adjMouseY) - game.viewTable[EGO_VIEW_TABLE].flags &= ~ADJ_EGO_XY; + if (x != _game.adjMouseX || y != _game.adjMouseY) + _game.viewTable[EGO_VIEW_TABLE].flags &= ~ADJ_EGO_XY; - game.adjMouseX = x; - game.adjMouseY = y; + _game.adjMouseX = x; + _game.adjMouseY = y; debugC(4, kDebugLevelScripts, "adj.ego.move.to.x.y(%d, %d)", x, y); break; // TODO: Check where (if anywhere) the 0 arguments version is used case 0: default: - game.viewTable[0].flags |= ADJ_EGO_XY; + _game.viewTable[0].flags |= ADJ_EGO_XY; break; } } -cmd(parse) { +void AgiEngine::cmd_parse(uint8 *p) { _v[vWordNotFound] = 0; - g_agi->setflag(fEnteredCli, false); - g_agi->setflag(fSaidAcceptedInput, false); + setflag(fEnteredCli, false); + setflag(fSaidAcceptedInput, false); - g_agi->dictionaryWords(g_agi->agiSprintf(game.strings[p0])); + dictionaryWords(agiSprintf(_game.strings[p0])); } -cmd(call) { +void AgiEngine::cmd_call(uint8 *p) { int oldCIP; int oldLognum; // CM: we don't save sIP because set.scan.start can be // used in a called script (fixes xmas demo) - oldCIP = curLogic->cIP; - oldLognum = game.lognum; + oldCIP = _curLogic->cIP; + oldLognum = _game.lognum; - g_agi->runLogic(p0); + runLogic(p0); - game.lognum = oldLognum; - curLogic = &game.logics[game.lognum]; - curLogic->cIP = oldCIP; + _game.lognum = oldLognum; + _curLogic = &_game.logics[_game.lognum]; + _curLogic->cIP = oldCIP; } -cmd(call_f) { - cmd_call(g_agi, &_v[p0]); +void AgiEngine::cmd_call_f(uint8 *p) { + cmd_call(&_v[p0]); } -cmd(draw_pic) { +void AgiEngine::cmd_draw_pic(uint8 *p) { debugC(6, kDebugLevelScripts, "=== draw pic %d ===", _v[p0]); - g_sprites->eraseBoth(); - g_picture->decodePicture(_v[p0], true); - g_sprites->blitBoth(); - game.pictureShown = 0; + _sprites->eraseBoth(); + _picture->decodePicture(_v[p0], true); + _sprites->blitBoth(); + _sprites->commitBoth(); + _game.pictureShown = 0; debugC(6, kDebugLevelScripts, "--- end of draw pic %d ---", _v[p0]); // WORKAROUND for a script bug which exists in SQ1, logic scripts @@ -768,63 +746,64 @@ cmd(draw_pic) { // above the ground), flag 103 is reset, thereby fixing this issue. Note // that this is a script bug and occurs in the original interpreter as well. // Fixes bug #1658514: AGI: SQ1 (2.2 DOS ENG) bizzare exploding roger - if (g_agi->getGameID() == GID_SQ1 && _v[p0] == 20) - g_agi->setflag(103, false); + if (getGameID() == GID_SQ1 && _v[p0] == 20) + setflag(103, false); // Simulate slowww computer. Many effects rely on this - g_agi->pause(kPausePicture); + pause(kPausePicture); } -cmd(show_pic) { +void AgiEngine::cmd_show_pic(uint8 *p) { debugC(6, kDebugLevelScripts, "=== show pic ==="); - g_agi->setflag(fOutputMode, false); - cmd_close_window(g_agi, NULL); - g_picture->showPic(); - game.pictureShown = 1; + setflag(fOutputMode, false); + closeWindow(); + _picture->showPic(); + _game.pictureShown = 1; debugC(6, kDebugLevelScripts, "--- end of show pic ---"); } -cmd(load_pic) { - g_sprites->eraseBoth(); - g_agi->agiLoadResource(rPICTURE, _v[p0]); - g_sprites->blitBoth(); +void AgiEngine::cmd_load_pic(uint8 *p) { + _sprites->eraseBoth(); + agiLoadResource(rPICTURE, _v[p0]); + _sprites->blitBoth(); + _sprites->commitBoth(); } -cmd(discard_pic) { +void AgiEngine::cmd_discard_pic(uint8 *p) { debugC(6, kDebugLevelScripts, "--- discard pic ---"); // do nothing } -cmd(overlay_pic) { +void AgiEngine::cmd_overlay_pic(uint8 *p) { debugC(6, kDebugLevelScripts, "--- overlay pic ---"); - g_sprites->eraseBoth(); - g_picture->decodePicture(_v[p0], false); - g_sprites->blitBoth(); - game.pictureShown = 0; - g_sprites->commitBoth(); + _sprites->eraseBoth(); + _picture->decodePicture(_v[p0], false); + _sprites->blitBoth(); + _game.pictureShown = 0; + _sprites->commitBoth(); // Simulate slowww computer. Many effects rely on this - g_agi->pause(kPausePicture); + pause(kPausePicture); } -cmd(show_pri_screen) { - g_agi->_debug.priority = 1; - g_sprites->eraseBoth(); - g_picture->showPic(); - g_sprites->blitBoth(); +void AgiEngine::cmd_show_pri_screen(uint8 *p) { + _debug.priority = 1; + _sprites->eraseBoth(); + _picture->showPic(); + _sprites->blitBoth(); - g_agi->waitKey(); + waitKey(); - g_agi->_debug.priority = 0; - g_sprites->eraseBoth(); - g_picture->showPic(); - g_sprites->blitBoth(); + _debug.priority = 0; + _sprites->eraseBoth(); + _picture->showPic(); + _sprites->blitBoth(); } -cmd(animate_obj) { +void AgiEngine::cmd_animate_obj(uint8 *p) { if (vt.flags & ANIMATED) return; @@ -835,14 +814,14 @@ cmd(animate_obj) { vt.direction = 0; } -cmd(unanimate_all) { +void AgiEngine::cmd_unanimate_all(uint8 *p) { int i; for (i = 0; i < MAX_VIEWTABLE; i++) - game.viewTable[i].flags &= ~(ANIMATED | DRAWN); + _game.viewTable[i].flags &= ~(ANIMATED | DRAWN); } -cmd(draw) { +void AgiEngine::cmd_draw(uint8 *p) { if (vt.flags & DRAWN) return; @@ -852,19 +831,19 @@ cmd(draw) { debugC(4, kDebugLevelScripts, "draw entry %d", vt.entry); vt.flags |= UPDATE; - if (g_agi->getVersion() >= 0x3000) { - g_agi->setLoop(&vt, vt.currentLoop); - g_agi->setCel(&vt, vt.currentCel); + if (getVersion() >= 0x3000) { + setLoop(&vt, vt.currentLoop); + setCel(&vt, vt.currentCel); } - g_agi->fixPosition(p0); + fixPosition(p0); vt.xPos2 = vt.xPos; vt.yPos2 = vt.yPos; vt.celData2 = vt.celData; - g_sprites->eraseUpdSprites(); + _sprites->eraseUpdSprites(); vt.flags |= DRAWN; - // WORKAROUND: This fixes a bug with AGI Fanmade game Space Trek. + // WORKAROUND: This fixes a bug with AGI Fanmade _game Space Trek. // The original workaround checked if AGI version was <= 2.440, which could // cause regressions with some AGI games. The original workaround no longer // works for Space Trek in ScummVM, as all fanmade games are set to use @@ -875,36 +854,43 @@ cmd(draw) { // TODO: Investigate this further and check if any other fanmade AGI // games are affected. If yes, then it'd be best to set this for Space // Trek only - if (g_agi->getFeatures() & GF_FANMADE) // See Sarien bug #546562 + if (getFeatures() & GF_FANMADE) // See Sarien bug #546562 vt.flags |= ANIMATED; - g_sprites->blitUpdSprites(); + _sprites->blitUpdSprites(); vt.flags &= ~DONTUPDATE; - g_sprites->commitBlock(vt.xPos, vt.yPos - vt.ySize + 1, vt.xPos + vt.xSize - 1, vt.yPos); + _sprites->commitBlock(vt.xPos, vt.yPos - vt.ySize + 1, vt.xPos + vt.xSize - 1, vt.yPos, true); debugC(4, kDebugLevelScripts, "vt entry #%d flags = %02x", p0, vt.flags); } -cmd(erase) { +void AgiEngine::cmd_erase(uint8 *p) { if (~vt.flags & DRAWN) return; - g_sprites->eraseUpdSprites(); + _sprites->eraseUpdSprites(); if (vt.flags & UPDATE) { vt.flags &= ~DRAWN; } else { - g_sprites->eraseNonupdSprites(); + _sprites->eraseNonupdSprites(); vt.flags &= ~DRAWN; - g_sprites->blitNonupdSprites(); + _sprites->blitNonupdSprites(); } - g_sprites->blitUpdSprites(); + _sprites->blitUpdSprites(); + + int x1, y1, x2, y2; + + x1 = MIN((int)MIN(vt.xPos, vt.xPos2), MIN(vt.xPos + vt.celData->width, vt.xPos2 + vt.celData2->width)); + x2 = MAX((int)MAX(vt.xPos, vt.xPos2), MAX(vt.xPos + vt.celData->width, vt.xPos2 + vt.celData2->width)); + y1 = MIN((int)MIN(vt.yPos, vt.yPos2), MIN(vt.yPos - vt.celData->height, vt.yPos2 - vt.celData2->height)); + y2 = MAX((int)MAX(vt.yPos, vt.yPos2), MAX(vt.yPos - vt.celData->height, vt.yPos2 - vt.celData2->height)); - g_sprites->commitBlock(vt.xPos, vt.yPos - vt.ySize + 1, vt.xPos + vt.xSize - 1, vt.yPos); + _sprites->commitBlock(x1, y1, x2, y2, true); } -cmd(position) { +void AgiEngine::cmd_position(uint8 *p) { vt.xPos = vt.xPos2 = p1; vt.yPos = vt.yPos2 = p2; @@ -921,27 +907,27 @@ cmd(position) { // I haven't checked but if Space Trek solely abuses the position-command we wouldn't // strictly need the identical workaround in the position.v-command but it does make // for a nice symmetry. - if (g_agi->getFeatures() & GF_CLIPCOORDS) - g_agi->clipViewCoordinates(&vt); + if (getFeatures() & GF_CLIPCOORDS) + clipViewCoordinates(&vt); } -cmd(position_f) { +void AgiEngine::cmd_position_f(uint8 *p) { vt.xPos = vt.xPos2 = _v[p1]; vt.yPos = vt.yPos2 = _v[p2]; // WORKAROUND: Part of the fix for bug #1659209 "AGI: Space Trek sprite duplication" // with an accompanying identical workaround in position-command (i.e. command 0x25). // See that workaround's comment for more in-depth information. - if (g_agi->getFeatures() & GF_CLIPCOORDS) - g_agi->clipViewCoordinates(&vt); + if (getFeatures() & GF_CLIPCOORDS) + clipViewCoordinates(&vt); } -cmd(get_posn) { - game.vars[p1] = (unsigned char)vt.xPos; - game.vars[p2] = (unsigned char)vt.yPos; +void AgiEngine::cmd_get_posn(uint8 *p) { + _game.vars[p1] = (unsigned char)vt.xPos; + _game.vars[p2] = (unsigned char)vt.yPos; } -cmd(reposition) { +void AgiEngine::cmd_reposition(uint8 *p) { int dx = (int8) _v[p1], dy = (int8) _v[p2]; debugC(4, kDebugLevelScripts, "dx=%d, dy=%d", dx, dy); @@ -957,106 +943,106 @@ cmd(reposition) { else vt.yPos += dy; - g_agi->fixPosition(p0); + fixPosition(p0); } -cmd(reposition_to) { +void AgiEngine::cmd_reposition_to(uint8 *p) { vt.xPos = p1; vt.yPos = p2; vt.flags |= UPDATE_POS; - g_agi->fixPosition(p0); + fixPosition(p0); } -cmd(reposition_to_f) { +void AgiEngine::cmd_reposition_to_f(uint8 *p) { vt.xPos = _v[p1]; vt.yPos = _v[p2]; vt.flags |= UPDATE_POS; - g_agi->fixPosition(p0); + fixPosition(p0); } -cmd(add_to_pic) { - g_sprites->addToPic(p0, p1, p2, p3, p4, p5, p6); +void AgiEngine::cmd_add_to_pic(uint8 *p) { + _sprites->addToPic(p0, p1, p2, p3, p4, p5, p6); } -cmd(add_to_pic_f) { - g_sprites->addToPic(_v[p0], _v[p1], _v[p2], _v[p3], _v[p4], _v[p5], _v[p6]); +void AgiEngine::cmd_add_to_pic_f(uint8 *p) { + _sprites->addToPic(_v[p0], _v[p1], _v[p2], _v[p3], _v[p4], _v[p5], _v[p6]); } -cmd(force_update) { - g_sprites->eraseBoth(); - g_sprites->blitBoth(); - g_sprites->commitBoth(); +void AgiEngine::cmd_force_update(uint8 *p) { + _sprites->eraseBoth(); + _sprites->blitBoth(); + _sprites->commitBoth(); } -cmd(reverse_loop) { +void AgiEngine::cmd_reverse_loop(uint8 *p) { debugC(4, kDebugLevelScripts, "o%d, f%d", p0, p1); vt.cycle = CYCLE_REV_LOOP; vt.flags |= (DONTUPDATE | UPDATE | CYCLING); vt.parm1 = p1; - g_agi->setflag(p1, false); + setflag(p1, false); } -cmd(end_of_loop) { +void AgiEngine::cmd_end_of_loop(uint8 *p) { debugC(4, kDebugLevelScripts, "o%d, f%d", p0, p1); vt.cycle = CYCLE_END_OF_LOOP; vt.flags |= (DONTUPDATE | UPDATE | CYCLING); vt.parm1 = p1; - g_agi->setflag(p1, false); + setflag(p1, false); } -cmd(block) { +void AgiEngine::cmd_block(uint8 *p) { debugC(4, kDebugLevelScripts, "x1=%d, y1=%d, x2=%d, y2=%d", p0, p1, p2, p3); - game.block.active = true; - game.block.x1 = p0; - game.block.y1 = p1; - game.block.x2 = p2; - game.block.y2 = p3; + _game.block.active = true; + _game.block.x1 = p0; + _game.block.y1 = p1; + _game.block.x2 = p2; + _game.block.y2 = p3; } -cmd(unblock) { - game.block.active = false; +void AgiEngine::cmd_unblock(uint8 *p) { + _game.block.active = false; } -cmd(normal_motion) { +void AgiEngine::cmd_normal_motion(uint8 *p) { vt.motion = MOTION_NORMAL; } -cmd(stop_motion) { +void AgiEngine::cmd_stop_motion(uint8 *p) { vt.direction = 0; vt.motion = MOTION_NORMAL; if (p0 == 0) { // ego only _v[vEgoDir] = 0; - game.playerControl = false; + _game.playerControl = false; } } -cmd(start_motion) { +void AgiEngine::cmd_start_motion(uint8 *p) { vt.motion = MOTION_NORMAL; if (p0 == 0) { // ego only _v[vEgoDir] = 0; - game.playerControl = true; + _game.playerControl = true; } } -cmd(player_control) { - game.playerControl = true; - game.viewTable[0].motion = MOTION_NORMAL; +void AgiEngine::cmd_player_control(uint8 *p) { + _game.playerControl = true; + _game.viewTable[0].motion = MOTION_NORMAL; } -cmd(program_control) { - game.playerControl = false; +void AgiEngine::cmd_program_control(uint8 *p) { + _game.playerControl = false; } -cmd(follow_ego) { +void AgiEngine::cmd_follow_ego(uint8 *p) { vt.motion = MOTION_FOLLOW_EGO; vt.parm1 = p1 > vt.stepSize ? p1 : vt.stepSize; vt.parm2 = p2; vt.parm3 = 0xff; - g_agi->setflag(p2, false); + setflag(p2, false); vt.flags |= UPDATE; } -cmd(move_obj) { +void AgiEngine::cmd_move_obj(uint8 *p) { // _D (_D_WARN "o=%d, x=%d, y=%d, s=%d, f=%d", p0, p1, p2, p3, p4); vt.motion = MOTION_MOVE_OBJ; @@ -1068,18 +1054,18 @@ cmd(move_obj) { if (p3 != 0) vt.stepSize = p3; - g_agi->setflag(p4, false); + setflag(p4, false); vt.flags |= UPDATE; if (p0 == 0) - game.playerControl = false; + _game.playerControl = false; // AGI 2.272 (ddp, xmas) doesn't call move_obj! - if (g_agi->getVersion() > 0x2272) - g_agi->moveObj(&vt); + if (getVersion() > 0x2272) + moveObj(&vt); } -cmd(move_obj_f) { +void AgiEngine::cmd_move_obj_f(uint8 *p) { vt.motion = MOTION_MOVE_OBJ; vt.parm1 = _v[p1]; vt.parm2 = _v[p2]; @@ -1089,67 +1075,67 @@ cmd(move_obj_f) { if (_v[p3] != 0) vt.stepSize = _v[p3]; - g_agi->setflag(p4, false); + setflag(p4, false); vt.flags |= UPDATE; if (p0 == 0) - game.playerControl = false; + _game.playerControl = false; // AGI 2.272 (ddp, xmas) doesn't call move_obj! - if (g_agi->getVersion() > 0x2272) - g_agi->moveObj(&vt); + if (getVersion() > 0x2272) + moveObj(&vt); } -cmd(wander) { +void AgiEngine::cmd_wander(uint8 *p) { if (p0 == 0) - game.playerControl = false; + _game.playerControl = false; vt.motion = MOTION_WANDER; vt.flags |= UPDATE; } -cmd(set_game_id) { - if (curLogic->texts && (p0 - 1) <= curLogic->numTexts) - strncpy(game.id, curLogic->texts[p0 - 1], 8); +void AgiEngine::cmd_set_game_id(uint8 *p) { + if (_curLogic->texts && (p0 - 1) <= _curLogic->numTexts) + strncpy(_game.id, _curLogic->texts[p0 - 1], 8); else - game.id[0] = 0; + _game.id[0] = 0; - report("Game ID: \"%s\"\n", game.id); + report("Game ID: \"%s\"\n", _game.id); } -cmd(pause) { - int tmp = game.clockEnabled; +void AgiEngine::cmd_pause(uint8 *p) { + int tmp = _game.clockEnabled; const char *b[] = { "Continue", NULL }; const char *b_ru[] = { "\x8f\xe0\xae\xa4\xae\xab\xa6\xa8\xe2\xec", NULL }; - game.clockEnabled = false; + _game.clockEnabled = false; - switch (g_agi->getLanguage()) { + switch (getLanguage()) { case Common::RU_RUS: - g_agi->selectionBox(" \x88\xa3\xe0\xa0 \xae\xe1\xe2\xa0\xad\xae\xa2\xab\xa5\xad\xa0. \n\n\n", b_ru); + selectionBox(" \x88\xa3\xe0\xa0 \xae\xe1\xe2\xa0\xad\xae\xa2\xab\xa5\xad\xa0. \n\n\n", b_ru); break; default: - g_agi->selectionBox(" Game is paused. \n\n\n", b); + selectionBox(" Game is paused. \n\n\n", b); break; } - game.clockEnabled = tmp; + _game.clockEnabled = tmp; } -cmd(set_menu) { - debugC(4, kDebugLevelScripts, "text %02x of %02x", p0, curLogic->numTexts); +void AgiEngine::cmd_set_menu(uint8 *p) { + debugC(4, kDebugLevelScripts, "text %02x of %02x", p0, _curLogic->numTexts); - if (curLogic->texts != NULL && p0 <= curLogic->numTexts) - g_agi->_menu->add(curLogic->texts[p0 - 1]); + if (_curLogic->texts != NULL && p0 <= _curLogic->numTexts) + _menu->add(_curLogic->texts[p0 - 1]); } -cmd(set_menu_item) { - debugC(4, kDebugLevelScripts, "text %02x of %02x", p0, curLogic->numTexts); +void AgiEngine::cmd_set_menu_item(uint8 *p) { + debugC(4, kDebugLevelScripts, "text %02x of %02x", p0, _curLogic->numTexts); - if (curLogic->texts != NULL && p0 <= curLogic->numTexts) - g_agi->_menu->addItem(curLogic->texts[p0 - 1], p1); + if (_curLogic->texts != NULL && p0 <= _curLogic->numTexts) + _menu->addItem(_curLogic->texts[p0 - 1], p1); } -cmd(version) { +void AgiEngine::cmd_version(uint8 *p) { char verMsg[64]; char ver2Msg[] = "\n" @@ -1168,7 +1154,7 @@ cmd(version) { sprintf(verMsg, TITLE " v%s", gScummVMVersion); - ver = g_agi->getVersion(); + ver = getVersion(); maj = (ver >> 12) & 0xf; min = ver & 0xfff; @@ -1186,88 +1172,87 @@ cmd(version) { strncpy(q + 1 + gap, verMsg, strlen(verMsg)); sprintf(msg, q, maj, min); - g_agi->messageBox(msg); + messageBox(msg); } -cmd(configure_screen) { - game.lineMinPrint = p0; - game.lineUserInput = p1; - game.lineStatus = p2; +void AgiEngine::cmd_configure_screen(uint8 *p) { + _game.lineMinPrint = p0; + _game.lineUserInput = p1; + _game.lineStatus = p2; } -cmd(text_screen) { +void AgiEngine::cmd_text_screen(uint8 *p) { debugC(4, kDebugLevelScripts, "switching to text mode"); - game.gfxMode = false; + _game.gfxMode = false; // Simulates the "bright background bit" of the PC video // controller. - if (game.colorBg) - game.colorBg |= 0x08; + if (_game.colorBg) + _game.colorBg |= 0x08; - g_gfx->clearScreen(game.colorBg); + _gfx->clearScreen(_game.colorBg); } -cmd(graphics) { +void AgiEngine::cmd_graphics(uint8 *p) { debugC(4, kDebugLevelScripts, "switching to graphics mode"); - if (!game.gfxMode) { - game.gfxMode = true; - g_gfx->clearScreen(0); - g_picture->showPic(); - g_agi->writeStatus(); - g_agi->writePrompt(); + if (!_game.gfxMode) { + _game.gfxMode = true; + _gfx->clearScreen(0); + _picture->showPic(); + writeStatus(); + writePrompt(); } } -cmd(set_text_attribute) { - game.colorFg = p0; - game.colorBg = p1; +void AgiEngine::cmd_set_text_attribute(uint8 *p) { + _game.colorFg = p0; + _game.colorBg = p1; - if (game.gfxMode) { - if (game.colorBg != 0) { - game.colorFg = 0; - game.colorBg = 15; + if (_game.gfxMode) { + if (_game.colorBg != 0) { + _game.colorFg = 0; + _game.colorBg = 15; } } } -cmd(status) { - g_agi->inventory(); +void AgiEngine::cmd_status(uint8 *p) { + inventory(); } -cmd(quit) { +void AgiEngine::cmd_quit(uint8 *p) { const char *buttons[] = { "Quit", "Continue", NULL }; - g_sound->stopSound(); + _sound->stopSound(); if (p0) { - g_agi->quitGame(); + quitGame(); } else { - if (g_agi->selectionBox - (" Quit the game, or continue? \n\n\n", buttons) == 0) { - g_agi->quitGame(); + if (selectionBox(" Quit the game, or continue? \n\n\n", buttons) == 0) { + quitGame(); } } } -cmd(restart_game) { +void AgiEngine::cmd_restart_game(uint8 *p) { const char *buttons[] = { "Restart", "Continue", NULL }; int sel; - g_sound->stopSound(); - sel = g_agi->getflag(fAutoRestart) ? 0 : - g_agi->selectionBox(" Restart game, or continue? \n\n\n", buttons); + _sound->stopSound(); + sel = getflag(fAutoRestart) ? 0 : + selectionBox(" Restart _game, or continue? \n\n\n", buttons); if (sel == 0) { - g_agi->_restartGame = true; - g_agi->setflag(fRestartGame, true); - g_agi->_menu->enableAll(); + _restartGame = true; + setflag(fRestartGame, true); + _menu->enableAll(); } } -cmd(distance) { +void AgiEngine::cmd_distance(uint8 *p) { int16 x1, y1, x2, y2, d; - VtEntry *v0 = &game.viewTable[p0]; - VtEntry *v1 = &game.viewTable[p1]; + VtEntry *v0 = &_game.viewTable[p0]; + VtEntry *v1 = &_game.viewTable[p1]; if (v0->flags & DRAWN && v1->flags & DRAWN) { x1 = v0->xPos + v0->xSize / 2; @@ -1290,7 +1275,7 @@ cmd(distance) { // wouldn't chase Rosella around anymore. If it had worked correctly the zombie // wouldn't have come up at all or it would have come up and gone back down // immediately. The latter approach is the one implemented here. - if (g_agi->getGameID() == GID_KQ4 && (_v[vCurRoom] == 16 || _v[vCurRoom] == 18) && p2 >= 221 && p2 <= 223) { + if (getGameID() == GID_KQ4 && (_v[vCurRoom] == 16 || _v[vCurRoom] == 18) && p2 >= 221 && p2 <= 223) { // Rooms 16 and 18 are graveyards where three zombies come up at night. They use logics 16 and 18. // Variables 221-223 are used to save the distance between each zombie and Rosella. // Variables 155, 156 and 162 are used to save the state of each zombie in room 16. @@ -1315,24 +1300,24 @@ cmd(distance) { _v[p2] = (unsigned char)d; } -cmd(accept_input) { +void AgiEngine::cmd_accept_input(uint8 *p) { debugC(4, kDebugLevelScripts | kDebugLevelInput, "input normal"); - g_agi->newInputMode(INPUT_NORMAL); - game.inputEnabled = true; - g_agi->writePrompt(); + newInputMode(INPUT_NORMAL); + _game.inputEnabled = true; + writePrompt(); } -cmd(prevent_input) { +void AgiEngine::cmd_prevent_input(uint8 *p) { debugC(4, kDebugLevelScripts | kDebugLevelInput, "no input"); - g_agi->newInputMode(INPUT_NONE); - game.inputEnabled = false; + newInputMode(INPUT_NONE); + _game.inputEnabled = false; - g_agi->clearPrompt(); + clearPrompt(); } -cmd(get_string) { +void AgiEngine::cmd_get_string(uint8 *p) { int tex, row, col; debugC(4, kDebugLevelScripts, "%d %d %d %d %d", p0, p1, p2, p3, p4); @@ -1348,63 +1333,63 @@ cmd(get_string) { if (col > 39) col = 39; - g_agi->newInputMode(INPUT_GETSTRING); + newInputMode(INPUT_GETSTRING); - if (curLogic->texts != NULL && curLogic->numTexts >= tex) { - int len = strlen(curLogic->texts[tex]); + if (_curLogic->texts != NULL && _curLogic->numTexts >= tex) { + int len = strlen(_curLogic->texts[tex]); - g_agi->printText(curLogic->texts[tex], 0, col, row, len, game.colorFg, game.colorBg); - g_agi->getString(col + len - 1, row, p4, p0); + printText(_curLogic->texts[tex], 0, col, row, len, _game.colorFg, _game.colorBg); + getString(col + len - 1, row, p4, p0); // SGEO: display input char - g_gfx->printCharacter((col + len), row, game.cursorChar, game.colorFg, game.colorBg); + _gfx->printCharacter((col + len), row, _game.cursorChar, _game.colorFg, _game.colorBg); } do { - g_agi->mainCycle(); - } while (game.inputMode == INPUT_GETSTRING && !(g_agi->shouldQuit() || g_agi->_restartGame)); + mainCycle(); + } while (_game.inputMode == INPUT_GETSTRING && !(shouldQuit() || _restartGame)); } -cmd(get_num) { +void AgiEngine::cmd_get_num(uint8 *p) { debugC(4, kDebugLevelScripts, "%d %d", p0, p1); - g_agi->newInputMode(INPUT_GETSTRING); + newInputMode(INPUT_GETSTRING); - if (curLogic->texts != NULL && curLogic->numTexts >= (p0 - 1)) { - int len = strlen(curLogic->texts[p0 - 1]); + if (_curLogic->texts != NULL && _curLogic->numTexts >= (p0 - 1)) { + int len = strlen(_curLogic->texts[p0 - 1]); - g_agi->printText(curLogic->texts[p0 - 1], 0, 0, 22, len, game.colorFg, game.colorBg); - g_agi->getString(len - 1, 22, 3, MAX_STRINGS); + printText(_curLogic->texts[p0 - 1], 0, 0, 22, len, _game.colorFg, _game.colorBg); + getString(len - 1, 22, 3, MAX_STRINGS); // CM: display input char - g_gfx->printCharacter((p3 + len), 22, game.cursorChar, game.colorFg, game.colorBg); + _gfx->printCharacter((p3 + len), 22, _game.cursorChar, _game.colorFg, _game.colorBg); } do { - g_agi->mainCycle(); - } while (game.inputMode == INPUT_GETSTRING && !(g_agi->shouldQuit() || g_agi->_restartGame)); + mainCycle(); + } while (_game.inputMode == INPUT_GETSTRING && !(shouldQuit() || _restartGame)); - _v[p1] = atoi(game.strings[MAX_STRINGS]); + _v[p1] = atoi(_game.strings[MAX_STRINGS]); - debugC(4, kDebugLevelScripts, "[%s] -> %d", game.strings[MAX_STRINGS], _v[p1]); + debugC(4, kDebugLevelScripts, "[%s] -> %d", _game.strings[MAX_STRINGS], _v[p1]); - g_agi->clearLines(22, 22, game.colorBg); - g_agi->flushLines(22, 22); + clearLines(22, 22, _game.colorBg); + flushLines(22, 22); } -cmd(set_cursor_char) { - if (curLogic->texts != NULL && (p0 - 1) <= curLogic->numTexts) { - game.cursorChar = *curLogic->texts[p0 - 1]; +void AgiEngine::cmd_set_cursor_char(uint8 *p) { + if (_curLogic->texts != NULL && (p0 - 1) <= _curLogic->numTexts) { + _game.cursorChar = *_curLogic->texts[p0 - 1]; } else { // default - game.cursorChar = '_'; + _game.cursorChar = '_'; } } -cmd(set_key) { +void AgiEngine::cmd_set_key(uint8 *p) { int key; - if (game.lastController >= MAX_CONTROLLERS) { + if (_game.lastController >= MAX_CONTROLLERS) { warning("Number of set.keys exceeded %d", MAX_CONTROLLERS); return; } @@ -1413,36 +1398,35 @@ cmd(set_key) { key = 256 * p1 + p0; - game.controllers[game.lastController].keycode = key; - game.controllers[game.lastController].controller = p2; - game.lastController++; + _game.controllers[_game.lastController].keycode = key; + _game.controllers[_game.lastController].controller = p2; + _game.lastController++; - game.controllerOccured[p2] = false; + _game.controllerOccured[p2] = false; } -cmd(set_string) { +void AgiEngine::cmd_set_string(uint8 *p) { // CM: to avoid crash in Groza (str = 150) if (p0 > MAX_STRINGS) return; - strcpy(game.strings[p0], curLogic->texts[p1 - 1]); + strcpy(_game.strings[p0], _curLogic->texts[p1 - 1]); } -cmd(display) { +void AgiEngine::cmd_display(uint8 *p) { int len = 40; - char *s = g_agi->wordWrapString(curLogic->texts[p2 - 1], &len); + char *s = wordWrapString(_curLogic->texts[p2 - 1], &len); - g_agi->printText(s, p1, 0, p0, 40, game.colorFg, game.colorBg); + printText(s, p1, 0, p0, 40, _game.colorFg, _game.colorBg); free(s); } -cmd(display_f) { - debugC(4, kDebugLevelScripts, "p0 = %d", p0); - g_agi->printText(curLogic->texts[_v[p2] - 1], _v[p1], 0, _v[p0], 40, game.colorFg, game.colorBg); +void AgiEngine::cmd_display_f(uint8 *p) { + printText(_curLogic->texts[_v[p2] - 1], _v[p1], 0, _v[p0], 40, _game.colorFg, _game.colorBg); } -cmd(clear_text_rect) { +void AgiEngine::cmd_clear_text_rect(uint8 *p) { int c, x1, y1, x2, y2; if ((c = p4) != 0) @@ -1463,21 +1447,21 @@ cmd(clear_text_rect) { if (y2 > GFX_HEIGHT) y2 = GFX_HEIGHT - 1; - g_gfx->drawRectangle(x1, y1, x2, y2, c); - g_gfx->flushBlock(x1, y1, x2, y2); + _gfx->drawRectangle(x1, y1, x2, y2, c); + _gfx->flushBlock(x1, y1, x2, y2); } -cmd(toggle_monitor) { +void AgiEngine::cmd_toggle_monitor(uint8 *p) { report("toggle.monitor\n"); } -cmd(echo_line) { - strcpy((char *)game.inputBuffer, (const char *)game.echoBuffer); - game.cursorPos = strlen((char *)game.inputBuffer); - game.hasPrompt = 0; +void AgiEngine::cmd_echo_line(uint8 *p) { + strcpy((char *)_game.inputBuffer, (const char *)_game.echoBuffer); + _game.cursorPos = strlen((char *)_game.inputBuffer); + _game.hasPrompt = 0; } -cmd(clear_lines) { +void AgiEngine::cmd_clear_lines(uint8 *p) { uint8 l; // Residence 44 calls clear.lines(24,0,0), see Sarien bug #558423 @@ -1487,78 +1471,78 @@ cmd(clear_lines) { // #1935838 and #1935842 l = (l <= 24) ? l : 24; - g_agi->clearLines(p0, l, p2); - g_agi->flushLines(p0, l); + clearLines(p0, l, p2); + flushLines(p0, l); } -cmd(print) { +void AgiEngine::cmd_print(uint8 *p) { int n = p0 < 1 ? 1 : p0; - g_agi->print(curLogic->texts[n - 1], 0, 0, 0); + print(_curLogic->texts[n - 1], 0, 0, 0); } -cmd(print_f) { +void AgiEngine::cmd_print_f(uint8 *p) { int n = _v[p0] < 1 ? 1 : _v[p0]; - g_agi->print(curLogic->texts[n - 1], 0, 0, 0); + print(_curLogic->texts[n - 1], 0, 0, 0); } -cmd(print_at) { +void AgiEngine::cmd_print_at(uint8 *p) { int n = p0 < 1 ? 1 : p0; debugC(4, kDebugLevelScripts, "%d %d %d %d", p0, p1, p2, p3); - g_agi->print(curLogic->texts[n - 1], p1, p2, p3); + print(_curLogic->texts[n - 1], p1, p2, p3); } -cmd(print_at_v) { +void AgiEngine::cmd_print_at_v(uint8 *p) { int n = _v[p0] < 1 ? 1 : _v[p0]; - g_agi->print(curLogic->texts[n - 1], p1, p2, p3); + print(_curLogic->texts[n - 1], p1, p2, p3); } -cmd(push_script) { +void AgiEngine::cmd_push_script(uint8 *p) { // We run AGIMOUSE always as a side effect - if (g_agi->getFeatures() & GF_AGIMOUSE || 1) { - game.vars[27] = g_agi->_mouse.button; - game.vars[28] = g_agi->_mouse.x / 2; - game.vars[29] = g_agi->_mouse.y; + if (getFeatures() & GF_AGIMOUSE || true) { + _game.vars[27] = _mouse.button; + _game.vars[28] = _mouse.x / 2; + _game.vars[29] = _mouse.y; } else { - if (g_agi->getVersion() >= 0x2915) { + if (getVersion() >= 0x2915) { report("push.script\n"); } } } -cmd(set_pri_base) { +void AgiEngine::cmd_set_pri_base(uint8 *p) { int i, x, pri; report("Priority base set to %d\n", p0); - // game.alt_pri = true; + // _game.alt_pri = true; x = (_HEIGHT - p0) * _HEIGHT / 10; for (i = 0; i < _HEIGHT; i++) { pri = (i - p0) < 0 ? 4 : (i - p0) * _HEIGHT / x + 5; if (pri > 15) pri = 15; - game.priTable[i] = pri; + _game.priTable[i] = pri; } } -cmd(mouse_posn) { - _v[p0] = WIN_TO_PIC_X(g_agi->_mouse.x); - _v[p1] = WIN_TO_PIC_Y(g_agi->_mouse.y); +void AgiEngine::cmd_mouse_posn(uint8 *p) { + _v[p0] = WIN_TO_PIC_X(_mouse.x); + _v[p1] = WIN_TO_PIC_Y(_mouse.y); } -cmd(shake_screen) { +void AgiEngine::cmd_shake_screen(uint8 *p) { int i; // AGIPAL uses shake.screen values between 100 and 109 to set the palette // (Checked the original AGIPAL-hack's shake.screen-routine's disassembly). if (p0 >= 100 && p0 < 110) { - if (g_agi->getFeatures() & GF_AGIPAL) { - g_gfx->setAGIPal(p0); + if (getFeatures() & GF_AGIPAL) { + _gfx->setAGIPal(p0); return; } else { warning("It looks like GF_AGIPAL flag is missing"); @@ -1567,208 +1551,213 @@ cmd(shake_screen) { // Disables input while shaking to prevent bug // #1678230: AGI: Entering text while screen is shaking - int originalValue = game.inputEnabled; - game.inputEnabled = 0; + bool originalValue = _game.inputEnabled; + _game.inputEnabled = false; - g_gfx->shakeStart(); + _gfx->shakeStart(); - g_sprites->commitBoth(); // Fixes SQ1 demo + _sprites->commitBoth(); // Fixes SQ1 demo for (i = 4 * p0; i; i--) { - g_gfx->shakeScreen(i & 1); - g_gfx->flushBlock(0, 0, GFX_WIDTH - 1, GFX_HEIGHT - 1); - g_agi->mainCycle(); + _gfx->shakeScreen(i & 1); + _gfx->flushBlock(0, 0, GFX_WIDTH - 1, GFX_HEIGHT - 1); + mainCycle(); } - g_gfx->shakeEnd(); + _gfx->shakeEnd(); // Sets input back to what it was - game.inputEnabled = originalValue; -} - -static void (*agiCommand[183])(AgiEngine *, uint8 *) = { - NULL, // 0x00 - cmd_increment, - cmd_decrement, - cmd_assignn, - cmd_assignv, - cmd_addn, - cmd_addv, - cmd_subn, - cmd_subv, // 0x08 - cmd_lindirectv, - cmd_rindirect, - cmd_lindirectn, - cmd_set, - cmd_reset, - cmd_toggle, - cmd_set_v, - cmd_reset_v, // 0x10 - cmd_toggle_v, - cmd_new_room, - cmd_new_room_f, - cmd_load_logic, - cmd_load_logic_f, - cmd_call, - cmd_call_f, - cmd_load_pic, // 0x18 - cmd_draw_pic, - cmd_show_pic, - cmd_discard_pic, - cmd_overlay_pic, - cmd_show_pri_screen, - cmd_load_view, - cmd_load_view_f, - cmd_discard_view, // 0x20 - cmd_animate_obj, - cmd_unanimate_all, - cmd_draw, - cmd_erase, - cmd_position, - cmd_position_f, - cmd_get_posn, - cmd_reposition, // 0x28 - cmd_set_view, - cmd_set_view_f, - cmd_set_loop, - cmd_set_loop_f, - cmd_fix_loop, - cmd_release_loop, - cmd_set_cel, - cmd_set_cel_f, // 0x30 - cmd_last_cel, - cmd_current_cel, - cmd_current_loop, - cmd_current_view, - cmd_number_of_loops, - cmd_set_priority, - cmd_set_priority_f, - cmd_release_priority, // 0x38 - cmd_get_priority, - cmd_stop_update, - cmd_start_update, - cmd_force_update, - cmd_ignore_horizon, - cmd_observe_horizon, - cmd_set_horizon, - cmd_object_on_water, // 0x40 - cmd_object_on_land, - cmd_object_on_anything, - cmd_ignore_objs, - cmd_observe_objs, - cmd_distance, - cmd_stop_cycling, - cmd_start_cycling, - cmd_normal_cycle, // 0x48 - cmd_end_of_loop, - cmd_reverse_cycle, - cmd_reverse_loop, - cmd_cycle_time, - cmd_stop_motion, - cmd_start_motion, - cmd_step_size, - cmd_step_time, // 0x50 - cmd_move_obj, - cmd_move_obj_f, - cmd_follow_ego, - cmd_wander, - cmd_normal_motion, - cmd_set_dir, - cmd_get_dir, - cmd_ignore_blocks, // 0x58 - cmd_observe_blocks, - cmd_block, - cmd_unblock, - cmd_get, - cmd_get_f, - cmd_drop, - cmd_put, - cmd_put_f, // 0x60 - cmd_get_room_f, - cmd_load_sound, - cmd_sound, - cmd_stop_sound, - cmd_print, - cmd_print_f, - cmd_display, - cmd_display_f, // 0x68 - cmd_clear_lines, - cmd_text_screen, - cmd_graphics, - cmd_set_cursor_char, - cmd_set_text_attribute, - cmd_shake_screen, - cmd_configure_screen, - cmd_status_line_on, // 0x70 - cmd_status_line_off, - cmd_set_string, - cmd_get_string, - cmd_word_to_string, - cmd_parse, - cmd_get_num, - cmd_prevent_input, - cmd_accept_input, // 0x78 - cmd_set_key, - cmd_add_to_pic, - cmd_add_to_pic_f, - cmd_status, - cmd_save_game, - cmd_load_game, - cmd_init_disk, - cmd_restart_game, // 0x80 - cmd_show_obj, - cmd_random, - cmd_program_control, - cmd_player_control, - cmd_obj_status_f, - cmd_quit, - cmd_show_mem, - cmd_pause, // 0x88 - cmd_echo_line, - cmd_cancel_line, - cmd_init_joy, - cmd_toggle_monitor, - cmd_version, - cmd_script_size, - cmd_set_game_id, - cmd_log, // 0x90 - cmd_set_scan_start, - cmd_reset_scan_start, - cmd_reposition_to, - cmd_reposition_to_f, - cmd_trace_on, - cmd_trace_info, - cmd_print_at, - cmd_print_at_v, // 0x98 - cmd_discard_view, - cmd_clear_text_rect, - cmd_set_upper_left, - cmd_set_menu, - cmd_set_menu_item, - cmd_submit_menu, - cmd_enable_item, - cmd_disable_item, // 0xa0 - cmd_menu_input, - cmd_show_obj_v, - cmd_open_dialogue, - cmd_close_dialogue, - cmd_mul_n, - cmd_mul_v, - cmd_div_n, - cmd_div_v, // 0xa8 - cmd_close_window, - cmd_set_simple, - cmd_push_script, - cmd_pop_script, - cmd_hold_key, - cmd_set_pri_base, - cmd_discard_sound, - cmd_hide_mouse, // 0xb0 - cmd_allow_menu, - cmd_show_mouse, - cmd_fence_mouse, - cmd_mouse_posn, - cmd_release_key, - cmd_adj_ego_move_to_x_y -}; + _game.inputEnabled = originalValue; +} + +void AgiEngine::setupOpcodes() { + AgiCommand tmp[] = { + NULL, // 0x00 + &AgiEngine::cmd_increment, + &AgiEngine::cmd_decrement, + &AgiEngine::cmd_assignn, + &AgiEngine::cmd_assignv, + &AgiEngine::cmd_addn, + &AgiEngine::cmd_addv, + &AgiEngine::cmd_subn, + &AgiEngine::cmd_subv, // 0x08 + &AgiEngine::cmd_lindirectv, + &AgiEngine::cmd_rindirect, + &AgiEngine::cmd_lindirectn, + &AgiEngine::cmd_set, + &AgiEngine::cmd_reset, + &AgiEngine::cmd_toggle, + &AgiEngine::cmd_set_v, + &AgiEngine::cmd_reset_v, // 0x10 + &AgiEngine::cmd_toggle_v, + &AgiEngine::cmd_new_room, + &AgiEngine::cmd_new_room_f, + &AgiEngine::cmd_load_logic, + &AgiEngine::cmd_load_logic_f, + &AgiEngine::cmd_call, + &AgiEngine::cmd_call_f, + &AgiEngine::cmd_load_pic, // 0x18 + &AgiEngine::cmd_draw_pic, + &AgiEngine::cmd_show_pic, + &AgiEngine::cmd_discard_pic, + &AgiEngine::cmd_overlay_pic, + &AgiEngine::cmd_show_pri_screen, + &AgiEngine::cmd_load_view, + &AgiEngine::cmd_load_view_f, + &AgiEngine::cmd_discard_view, // 0x20 + &AgiEngine::cmd_animate_obj, + &AgiEngine::cmd_unanimate_all, + &AgiEngine::cmd_draw, + &AgiEngine::cmd_erase, + &AgiEngine::cmd_position, + &AgiEngine::cmd_position_f, + &AgiEngine::cmd_get_posn, + &AgiEngine::cmd_reposition, // 0x28 + &AgiEngine::cmd_set_view, + &AgiEngine::cmd_set_view_f, + &AgiEngine::cmd_set_loop, + &AgiEngine::cmd_set_loop_f, + &AgiEngine::cmd_fix_loop, + &AgiEngine::cmd_release_loop, + &AgiEngine::cmd_set_cel, + &AgiEngine::cmd_set_cel_f, // 0x30 + &AgiEngine::cmd_last_cel, + &AgiEngine::cmd_current_cel, + &AgiEngine::cmd_current_loop, + &AgiEngine::cmd_current_view, + &AgiEngine::cmd_number_of_loops, + &AgiEngine::cmd_set_priority, + &AgiEngine::cmd_set_priority_f, + &AgiEngine::cmd_release_priority, // 0x38 + &AgiEngine::cmd_get_priority, + &AgiEngine::cmd_stop_update, + &AgiEngine::cmd_start_update, + &AgiEngine::cmd_force_update, + &AgiEngine::cmd_ignore_horizon, + &AgiEngine::cmd_observe_horizon, + &AgiEngine::cmd_set_horizon, + &AgiEngine::cmd_object_on_water, // 0x40 + &AgiEngine::cmd_object_on_land, + &AgiEngine::cmd_object_on_anything, + &AgiEngine::cmd_ignore_objs, + &AgiEngine::cmd_observe_objs, + &AgiEngine::cmd_distance, + &AgiEngine::cmd_stop_cycling, + &AgiEngine::cmd_start_cycling, + &AgiEngine::cmd_normal_cycle, // 0x48 + &AgiEngine::cmd_end_of_loop, + &AgiEngine::cmd_reverse_cycle, + &AgiEngine::cmd_reverse_loop, + &AgiEngine::cmd_cycle_time, + &AgiEngine::cmd_stop_motion, + &AgiEngine::cmd_start_motion, + &AgiEngine::cmd_step_size, + &AgiEngine::cmd_step_time, // 0x50 + &AgiEngine::cmd_move_obj, + &AgiEngine::cmd_move_obj_f, + &AgiEngine::cmd_follow_ego, + &AgiEngine::cmd_wander, + &AgiEngine::cmd_normal_motion, + &AgiEngine::cmd_set_dir, + &AgiEngine::cmd_get_dir, + &AgiEngine::cmd_ignore_blocks, // 0x58 + &AgiEngine::cmd_observe_blocks, + &AgiEngine::cmd_block, + &AgiEngine::cmd_unblock, + &AgiEngine::cmd_get, + &AgiEngine::cmd_get_f, + &AgiEngine::cmd_drop, + &AgiEngine::cmd_put, + &AgiEngine::cmd_put_f, // 0x60 + &AgiEngine::cmd_get_room_f, + &AgiEngine::cmd_load_sound, + &AgiEngine::cmd_sound, + &AgiEngine::cmd_stop_sound, + &AgiEngine::cmd_print, + &AgiEngine::cmd_print_f, + &AgiEngine::cmd_display, + &AgiEngine::cmd_display_f, // 0x68 + &AgiEngine::cmd_clear_lines, + &AgiEngine::cmd_text_screen, + &AgiEngine::cmd_graphics, + &AgiEngine::cmd_set_cursor_char, + &AgiEngine::cmd_set_text_attribute, + &AgiEngine::cmd_shake_screen, + &AgiEngine::cmd_configure_screen, + &AgiEngine::cmd_status_line_on, // 0x70 + &AgiEngine::cmd_status_line_off, + &AgiEngine::cmd_set_string, + &AgiEngine::cmd_get_string, + &AgiEngine::cmd_word_to_string, + &AgiEngine::cmd_parse, + &AgiEngine::cmd_get_num, + &AgiEngine::cmd_prevent_input, + &AgiEngine::cmd_accept_input, // 0x78 + &AgiEngine::cmd_set_key, + &AgiEngine::cmd_add_to_pic, + &AgiEngine::cmd_add_to_pic_f, + &AgiEngine::cmd_status, + &AgiEngine::cmd_save_game, + &AgiEngine::cmd_load_game, + &AgiEngine::cmd_init_disk, + &AgiEngine::cmd_restart_game, // 0x80 + &AgiEngine::cmd_show_obj, + &AgiEngine::cmd_random, + &AgiEngine::cmd_program_control, + &AgiEngine::cmd_player_control, + &AgiEngine::cmd_obj_status_f, + &AgiEngine::cmd_quit, + &AgiEngine::cmd_show_mem, + &AgiEngine::cmd_pause, // 0x88 + &AgiEngine::cmd_echo_line, + &AgiEngine::cmd_cancel_line, + &AgiEngine::cmd_init_joy, + &AgiEngine::cmd_toggle_monitor, + &AgiEngine::cmd_version, + &AgiEngine::cmd_script_size, + &AgiEngine::cmd_set_game_id, + &AgiEngine::cmd_log, // 0x90 + &AgiEngine::cmd_set_scan_start, + &AgiEngine::cmd_reset_scan_start, + &AgiEngine::cmd_reposition_to, + &AgiEngine::cmd_reposition_to_f, + &AgiEngine::cmd_trace_on, + &AgiEngine::cmd_trace_info, + &AgiEngine::cmd_print_at, + &AgiEngine::cmd_print_at_v, // 0x98 + &AgiEngine::cmd_discard_view, // Opcode repeated from 0x20 ? + &AgiEngine::cmd_clear_text_rect, + &AgiEngine::cmd_set_upper_left, + &AgiEngine::cmd_set_menu, + &AgiEngine::cmd_set_menu_item, + &AgiEngine::cmd_submit_menu, + &AgiEngine::cmd_enable_item, + &AgiEngine::cmd_disable_item, // 0xa0 + &AgiEngine::cmd_menu_input, + &AgiEngine::cmd_show_obj_v, + &AgiEngine::cmd_open_dialogue, + &AgiEngine::cmd_close_dialogue, + &AgiEngine::cmd_mul_n, + &AgiEngine::cmd_mul_v, + &AgiEngine::cmd_div_n, + &AgiEngine::cmd_div_v, // 0xa8 + &AgiEngine::cmd_close_window, + &AgiEngine::cmd_set_simple, + &AgiEngine::cmd_push_script, + &AgiEngine::cmd_pop_script, + &AgiEngine::cmd_hold_key, + &AgiEngine::cmd_set_pri_base, + &AgiEngine::cmd_discard_sound, + &AgiEngine::cmd_hide_mouse, // 0xb0 + &AgiEngine::cmd_allow_menu, + &AgiEngine::cmd_show_mouse, + &AgiEngine::cmd_fence_mouse, + &AgiEngine::cmd_mouse_posn, + &AgiEngine::cmd_release_key, + &AgiEngine::cmd_adj_ego_move_to_x_y + }; + assert(ARRAYSIZE(_agiCommands) == ARRAYSIZE(tmp)); + for (int i = 0; i < ARRAYSIZE(tmp); ++i) + _agiCommands[i] = tmp[i]; +} /** * Execute a logic script @@ -1781,6 +1770,9 @@ int AgiEngine::runLogic(int n) { int num = 0; ScriptPos sp; + debugC(2, kDebugLevelScripts, "================="); + debugC(2, kDebugLevelScripts, "runLogic(%d)", n); + sp.script = n; sp.curIP = 0; _game.execStack.push_back(sp); @@ -1792,12 +1784,12 @@ int AgiEngine::runLogic(int n) { } _game.lognum = n; - curLogic = &_game.logics[_game.lognum]; + _curLogic = &_game.logics[_game.lognum]; - code = curLogic->data; - curLogic->cIP = curLogic->sIP; + code = _curLogic->data; + _curLogic->cIP = _curLogic->sIP; - timerHack = 0; + _timerHack = 0; while (ip < _game.logics[n].size && !(shouldQuit() || _restartGame)) { if (_debug.enabled) { if (_debug.steps > 0) { @@ -1807,6 +1799,7 @@ int AgiEngine::runLogic(int n) { } } else { _sprites->blitBoth(); + _sprites->commitBoth(); do { mainCycle(); } while (!_debug.steps && _debug.enabled); @@ -1816,6 +1809,11 @@ int AgiEngine::runLogic(int n) { _game.execStack.back().curIP = ip; + char st[101]; + int sz = MIN(_game.execStack.size(), 100u); + memset(st, '.', sz); + st[sz] = 0; + switch (op = *(code + ip++)) { case 0xff: // if (open/close) testIfCode(n); @@ -1826,13 +1824,16 @@ int AgiEngine::runLogic(int n) { // timer must keep running even in goto loops, // but AGI engine can't do that :( - if (timerHack > 20) { + if (_timerHack > 20) { pollTimer(); updateTimer(); - timerHack = 0; + _timerHack = 0; } break; case 0x00: // return + debugC(2, kDebugLevelScripts, "%sreturn() // Logic %d", st, n); + debugC(2, kDebugLevelScripts, "================="); + _game.execStack.pop_back(); return 1; default: @@ -1840,8 +1841,9 @@ int AgiEngine::runLogic(int n) { memmove(p, code + ip, num); memset(p + num, 0, CMD_BSIZE - num); - debugC(2, kDebugLevelScripts, "%s(%d %d %d)", logicNamesCmd[op].name, p[0], p[1], p[2]); - agiCommand[op](this, p); + debugC(2, kDebugLevelScripts, "%s%s(%d %d %d)", st, logicNamesCmd[op].name, p[0], p[1], p[2]); + + (this->*_agiCommands[op])(p); ip += num; } @@ -1857,7 +1859,7 @@ int AgiEngine::runLogic(int n) { void AgiEngine::executeAgiCommand(uint8 op, uint8 *p) { debugC(2, kDebugLevelScripts, "%s(%d %d %d)", logicNamesCmd[op].name, p[0], p[1], p[2]); - agiCommand[op] (this, p); + (this->*_agiCommands[op])(p); } } // End of namespace Agi |