aboutsummaryrefslogtreecommitdiff
path: root/engines
diff options
context:
space:
mode:
authorAlyssa Milburn2011-08-17 09:28:51 +0200
committerAlyssa Milburn2011-08-17 09:28:51 +0200
commitae287ccee58ebf68ab6125e5bbb4d8a44874330e (patch)
tree2f4cee4b2940466b8a578962e0174c6f89077a40 /engines
parentf5255288eabc0527c4c6b727a9db6b8d09a31206 (diff)
parente36832bbf84cba88fe6b17e1634fab0d550f13df (diff)
downloadscummvm-rg350-ae287ccee58ebf68ab6125e5bbb4d8a44874330e.tar.gz
scummvm-rg350-ae287ccee58ebf68ab6125e5bbb4d8a44874330e.tar.bz2
scummvm-rg350-ae287ccee58ebf68ab6125e5bbb4d8a44874330e.zip
Merge remote-tracking branch 'origin/master' into soccer
Conflicts: engines/scumm/he/logic_he.cpp engines/scumm/he/logic_he.h
Diffstat (limited to 'engines')
-rw-r--r--engines/agi/agi.cpp12
-rw-r--r--engines/agi/agi.h259
-rw-r--r--engines/agi/checks.cpp30
-rw-r--r--engines/agi/console.cpp34
-rw-r--r--engines/agi/console.h32
-rw-r--r--engines/agi/cycle.cpp6
-rw-r--r--engines/agi/detection.cpp29
-rw-r--r--engines/agi/detection_tables.h87
-rw-r--r--engines/agi/id.cpp18
-rw-r--r--engines/agi/keyboard.cpp4
-rw-r--r--engines/agi/loader_v1.cpp329
-rw-r--r--engines/agi/module.mk3
-rw-r--r--engines/agi/motion.cpp28
-rw-r--r--engines/agi/objects.cpp36
-rw-r--r--engines/agi/op_cmd.cpp1442
-rw-r--r--engines/agi/op_dbg.cpp255
-rw-r--r--engines/agi/op_test.cpp435
-rw-r--r--engines/agi/opcodes.cpp381
-rw-r--r--engines/agi/opcodes.h246
-rw-r--r--engines/agi/preagi.cpp230
-rw-r--r--engines/agi/preagi.h25
-rw-r--r--engines/agi/preagi_common.cpp205
-rw-r--r--engines/agi/preagi_common.h51
-rw-r--r--engines/agi/preagi_mickey.cpp1068
-rw-r--r--engines/agi/preagi_mickey.h18
-rw-r--r--engines/agi/preagi_troll.cpp305
-rw-r--r--engines/agi/preagi_troll.h13
-rw-r--r--engines/agi/preagi_winnie.cpp575
-rw-r--r--engines/agi/preagi_winnie.h13
-rw-r--r--engines/agi/saveload.cpp4
-rw-r--r--engines/agi/sound.cpp27
-rw-r--r--engines/agi/sound.h10
-rw-r--r--engines/agi/sound_2gs.cpp2
-rw-r--r--engines/agi/sound_2gs.h2
-rw-r--r--engines/agi/sound_coco3.cpp2
-rw-r--r--engines/agi/sound_coco3.h2
-rw-r--r--engines/agi/sound_midi.cpp2
-rw-r--r--engines/agi/sound_midi.h2
-rw-r--r--engines/agi/sound_pcjr.cpp166
-rw-r--r--engines/agi/sound_pcjr.h17
-rw-r--r--engines/agi/sound_sarien.cpp2
-rw-r--r--engines/agi/sound_sarien.h2
-rw-r--r--engines/agi/sprite.cpp14
-rw-r--r--engines/agi/view.cpp57
-rw-r--r--engines/agi/view.h66
-rw-r--r--engines/agi/words.cpp136
-rw-r--r--engines/agos/detection_tables.h52
-rw-r--r--engines/composer/composer.cpp66
-rw-r--r--engines/composer/composer.h3
-rw-r--r--engines/composer/detection.cpp26
-rw-r--r--engines/composer/graphics.cpp22
-rw-r--r--engines/dreamweb/dreamgen.cpp1951
-rw-r--r--engines/dreamweb/dreamgen.h163
-rw-r--r--engines/dreamweb/module.mk5
-rw-r--r--engines/dreamweb/print.cpp224
-rw-r--r--engines/dreamweb/runtime.h6
-rw-r--r--engines/dreamweb/sprite.cpp874
-rw-r--r--engines/dreamweb/structs.h99
-rw-r--r--engines/dreamweb/stubs.cpp1503
-rw-r--r--engines/dreamweb/stubs.h76
-rw-r--r--engines/dreamweb/vgagrafx.cpp452
-rw-r--r--engines/made/detection.cpp30
-rw-r--r--engines/mohawk/cursors.cpp37
-rw-r--r--engines/mohawk/detection_tables.h84
-rw-r--r--engines/mohawk/dialogs.cpp18
-rw-r--r--engines/mohawk/dialogs.h1
-rw-r--r--engines/mohawk/graphics.cpp11
-rw-r--r--engines/mohawk/graphics.h4
-rw-r--r--engines/mohawk/myst.cpp6
-rw-r--r--engines/mohawk/myst.h1
-rw-r--r--engines/mohawk/myst_stacks/demo.cpp98
-rw-r--r--engines/mohawk/myst_stacks/demo.h14
-rw-r--r--engines/mohawk/myst_stacks/myst.h4
-rw-r--r--engines/mohawk/myst_stacks/preview.cpp211
-rw-r--r--engines/mohawk/myst_stacks/preview.h27
-rw-r--r--engines/mohawk/myst_stacks/slides.cpp10
-rw-r--r--engines/mohawk/riven.cpp175
-rw-r--r--engines/mohawk/riven.h8
-rw-r--r--engines/mohawk/riven_external.cpp32
-rw-r--r--engines/mohawk/riven_vars.cpp8
-rw-r--r--engines/mohawk/sound.cpp2
-rw-r--r--engines/saga/detection_tables.h16
-rw-r--r--engines/scumm/cursor.cpp77
-rw-r--r--engines/scumm/he/intern_he.h2
-rw-r--r--engines/scumm/he/logic/basketball.cpp105
-rw-r--r--engines/scumm/player_v2cms.cpp39
-rw-r--r--engines/scumm/player_v2cms.h10
-rw-r--r--engines/scumm/sound.cpp4
-rw-r--r--engines/tinsel/detection_tables.h26
-rw-r--r--engines/toon/path.cpp29
-rw-r--r--engines/tsage/blue_force/blueforce_logic.cpp255
-rw-r--r--engines/tsage/blue_force/blueforce_logic.h (renamed from engines/tsage/blueforce_logic.h)61
-rw-r--r--engines/tsage/blue_force/blueforce_scenes0.cpp (renamed from engines/tsage/blueforce_scenes0.cpp)72
-rw-r--r--engines/tsage/blue_force/blueforce_scenes0.h (renamed from engines/tsage/blueforce_scenes0.h)39
-rw-r--r--engines/tsage/blue_force/blueforce_scenes1.cpp432
-rw-r--r--engines/tsage/blue_force/blueforce_scenes1.h132
-rw-r--r--engines/tsage/blueforce_logic.cpp123
-rw-r--r--engines/tsage/converse.cpp47
-rw-r--r--engines/tsage/converse.h8
-rw-r--r--engines/tsage/core.cpp55
-rw-r--r--engines/tsage/core.h31
-rw-r--r--engines/tsage/debugger.cpp6
-rw-r--r--engines/tsage/debugger.h4
-rw-r--r--engines/tsage/detection.cpp16
-rw-r--r--engines/tsage/detection_tables.h16
-rw-r--r--engines/tsage/dialogs.cpp6
-rw-r--r--engines/tsage/dialogs.h4
-rw-r--r--engines/tsage/events.cpp6
-rw-r--r--engines/tsage/events.h4
-rw-r--r--engines/tsage/globals.cpp69
-rw-r--r--engines/tsage/globals.h32
-rw-r--r--engines/tsage/graphics.cpp22
-rw-r--r--engines/tsage/graphics.h6
-rw-r--r--engines/tsage/module.mk25
-rw-r--r--engines/tsage/resources.cpp4
-rw-r--r--engines/tsage/resources.h4
-rw-r--r--engines/tsage/ringworld/ringworld_demo.cpp (renamed from engines/tsage/ringworld_demo.cpp)10
-rw-r--r--engines/tsage/ringworld/ringworld_demo.h (renamed from engines/tsage/ringworld_demo.h)10
-rw-r--r--engines/tsage/ringworld/ringworld_logic.cpp (renamed from engines/tsage/ringworld_logic.cpp)30
-rw-r--r--engines/tsage/ringworld/ringworld_logic.h (renamed from engines/tsage/ringworld_logic.h)12
-rw-r--r--engines/tsage/ringworld/ringworld_scenes1.cpp (renamed from engines/tsage/ringworld_scenes1.cpp)10
-rw-r--r--engines/tsage/ringworld/ringworld_scenes1.h (renamed from engines/tsage/ringworld_scenes1.h)12
-rw-r--r--engines/tsage/ringworld/ringworld_scenes10.cpp (renamed from engines/tsage/ringworld_scenes10.cpp)10
-rw-r--r--engines/tsage/ringworld/ringworld_scenes10.h (renamed from engines/tsage/ringworld_scenes10.h)11
-rw-r--r--engines/tsage/ringworld/ringworld_scenes2.cpp (renamed from engines/tsage/ringworld_scenes2.cpp)10
-rw-r--r--engines/tsage/ringworld/ringworld_scenes2.h (renamed from engines/tsage/ringworld_scenes2.h)12
-rw-r--r--engines/tsage/ringworld/ringworld_scenes3.cpp (renamed from engines/tsage/ringworld_scenes3.cpp)10
-rw-r--r--engines/tsage/ringworld/ringworld_scenes3.h (renamed from engines/tsage/ringworld_scenes3.h)12
-rw-r--r--engines/tsage/ringworld/ringworld_scenes4.cpp (renamed from engines/tsage/ringworld_scenes4.cpp)12
-rw-r--r--engines/tsage/ringworld/ringworld_scenes4.h (renamed from engines/tsage/ringworld_scenes4.h)12
-rw-r--r--engines/tsage/ringworld/ringworld_scenes5.cpp (renamed from engines/tsage/ringworld_scenes5.cpp)12
-rw-r--r--engines/tsage/ringworld/ringworld_scenes5.h (renamed from engines/tsage/ringworld_scenes5.h)11
-rw-r--r--engines/tsage/ringworld/ringworld_scenes6.cpp (renamed from engines/tsage/ringworld_scenes6.cpp)9
-rw-r--r--engines/tsage/ringworld/ringworld_scenes6.h (renamed from engines/tsage/ringworld_scenes6.h)11
-rw-r--r--engines/tsage/ringworld/ringworld_scenes8.cpp (renamed from engines/tsage/ringworld_scenes8.cpp)10
-rw-r--r--engines/tsage/ringworld/ringworld_scenes8.h (renamed from engines/tsage/ringworld_scenes8.h)12
-rw-r--r--engines/tsage/saveload.cpp4
-rw-r--r--engines/tsage/saveload.h4
-rw-r--r--engines/tsage/scenes.cpp19
-rw-r--r--engines/tsage/scenes.h5
-rw-r--r--engines/tsage/sound.cpp4
-rw-r--r--engines/tsage/sound.h4
-rw-r--r--engines/tsage/staticres.cpp34
-rw-r--r--engines/tsage/staticres.h32
-rw-r--r--engines/tsage/tsage.cpp10
-rw-r--r--engines/tsage/tsage.h4
146 files changed, 8425 insertions, 6705 deletions
diff --git a/engines/agi/agi.cpp b/engines/agi/agi.cpp
index 0eefbab04d..4bebf97e95 100644
--- a/engines/agi/agi.cpp
+++ b/engines/agi/agi.cpp
@@ -504,6 +504,7 @@ AgiBase::AgiBase(OSystem *syst, const AGIGameDescription *gameDesc) : Engine(sys
_noSaveLoadAllowed = false;
_rnd = new Common::RandomSource("agi");
+ _sound = 0;
initFeatures();
initVersion();
@@ -511,6 +512,11 @@ AgiBase::AgiBase(OSystem *syst, const AGIGameDescription *gameDesc) : Engine(sys
AgiBase::~AgiBase() {
delete _rnd;
+
+ if (_sound) {
+ _sound->deinitSound();
+ delete _sound;
+ }
}
AgiEngine::AgiEngine(OSystem *syst, const AGIGameDescription *gameDesc) : AgiBase(syst, gameDesc) {
@@ -536,6 +542,8 @@ AgiEngine::AgiEngine(OSystem *syst, const AGIGameDescription *gameDesc) : AgiBas
memset(&_debug, 0, sizeof(struct AgiDebug));
memset(&_mouse, 0, sizeof(struct Mouse));
+ _game._vm = this;
+
_game.clockEnabled = false;
_game.state = STATE_INIT;
@@ -571,7 +579,7 @@ AgiEngine::AgiEngine(OSystem *syst, const AGIGameDescription *gameDesc) : AgiBas
_game.controllerOccured[i] = false;
setupOpcodes();
- _curLogic = NULL;
+ _game._curLogic = NULL;
_timerHack = 0;
}
@@ -680,8 +688,6 @@ AgiEngine::~AgiEngine() {
agiDeinit();
delete _loader;
- _sound->deinitSound();
- delete _sound;
_gfx->deinitVideo();
delete _sprites;
delete _picture;
diff --git a/engines/agi/agi.h b/engines/agi/agi.h
index 0155caf11d..080373d27b 100644
--- a/engines/agi/agi.h
+++ b/engines/agi/agi.h
@@ -88,6 +88,7 @@ typedef signed int Err;
#define _EMPTY 0xfffff
#define EGO_OWNED 0xff
+#define EGO_OWNED_V1 0xf9
#define CRYPT_KEY_SIERRA "Avis Durgan"
#define CRYPT_KEY_AGDS "Alex Simkin"
@@ -131,10 +132,16 @@ enum AgiGameID {
enum AgiGameType {
GType_PreAGI = 0,
- GType_V2 = 1,
- GType_V3 = 2
+ GType_V1 = 1,
+ GType_V2 = 2,
+ GType_V3 = 3
};
+ enum BooterDisks {
+ BooterDisk1 = 0,
+ BooterDisk2 = 1
+ };
+
//
// GF_OLDAMIGAV20 means that the interpreter is an old Amiga AGI interpreter that
// uses value 20 for the computer type (v20 i.e. vComputer) rather than the usual value 5.
@@ -537,6 +544,8 @@ enum {
* by the interpreter.
*/
struct AgiGame {
+ AgiEngine *_vm;
+
State state; /**< state of the interpreter */
// TODO: Check whether adjMouseX and adjMouseY must be saved and loaded when using savegames.
@@ -621,6 +630,11 @@ struct AgiGame {
AgiView views[MAX_DIRS]; /**< AGI view resources */
AgiSound *sounds[MAX_DIRS]; /**< Pointers to AGI sound resources */
+ AgiLogic *_curLogic;
+
+ // words
+ Common::Array<AgiWord*> words[26];
+
// view table
VtEntry viewTable[MAX_VIEWTABLE];
@@ -629,6 +643,13 @@ struct AgiGame {
int simpleSave; /**< select simple savegames */
Common::Rect mouseFence; /**< rectangle set by fence.mouse command */
+
+ // IF condition handling
+ int testResult;
+
+
+ int max_logics;
+ int logic_list[256];
};
class AgiLoader {
@@ -646,6 +667,28 @@ public:
virtual int loadWords(const char *) = 0;
};
+class AgiLoader_v1 : public AgiLoader {
+private:
+ AgiEngine *_vm;
+ Common::String _filenameDisk0;
+ Common::String _filenameDisk1;
+
+ int loadDir_DDP(AgiDir *agid, int offset, int max);
+ int loadDir_BC(AgiDir *agid, int offset, int max);
+ uint8 *loadVolRes(AgiDir *agid);
+
+public:
+ AgiLoader_v1(AgiEngine *vm);
+
+ virtual int init();
+ virtual int deinit();
+ virtual int detectGame();
+ virtual int loadResource(int, int);
+ virtual int unloadResource(int, int);
+ virtual int loadObjects(const char *);
+ virtual int loadWords(const char *);
+};
+
class AgiLoader_v2 : public AgiLoader {
private:
AgiEngine *_vm;
@@ -690,6 +733,7 @@ public:
virtual int loadWords(const char *);
};
+
class GfxMgr;
class SpritesMgr;
class Menu;
@@ -745,6 +789,8 @@ public:
AgiGame _game;
Common::RandomSource *_rnd;
+ SoundMgr *_sound;
+
Mouse _mouse;
bool _noSaveLoadAllowed;
@@ -789,10 +835,14 @@ public:
void initVersion();
void setVersion(uint16 version);
+ const char *getDiskName(uint16 id);
+
bool canLoadGameStateCurrently();
bool canSaveGameStateCurrently();
};
+typedef void (*AgiCommand)(AgiGame *state, uint8 *p);
+
class AgiEngine : public AgiBase {
protected:
// Engine APIs
@@ -851,7 +901,6 @@ public:
char _lastSentence[40];
SpritesMgr *_sprites;
- SoundMgr *_sound;
PictureMgr *_picture;
AgiLoader *_loader; // loader
@@ -915,16 +964,21 @@ public:
void checkQuickLoad();
// Objects
+public:
int showObjects();
- int decodeObjects(uint8 *mem, uint32 flen);
int loadObjects(const char *fname);
- int allocObjects(int);
+ int loadObjects(Common::File &fp);
void unloadObjects();
const char *objectName(unsigned int);
int objectGetLocation(unsigned int);
void objectSetLocation(unsigned int, int);
+private:
+ int decodeObjects(uint8 *mem, uint32 flen);
+ int readObjects(Common::File &fp, int flen);
+ int allocObjects(int);
// Logic
+public:
int decodeLogic(int);
void unloadLogic(int);
int runLogic(int);
@@ -932,8 +986,10 @@ public:
int testIfCode(int);
void executeAgiCommand(uint8, uint8 *);
-private:
+public:
// Some submethods of testIfCode
+ void skipInstruction(byte op);
+ void skipInstructionsUntil(byte v);
uint8 testObjRight(uint8, uint8, uint8, uint8, uint8);
uint8 testObjCenter(uint8, uint8, uint8, uint8, uint8);
uint8 testObjInBox(uint8, uint8, uint8, uint8, uint8);
@@ -966,8 +1022,10 @@ public:
bool isEgoView(const VtEntry *v);
// Words
+public:
int showWords();
int loadWords(const char *);
+ int loadWords_v1(Common::File &f);
void unloadWords();
int findWord(const char *word, int *flen);
void dictionaryWords(char *);
@@ -1045,196 +1103,13 @@ public:
char _predictiveResult[40];
private:
- typedef void (AgiEngine::*AgiCommand)(uint8 *);
-
AgiCommand _agiCommands[183];
- AgiLogic *_curLogic;
- int _timerHack; // Workaround for timer loop in MH1 logic 153
+ AgiCommand _agiCondCommands[256];
void setupOpcodes();
- void cmd_increment(uint8 *p);
- void cmd_decrement(uint8 *p);
- void cmd_assignn(uint8 *p);
- void cmd_assignv(uint8 *p);
- void cmd_addn(uint8 *p);
- void cmd_addv(uint8 *p);
- void cmd_subn(uint8 *p);
- void cmd_subv(uint8 *p); // 0x08
- void cmd_lindirectv(uint8 *p);
- void cmd_rindirect(uint8 *p);
- void cmd_lindirectn(uint8 *p);
- void cmd_set(uint8 *p);
- void cmd_reset(uint8 *p);
- void cmd_toggle(uint8 *p);
- void cmd_set_v(uint8 *p);
- void cmd_reset_v(uint8 *p); // 0x10
- void cmd_toggle_v(uint8 *p);
- void cmd_new_room(uint8 *p);
- void cmd_new_room_f(uint8 *p);
- void cmd_load_logic(uint8 *p);
- void cmd_load_logic_f(uint8 *p);
- void cmd_call(uint8 *p);
- void cmd_call_f(uint8 *p);
- void cmd_load_pic(uint8 *p); // 0x18
- void cmd_draw_pic(uint8 *p);
- void cmd_show_pic(uint8 *p);
- void cmd_discard_pic(uint8 *p);
- void cmd_overlay_pic(uint8 *p);
- void cmd_show_pri_screen(uint8 *p);
- void cmd_load_view(uint8 *p);
- void cmd_load_view_f(uint8 *p);
- void cmd_discard_view(uint8 *p); // 0x20
- void cmd_animate_obj(uint8 *p);
- void cmd_unanimate_all(uint8 *p);
- void cmd_draw(uint8 *p);
- void cmd_erase(uint8 *p);
- void cmd_position(uint8 *p);
- void cmd_position_f(uint8 *p);
- void cmd_get_posn(uint8 *p);
- void cmd_reposition(uint8 *p); // 0x28
- void cmd_set_view(uint8 *p);
- void cmd_set_view_f(uint8 *p);
- void cmd_set_loop(uint8 *p);
- void cmd_set_loop_f(uint8 *p);
- void cmd_fix_loop(uint8 *p);
- void cmd_release_loop(uint8 *p);
- void cmd_set_cel(uint8 *p);
- void cmd_set_cel_f(uint8 *p); // 0x30
- void cmd_last_cel(uint8 *p);
- void cmd_current_cel(uint8 *p);
- void cmd_current_loop(uint8 *p);
- void cmd_current_view(uint8 *p);
- void cmd_number_of_loops(uint8 *p);
- void cmd_set_priority(uint8 *p);
- void cmd_set_priority_f(uint8 *p);
- void cmd_release_priority(uint8 *p); // 0x38
- void cmd_get_priority(uint8 *p);
- void cmd_stop_update(uint8 *p);
- void cmd_start_update(uint8 *p);
- void cmd_force_update(uint8 *p);
- void cmd_ignore_horizon(uint8 *p);
- void cmd_observe_horizon(uint8 *p);
- void cmd_set_horizon(uint8 *p);
- void cmd_object_on_water(uint8 *p); // 0x40
- void cmd_object_on_land(uint8 *p);
- void cmd_object_on_anything(uint8 *p);
- void cmd_ignore_objs(uint8 *p);
- void cmd_observe_objs(uint8 *p);
- void cmd_distance(uint8 *p);
- void cmd_stop_cycling(uint8 *p);
- void cmd_start_cycling(uint8 *p);
- void cmd_normal_cycle(uint8 *p); // 0x48
- void cmd_end_of_loop(uint8 *p);
- void cmd_reverse_cycle(uint8 *p);
- void cmd_reverse_loop(uint8 *p);
- void cmd_cycle_time(uint8 *p);
- void cmd_stop_motion(uint8 *p);
- void cmd_start_motion(uint8 *p);
- void cmd_step_size(uint8 *p);
- void cmd_step_time(uint8 *p); // 0x50
- void cmd_move_obj(uint8 *p);
- void cmd_move_obj_f(uint8 *p);
- void cmd_follow_ego(uint8 *p);
- void cmd_wander(uint8 *p);
- void cmd_normal_motion(uint8 *p);
- void cmd_set_dir(uint8 *p);
- void cmd_get_dir(uint8 *p);
- void cmd_ignore_blocks(uint8 *p); // 0x58
- void cmd_observe_blocks(uint8 *p);
- void cmd_block(uint8 *p);
- void cmd_unblock(uint8 *p);
- void cmd_get(uint8 *p);
- void cmd_get_f(uint8 *p);
- void cmd_drop(uint8 *p);
- void cmd_put(uint8 *p);
- void cmd_put_f(uint8 *p); // 0x60
- void cmd_get_room_f(uint8 *p);
- void cmd_load_sound(uint8 *p);
- void cmd_sound(uint8 *p);
- void cmd_stop_sound(uint8 *p);
- void cmd_print(uint8 *p);
- void cmd_print_f(uint8 *p);
- void cmd_display(uint8 *p);
- void cmd_display_f(uint8 *p); // 0x68
- void cmd_clear_lines(uint8 *p);
- void cmd_text_screen(uint8 *p);
- void cmd_graphics(uint8 *p);
- void cmd_set_cursor_char(uint8 *p);
- void cmd_set_text_attribute(uint8 *p);
- void cmd_shake_screen(uint8 *p);
- void cmd_configure_screen(uint8 *p);
- void cmd_status_line_on(uint8 *p); // 0x70
- void cmd_status_line_off(uint8 *p);
- void cmd_set_string(uint8 *p);
- void cmd_get_string(uint8 *p);
- void cmd_word_to_string(uint8 *p);
- void cmd_parse(uint8 *p);
- void cmd_get_num(uint8 *p);
- void cmd_prevent_input(uint8 *p);
- void cmd_accept_input(uint8 *p); // 0x78
- void cmd_set_key(uint8 *p);
- void cmd_add_to_pic(uint8 *p);
- void cmd_add_to_pic_f(uint8 *p);
- void cmd_status(uint8 *p);
- void cmd_save_game(uint8 *p);
- void cmd_load_game(uint8 *p);
- void cmd_init_disk(uint8 *p);
- void cmd_restart_game(uint8 *p); // 0x80
- void cmd_show_obj(uint8 *p);
- void cmd_random(uint8 *p);
- void cmd_program_control(uint8 *p);
- void cmd_player_control(uint8 *p);
- void cmd_obj_status_f(uint8 *p);
- void cmd_quit(uint8 *p);
- void cmd_show_mem(uint8 *p);
- void cmd_pause(uint8 *p); // 0x88
- void cmd_echo_line(uint8 *p);
- void cmd_cancel_line(uint8 *p);
- void cmd_init_joy(uint8 *p);
- void cmd_toggle_monitor(uint8 *p);
- void cmd_version(uint8 *p);
- void cmd_script_size(uint8 *p);
- void cmd_set_game_id(uint8 *p);
- void cmd_log(uint8 *p); // 0x90
- void cmd_set_scan_start(uint8 *p);
- void cmd_reset_scan_start(uint8 *p);
- void cmd_reposition_to(uint8 *p);
- void cmd_reposition_to_f(uint8 *p);
- void cmd_trace_on(uint8 *p);
- void cmd_trace_info(uint8 *p);
- void cmd_print_at(uint8 *p);
- void cmd_print_at_v(uint8 *p); // 0x98
- //void cmd_discard_view(uint8 *p); // Opcode repeated from 0x20 ?
- void cmd_clear_text_rect(uint8 *p);
- void cmd_set_upper_left(uint8 *p);
- void cmd_set_menu(uint8 *p);
- void cmd_set_menu_item(uint8 *p);
- void cmd_submit_menu(uint8 *p);
- void cmd_enable_item(uint8 *p);
- void cmd_disable_item(uint8 *p); // 0xa0
- void cmd_menu_input(uint8 *p);
- void cmd_show_obj_v(uint8 *p);
- void cmd_open_dialogue(uint8 *p);
- void cmd_close_dialogue(uint8 *p);
- void cmd_mul_n(uint8 *p);
- void cmd_mul_v(uint8 *p);
- void cmd_div_n(uint8 *p);
- void cmd_div_v(uint8 *p); // 0xa8
- void cmd_close_window(uint8 *p);
- void cmd_set_simple(uint8 *p);
- void cmd_push_script(uint8 *p);
- void cmd_pop_script(uint8 *p);
- void cmd_hold_key(uint8 *p);
- void cmd_set_pri_base(uint8 *p);
- void cmd_discard_sound(uint8 *p);
- void cmd_hide_mouse(uint8 *p); // 0xb0
- void cmd_allow_menu(uint8 *p);
- void cmd_show_mouse(uint8 *p);
- void cmd_fence_mouse(uint8 *p);
- void cmd_mouse_posn(uint8 *p);
- void cmd_release_key(uint8 *p);
- void cmd_adj_ego_move_to_x_y(uint8 *p);
+public:
+ int _timerHack; // Workaround for timer loop in MH1 logic 153
};
} // End of namespace Agi
diff --git a/engines/agi/checks.cpp b/engines/agi/checks.cpp
index 20276657ff..c3b31f6ba9 100644
--- a/engines/agi/checks.cpp
+++ b/engines/agi/checks.cpp
@@ -31,7 +31,7 @@ int AgiEngine::checkPosition(VtEntry *v) {
v->xPos + v->xSize > _WIDTH ||
v->yPos - v->ySize + 1 < 0 ||
v->yPos >= _HEIGHT ||
- ((~v->flags & IGNORE_HORIZON) && v->yPos <= _game.horizon)) {
+ ((~v->flags & fIgnoreHorizon) && v->yPos <= _game.horizon)) {
debugC(4, kDebugLevelSprites, "check position failed: x=%d, y=%d, h=%d, w=%d",
v->xPos, v->yPos, v->xSize, v->ySize);
return 0;
@@ -52,14 +52,14 @@ int AgiEngine::checkPosition(VtEntry *v) {
int AgiEngine::checkCollision(VtEntry *v) {
VtEntry *u;
- if (v->flags & IGNORE_OBJECTS)
+ if (v->flags & fIgnoreObjects)
return 0;
for (u = _game.viewTable; u < &_game.viewTable[MAX_VIEWTABLE]; u++) {
- if ((u->flags & (ANIMATED | DRAWN)) != (ANIMATED | DRAWN))
+ if ((u->flags & (fAnimated | fDrawn)) != (fAnimated | fDrawn))
continue;
- if (u->flags & IGNORE_OBJECTS)
+ if (u->flags & fIgnoreObjects)
continue;
// Same object, check next
@@ -92,7 +92,7 @@ int AgiEngine::checkPriority(VtEntry *v) {
int i, trigger, water, pass, pri;
uint8 *p0;
- if (~v->flags & FIXED_PRIORITY) {
+ if (~v->flags & fFixedPriority) {
// Priority bands
v->priority = _game.priTable[v->yPos];
}
@@ -129,7 +129,7 @@ int AgiEngine::checkPriority(VtEntry *v) {
water = 0;
if (pri == 1) { // conditional blue
- if (v->flags & IGNORE_BLOCKS)
+ if (v->flags & fIgnoreBlocks)
continue;
debugC(4, kDebugLevelSprites, "Blocks observed!");
@@ -145,9 +145,9 @@ int AgiEngine::checkPriority(VtEntry *v) {
}
if (pass) {
- if (!water && v->flags & ON_WATER)
+ if (!water && v->flags & fOnWater)
pass = 0;
- if (water && v->flags & ON_LAND)
+ if (water && v->flags & fOnLand)
pass = 0;
}
@@ -180,7 +180,7 @@ void AgiEngine::updatePosition() {
_game.vars[vBorderTouchObj] = 0;
for (v = _game.viewTable; v < &_game.viewTable[MAX_VIEWTABLE]; v++) {
- if ((v->flags & (ANIMATED | UPDATE | DRAWN)) != (ANIMATED | UPDATE | DRAWN)) {
+ if ((v->flags & (fAnimated | fUpdate | fDrawn)) != (fAnimated | fUpdate | fDrawn)) {
continue;
}
@@ -195,7 +195,7 @@ void AgiEngine::updatePosition() {
y = oldY = v->yPos;
// If object has moved, update its position
- if (~v->flags & UPDATE_POS) {
+ if (~v->flags & fUpdatePos) {
int dx[9] = { 0, 0, 1, 1, 1, 0, -1, -1, -1 };
int dy[9] = { 0, -1, -1, 0, 1, 1, 1, 0, -1 };
x += v->stepSize * dx[v->direction];
@@ -212,7 +212,7 @@ void AgiEngine::updatePosition() {
} else if (x <= 0 && getVersion() == 0x3086) { // KQ4
x = 0; // See Sarien bug #590462
border = 4;
- } else if (v->entry == 0 && x == 0 && v->flags & ADJ_EGO_XY) {
+ } else if (v->entry == 0 && x == 0 && v->flags & fAdjEgoXY) {
// Extra test to walk west clicking the mouse
x = 0;
border = 4;
@@ -228,7 +228,7 @@ void AgiEngine::updatePosition() {
} else if (y > _HEIGHT - 1) {
y = _HEIGHT - 1;
border = 3;
- } else if ((~v->flags & IGNORE_HORIZON) && y <= _game.horizon) {
+ } else if ((~v->flags & fIgnoreHorizon) && y <= _game.horizon) {
debugC(4, kDebugLevelSprites, "y = %d, horizon = %d", y, _game.horizon);
y = _game.horizon + 1;
border = 1;
@@ -251,12 +251,12 @@ void AgiEngine::updatePosition() {
_game.vars[vBorderCode] = v->entry;
_game.vars[vBorderTouchObj] = border;
}
- if (v->motion == MOTION_MOVE_OBJ) {
+ if (v->motion == kMotionMoveObj) {
inDestination(v);
}
}
- v->flags &= ~UPDATE_POS;
+ v->flags &= ~fUpdatePos;
}
}
@@ -276,7 +276,7 @@ void AgiEngine::fixPosition(int n) {
debugC(4, kDebugLevelSprites, "adjusting view table entry #%d (%d,%d)", n, v->xPos, v->yPos);
// test horizon
- if ((~v->flags & IGNORE_HORIZON) && v->yPos <= _game.horizon)
+ if ((~v->flags & fIgnoreHorizon) && v->yPos <= _game.horizon)
v->yPos = _game.horizon + 1;
dir = 0;
diff --git a/engines/agi/console.cpp b/engines/agi/console.cpp
index d49bd57ea2..dd06736290 100644
--- a/engines/agi/console.cpp
+++ b/engines/agi/console.cpp
@@ -96,8 +96,8 @@ bool Console::Cmd_RunOpcode(int argc, const char **argv) {
for (int i = 0; logicNamesCmd[i].name; i++) {
if (!strcmp(argv[1], logicNamesCmd[i].name)) {
uint8 p[16];
- if ((argc - 2) != logicNamesCmd[i].numArgs) {
- DebugPrintf("AGI command wants %d arguments\n", logicNamesCmd[i].numArgs);
+ if ((argc - 2) != logicNamesCmd[i].argumentsLength()) {
+ DebugPrintf("AGI command wants %d arguments\n", logicNamesCmd[i].argumentsLength());
return 0;
}
p[0] = argv[2] ? (char)strtoul(argv[2], NULL, 0) : 0;
@@ -260,7 +260,7 @@ bool Console::Cmd_BT(int argc, const char **argv) {
for (it = _vm->_game.execStack.begin(); it != _vm->_game.execStack.end(); ++it) {
code = _vm->_game.logics[it->script].data;
op = code[it->curIP];
- num = logicNamesCmd[op].numArgs;
+ num = logicNamesCmd[op].argumentsLength();
memmove(p, &code[it->curIP], num);
memset(p + num, 0, CMD_BSIZE - num);
@@ -275,25 +275,21 @@ bool Console::Cmd_BT(int argc, const char **argv) {
return true;
}
-PreAGI_Console::PreAGI_Console(PreAgiEngine *vm) {
- _vm = vm;
-}
-
-Mickey_Console::Mickey_Console(PreAgiEngine *vm, Mickey *mickey) : PreAGI_Console(vm) {
+MickeyConsole::MickeyConsole(MickeyEngine *mickey) : GUI::Debugger() {
_mickey = mickey;
- DCmd_Register("curRoom", WRAP_METHOD(Mickey_Console, Cmd_CurRoom));
- DCmd_Register("gotoRoom", WRAP_METHOD(Mickey_Console, Cmd_GotoRoom));
- DCmd_Register("drawPic", WRAP_METHOD(Mickey_Console, Cmd_DrawPic));
- DCmd_Register("drawObj", WRAP_METHOD(Mickey_Console, Cmd_DrawObj));
+ DCmd_Register("curRoom", WRAP_METHOD(MickeyConsole, Cmd_CurRoom));
+ DCmd_Register("gotoRoom", WRAP_METHOD(MickeyConsole, Cmd_GotoRoom));
+ DCmd_Register("drawPic", WRAP_METHOD(MickeyConsole, Cmd_DrawPic));
+ DCmd_Register("drawObj", WRAP_METHOD(MickeyConsole, Cmd_DrawObj));
}
-bool Mickey_Console::Cmd_CurRoom(int argc, const char **argv) {
+bool MickeyConsole::Cmd_CurRoom(int argc, const char **argv) {
_mickey->debugCurRoom();
return true;
}
-bool Mickey_Console::Cmd_GotoRoom(int argc, const char **argv) {
+bool MickeyConsole::Cmd_GotoRoom(int argc, const char **argv) {
if (argc != 2)
DebugPrintf("Usage: %s <Room number>\n", argv[0]);
else
@@ -301,7 +297,7 @@ bool Mickey_Console::Cmd_GotoRoom(int argc, const char **argv) {
return true;
}
-bool Mickey_Console::Cmd_DrawPic(int argc, const char **argv) {
+bool MickeyConsole::Cmd_DrawPic(int argc, const char **argv) {
if (argc != 2)
DebugPrintf("Usage: %s <Picture number>\n", argv[0]);
else
@@ -309,7 +305,7 @@ bool Mickey_Console::Cmd_DrawPic(int argc, const char **argv) {
return true;
}
-bool Mickey_Console::Cmd_DrawObj(int argc, const char **argv) {
+bool MickeyConsole::Cmd_DrawObj(int argc, const char **argv) {
if (argc != 2)
DebugPrintf("Usage: %s <Object number>\n", argv[0]);
else
@@ -317,13 +313,13 @@ bool Mickey_Console::Cmd_DrawObj(int argc, const char **argv) {
return true;
}
-Winnie_Console::Winnie_Console(PreAgiEngine *vm, Winnie *winnie) : PreAGI_Console(vm) {
+WinnieConsole::WinnieConsole(WinnieEngine *winnie) : GUI::Debugger() {
_winnie = winnie;
- DCmd_Register("curRoom", WRAP_METHOD(Winnie_Console, Cmd_CurRoom));
+ DCmd_Register("curRoom", WRAP_METHOD(WinnieConsole, Cmd_CurRoom));
}
-bool Winnie_Console::Cmd_CurRoom(int argc, const char **argv) {
+bool WinnieConsole::Cmd_CurRoom(int argc, const char **argv) {
_winnie->debugCurRoom();
return true;
diff --git a/engines/agi/console.h b/engines/agi/console.h
index 308b0f1d1f..5f69460907 100644
--- a/engines/agi/console.h
+++ b/engines/agi/console.h
@@ -27,8 +27,8 @@ namespace Agi {
class AgiEngine;
class PreAgiEngine;
-class Winnie;
-class Mickey;
+class MickeyEngine;
+class WinnieEngine;
struct AgiDebug {
int enabled;
@@ -67,23 +67,13 @@ private:
AgiEngine *_vm;
};
-class PreAGI_Console : public GUI::Debugger {
+class MickeyConsole : public GUI::Debugger {
public:
- PreAGI_Console(PreAgiEngine *vm);
- virtual ~PreAGI_Console() {}
+ MickeyConsole(MickeyEngine *mickey);
+ virtual ~MickeyConsole() {}
private:
- PreAgiEngine *_vm;
-};
-
-
-class Mickey_Console : public PreAGI_Console {
-public:
- Mickey_Console(PreAgiEngine *vm, Mickey *mickey);
- virtual ~Mickey_Console() {}
-
-private:
- Mickey *_mickey;
+ MickeyEngine *_mickey;
bool Cmd_CurRoom(int argc, const char **argv);
bool Cmd_GotoRoom(int argc, const char **argv);
@@ -91,17 +81,17 @@ private:
bool Cmd_DrawObj(int argc, const char **argv);
};
-class Winnie_Console : public PreAGI_Console {
+class WinnieConsole : public GUI::Debugger {
public:
- Winnie_Console(PreAgiEngine *vm, Winnie *winnie);
- virtual ~Winnie_Console() {}
+ WinnieConsole(WinnieEngine *winnie);
+ virtual ~WinnieConsole() {}
private:
- Winnie *_winnie;
+ WinnieEngine *_winnie;
bool Cmd_CurRoom(int argc, const char **argv);
};
-} // End of namespace Agi
+} // End of namespace Agi
#endif /* AGI_CONSOLE_H */
diff --git a/engines/agi/cycle.cpp b/engines/agi/cycle.cpp
index d86fb36709..e6f122f9f6 100644
--- a/engines/agi/cycle.cpp
+++ b/engines/agi/cycle.cpp
@@ -47,8 +47,8 @@ void AgiEngine::newRoom(int n) {
i = 0;
for (v = _game.viewTable; v < &_game.viewTable[MAX_VIEWTABLE]; v++) {
v->entry = i++;
- v->flags &= ~(ANIMATED | DRAWN);
- v->flags |= UPDATE;
+ v->flags &= ~(fAnimated | fDrawn);
+ v->flags |= fUpdate;
v->stepTime = 1;
v->stepTimeCount = 1;
v->cycleTime = 1;
@@ -220,7 +220,7 @@ int AgiEngine::mainCycle() {
}
// Click-to-walk mouse interface
- if (_game.playerControl && v->flags & ADJ_EGO_XY) {
+ if (_game.playerControl && v->flags & fAdjEgoXY) {
int toX = v->parm1;
int toY = v->parm2;
diff --git a/engines/agi/detection.cpp b/engines/agi/detection.cpp
index 93fcd2d283..5141ab761f 100644
--- a/engines/agi/detection.cpp
+++ b/engines/agi/detection.cpp
@@ -28,6 +28,7 @@
#include "engines/advancedDetector.h"
#include "common/config-manager.h"
#include "common/file.h"
+#include "common/md5.h"
#include "common/savefile.h"
#include "common/textconsole.h"
#include "graphics/thumbnail.h"
@@ -35,6 +36,9 @@
#include "agi/agi.h"
#include "agi/preagi.h"
+#include "agi/preagi_mickey.h"
+#include "agi/preagi_troll.h"
+#include "agi/preagi_winnie.h"
#include "agi/wagparser.h"
@@ -93,6 +97,14 @@ void AgiBase::initVersion() {
_gameVersion = _gameDescription->version;
}
+const char *AgiBase::getDiskName(uint16 id) {
+ for (int i = 0; _gameDescription->desc.filesDescriptions[i].fileName != NULL; i++)
+ if (_gameDescription->desc.filesDescriptions[i].fileType == id)
+ return _gameDescription->desc.filesDescriptions[i].fileName;
+
+ return "";
+}
+
}
static const PlainGameDescriptor agiGames[] = {
@@ -182,8 +194,19 @@ bool AgiMetaEngine::createInstance(OSystem *syst, Engine **engine, const ADGameD
switch (gd->gameType) {
case Agi::GType_PreAGI:
- *engine = new Agi::PreAgiEngine(syst, gd);
+ switch (gd->gameID) {
+ case GID_MICKEY:
+ *engine = new Agi::MickeyEngine(syst, gd);
+ break;
+ case GID_TROLL:
+ *engine = new Agi::TrollEngine(syst, gd);
+ break;
+ case GID_WINNIE:
+ *engine = new Agi::WinnieEngine(syst, gd);
+ break;
+ }
break;
+ case Agi::GType_V1:
case Agi::GType_V2:
case Agi::GType_V3:
*engine = new Agi::AgiEngine(syst, gd);
@@ -477,7 +500,9 @@ int AgiEngine::agiDetectGame() {
assert(_gameDescription != NULL);
- if (getVersion() <= 0x2999) {
+ if (getVersion() <= 0x2001) {
+ _loader = new AgiLoader_v1(this);
+ } else if (getVersion() <= 0x2999) {
_loader = new AgiLoader_v2(this);
} else {
_loader = new AgiLoader_v3(this);
diff --git a/engines/agi/detection_tables.h b/engines/agi/detection_tables.h
index cd3edf50c6..28e94075a6 100644
--- a/engines/agi/detection_tables.h
+++ b/engines/agi/detection_tables.h
@@ -37,7 +37,7 @@ using Common::GUIO_NONE;
gid, \
interp, \
features, \
- ver, \
+ ver \
}
#define GAME_LVFPNF(id,name,fname,md5,size,lang,ver,features,gid,platform,interp) { \
@@ -53,9 +53,10 @@ using Common::GUIO_NONE;
gid, \
interp, \
features, \
- ver, \
+ ver \
}
+#define BOOTER2(id,extra,fname,md5,size,ver,gid) GAME_LVFPN(id,extra,fname,md5,size,Common::EN_ANY,ver,0,gid,Common::kPlatformPC,GType_V2)
#define GAME(id,extra,md5,ver,gid) GAME_LVFPN(id,extra,"logdir",md5,-1,Common::EN_ANY,ver,0,gid,Common::kPlatformPC,GType_V2)
#define GAME3(id,extra,fname,md5,ver,gid) GAME_LVFPN(id,extra,fname,md5,-1,Common::EN_ANY,ver,0,gid,Common::kPlatformPC,GType_V3)
@@ -118,6 +119,69 @@ static const AGIGameDescription gameDescriptions[] = {
// AGI Demo for Kings Quest III and Space Quest I
GAME("agidemo", "Demo Kings Quest III and Space Quest I", "502e6bf96827b6c4d3e67c9cdccd1033", 0x2272, GID_AGIDEMO),
+ {
+ // Black Cauldron (PC 3.5" booter) 1.1J [AGI 1.12]
+ {
+ "bc",
+ "Booter 1.1J",
+ {
+ { "bc-d1.img", BooterDisk1, "1d29a82b41c9c7491e2b68d16864bd11", 368640},
+ { "bc-d2.img", BooterDisk2, "5568f7a52e787305656246f95e2aa375", 368640},
+ { NULL, 0, NULL, 0}
+ },
+ Common::EN_ANY,
+ Common::kPlatformPC,
+ ADGF_NO_FLAGS,
+ GUIO_NONE
+ },
+ GID_BC,
+ GType_V1,
+ 0,
+ 0x1120
+ },
+
+ {
+ // Black Cauldron (PC 3.5" booter) 1.1K [AGI 1.12]
+ {
+ "bc",
+ "Booter 1.1K",
+ {
+ { "bc-d1.img", BooterDisk1, "98a51d3a372baa9df288b6c0f0232567", 368640},
+ { "bc-d2.img", BooterDisk2, "5568f7a52e787305656246f95e2aa375", 368640},
+ { NULL, 0, NULL, 0}
+ },
+ Common::EN_ANY,
+ Common::kPlatformPC,
+ ADGF_NO_FLAGS,
+ GUIO_NONE
+ },
+ GID_BC,
+ GType_V1,
+ 0,
+ 0x1120
+ },
+
+ {
+ // Black Cauldron (PC 3.5" booter) 1.1M [AGI 1.12]
+ {
+ "bc",
+ "Booter 1.1M",
+ {
+ { "bc-d1.img", BooterDisk1, "edc0e5befbe5e44bb109cdf9137ee12d", 368640},
+ { "bc-d2.img", BooterDisk2, "5568f7a52e787305656246f95e2aa375", 368640},
+ { NULL, 0, NULL, 0}
+ },
+ Common::EN_ANY,
+ Common::kPlatformPC,
+ ADGF_NO_FLAGS,
+ GUIO_NONE
+ },
+ GID_BC,
+ GType_V1,
+ 0,
+ 0x1120
+ },
+
// Black Cauldron (Amiga) 2.00 6/14/87
GAME_P("bc", "2.00 1987-06-14", "7b01694af21213b4727bb94476f64eb5", 0x2440, GID_BC, Common::kPlatformAmiga),
@@ -143,9 +207,9 @@ static const AGIGameDescription gameDescriptions[] = {
// Black Cauldron (CoCo3 360k) [AGI 2.072]
GAME_PS("bc", "updated", "c4e1937f74e8100cd0152b904434d8b4", 357, 0x2440, GID_BC, Common::kPlatformCoCo3),
-// TODO
-// These aren't supposed to work now as they require unsupported agi engine 2.01
-#if 0
+ // Donald Duck's Playground (PC Booter) 1.0Q
+ BOOTER2("ddp", "Booter 1.0Q", "ddp.img", "f323f10abf8140ffb2668b09af2e7b87", 368640, 0x2001, GID_DDP),
+
// Donald Duck's Playground (Amiga) 1.0C
// Menus not tested
GAME_P("ddp", "1.0C 1987-04-27", "550971d196f65190a5c760d2479406ef", 0x2272, GID_DDP, Common::kPlatformAmiga),
@@ -157,7 +221,6 @@ static const AGIGameDescription gameDescriptions[] = {
// reported by Filippos (thebluegr) in bugreport #1654500
// Menus not tested
GAME_PS("ddp", "1.0C 1986-06-09", "550971d196f65190a5c760d2479406ef", 132, 0x2272, GID_DDP, Common::kPlatformPC),
-#endif
// Gold Rush! (Amiga) 1.01 1/13/89 aka 2.05 3/9/89 # 2.316
GAME3_PS("goldrush", "1.01 1989-01-13 aka 2.05 1989-03-09", "dirs", "a1d4de3e75c2688c1e2ca2634ffc3bd8", 2399, 0x3149, 0, GID_GOLDRUSH, Common::kPlatformAmiga),
@@ -196,7 +259,7 @@ static const AGIGameDescription gameDescriptions[] = {
GID_GOLDRUSH,
GType_V3,
GF_MACGOLDRUSH,
- 0x3149,
+ 0x3149
},
@@ -514,7 +577,7 @@ static const AGIGameDescription gameDescriptions[] = {
GID_SQ2,
GType_V2,
0,
- 0x2936,
+ 0x2936
},
@@ -659,7 +722,7 @@ static const AGIGameDescription gameDescriptions[] = {
GID_FANMADE,
GType_V2,
GF_AGDS,
- 0x2440,
+ 0x2440
},
{
@@ -676,7 +739,7 @@ static const AGIGameDescription gameDescriptions[] = {
GID_GETOUTTASQ,
GType_V2,
0,
- 0x2440,
+ 0x2440
},
FANMADE_F("Half-Death - Terror At White-Mesa", "b62c05d0ace878261392073f57ae788c", GF_AGIMOUSE),
@@ -831,7 +894,7 @@ static const AGIGameDescription gameDescriptions[] = {
GID_FANMADE,
GType_V3,
GF_FANMADE,
- 0x3149,
+ 0x3149
},
FANMADE_SVP("V - The Graphical Adventure", "1646eaade74f137a9041eb427a389969", 768, 0x2440, Common::kPlatformCoCo3),
@@ -859,7 +922,7 @@ static AGIGameDescription g_fallbackDesc = {
GID_FANMADE,
GType_V2,
GF_FANMADE,
- 0x2917,
+ 0x2917
};
} // End of namespace Agi
diff --git a/engines/agi/id.cpp b/engines/agi/id.cpp
index 00f8407529..dd370d4189 100644
--- a/engines/agi/id.cpp
+++ b/engines/agi/id.cpp
@@ -48,14 +48,17 @@ int AgiEngine::setupV2Game(int ver) {
// 'quit' takes 0 args for 2.089
if (ver == 0x2089)
- logicNamesCmd[0x86].numArgs = 0;
+// logicNamesCmd[0x86].numArgs = 0;
+ logicNamesCmd[0x86].args = "";
// 'print.at' and 'print.at.v' take 3 args before 2.272
// This is documented in the specs as only < 2.440, but it seems
// that KQ3 (2.272) needs a 'print.at' taking 4 args.
if (ver < 0x2272) {
- logicNamesCmd[0x97].numArgs = 3;
- logicNamesCmd[0x98].numArgs = 3;
+// logicNamesCmd[0x97].numArgs = 3;
+// logicNamesCmd[0x98].numArgs = 3;
+ logicNamesCmd[0x97].args = "vvv";
+ logicNamesCmd[0x98].args = "vvv";
}
return ec;
@@ -73,8 +76,10 @@ int AgiEngine::setupV3Game(int ver) {
// 'unknown173' also takes 1 arg for 3.002.068, not 0 args.
// Is this actually used anywhere? -- dsymonds
if (ver == 0x3086) {
- logicNamesCmd[0xb0].numArgs = 1;
- logicNamesCmd[0xad].numArgs = 1;
+// logicNamesCmd[0xb0].numArgs = 1;
+// logicNamesCmd[0xad].numArgs = 1;
+ logicNamesCmd[0xb0].args = "n";
+ logicNamesCmd[0xad].args = "n";
}
// FIXME: Apply this fix to other games also that use 2 arguments for command 182.
@@ -83,7 +88,8 @@ int AgiEngine::setupV3Game(int ver) {
// has been set to use AGI 3.149 in ScummVM so that's why this initialization is
// here and not in setupV2Game.
if (getGameID() == GID_GOLDRUSH && getPlatform() == Common::kPlatformAmiga)
- logicNamesCmd[182].numArgs = 2;
+// logicNamesCmd[182].numArgs = 2;
+ logicNamesCmd[182].args = "vv";
return ec;
}
diff --git a/engines/agi/keyboard.cpp b/engines/agi/keyboard.cpp
index f5810a6e8c..d899a6e202 100644
--- a/engines/agi/keyboard.cpp
+++ b/engines/agi/keyboard.cpp
@@ -180,7 +180,7 @@ int AgiEngine::handleController(int key) {
if (!(getFeatures() & GF_AGIMOUSE)) {
// Handle mouse button events
if (key == BUTTON_LEFT) {
- v->flags |= ADJ_EGO_XY;
+ v->flags |= fAdjEgoXY;
v->parm1 = WIN_TO_PIC_X(_mouse.x);
v->parm2 = WIN_TO_PIC_Y(_mouse.y);
return true;
@@ -188,7 +188,7 @@ int AgiEngine::handleController(int key) {
}
if (d || key == KEY_STATIONARY) {
- v->flags &= ~ADJ_EGO_XY;
+ v->flags &= ~fAdjEgoXY;
v->direction = v->direction == d ? 0 : d;
return true;
}
diff --git a/engines/agi/loader_v1.cpp b/engines/agi/loader_v1.cpp
new file mode 100644
index 0000000000..c6a3e66705
--- /dev/null
+++ b/engines/agi/loader_v1.cpp
@@ -0,0 +1,329 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "agi/agi.h"
+#include "common/md5.h"
+
+#define IMAGE_SIZE 368640 // = 40 * 2 * 9 * 512 = tracks * sides * sectors * sector size
+#define SECTOR_OFFSET(s) ((s) * 512)
+
+#define DDP_BASE_SECTOR 0x1C2
+#define DDP_LOGDIR_SEC SECTOR_OFFSET(171) + 5
+#define DDP_LOGDIR_MAX 43
+#define DDP_PICDIR_SEC SECTOR_OFFSET(180) + 5
+#define DDP_PICDIR_MAX 30
+#define DDP_VIEWDIR_SEC SECTOR_OFFSET(189) + 5
+#define DDP_VIEWDIR_MAX 171
+#define DDP_SNDDIR_SEC SECTOR_OFFSET(198) + 5
+#define DDP_SNDDIR_MAX 64
+
+#define BC_LOGDIR_SEC SECTOR_OFFSET(90) + 5
+#define BC_LOGDIR_MAX 118
+#define BC_VIEWDIR_SEC SECTOR_OFFSET(96) + 5
+#define BC_VIEWDIR_MAX 180
+#define BC_PICDIR_SEC SECTOR_OFFSET(93) + 8
+#define BC_PICDIR_MAX 117
+#define BC_SNDDIR_SEC SECTOR_OFFSET(99) + 5
+#define BC_SNDDIR_MAX 29
+#define BC_WORDS SECTOR_OFFSET(0x26D) + 5
+#define BC_OBJECTS SECTOR_OFFSET(0x1E6) + 3
+
+namespace Agi {
+
+
+AgiLoader_v1::AgiLoader_v1(AgiEngine *vm) {
+ _vm = vm;
+}
+
+int AgiLoader_v1::detectGame() {
+ // Find filenames for the disk images
+ _filenameDisk0 = _vm->getDiskName(BooterDisk1);
+ _filenameDisk1 = _vm->getDiskName(BooterDisk2);
+
+ return _vm->setupV2Game(_vm->getVersion());
+}
+
+int AgiLoader_v1::loadDir_DDP(AgiDir *agid, int offset, int max) {
+ Common::File fp;
+
+ if (!fp.open(_filenameDisk0))
+ return errBadFileOpen;
+
+ // Cleanup
+ for (int i = 0; i < MAX_DIRS; i++) {
+ agid[i].volume = 0xFF;
+ agid[i].offset = _EMPTY;
+ }
+
+ fp.seek(offset, SEEK_SET);
+ for (int i = 0; i <= max; i++) {
+ int b0 = fp.readByte();
+ int b1 = fp.readByte();
+ int b2 = fp.readByte();
+
+ if (b0 == 0xFF && b1 == 0xFF && b2 == 0xFF) {
+ agid[i].volume = 0xFF;
+ agid[i].offset = _EMPTY;
+ } else {
+ int sec = (DDP_BASE_SECTOR + (((b0 & 0xF) << 8) | b1)) >> 1;
+ int off = ((b1 & 0x1) << 8) | b2;
+ agid[i].volume = 0;
+ agid[i].offset = SECTOR_OFFSET(sec) + off;
+ }
+ }
+
+ fp.close();
+
+ return errOK;
+}
+
+int AgiLoader_v1::loadDir_BC(AgiDir *agid, int offset, int max) {
+ Common::File fp;
+
+ if (!fp.open(_filenameDisk0))
+ return errBadFileOpen;
+
+ // Cleanup
+ for (int i = 0; i < MAX_DIRS; i++) {
+ agid[i].volume = 0xFF;
+ agid[i].offset = _EMPTY;
+ }
+
+ fp.seek(offset, SEEK_SET);
+ for (int i = 0; i <= max; i++) {
+ int b0 = fp.readByte();
+ int b1 = fp.readByte();
+ int b2 = fp.readByte();
+
+ if (b0 == 0xFF && b1 == 0xFF && b2 == 0xFF) {
+ agid[i].volume = 0xFF;
+ agid[i].offset = _EMPTY;
+ } else {
+ int sec = (b0 & 0x3F) * 18 + ((b1 >> 1) & 0x1) * 9 + ((b1 >> 2) & 0x1F) - 1;
+ int off = ((b1 & 0x1) << 8) | b2;
+ int vol = (b0 & 0xC0) >> 6;
+ agid[i].volume = 0;
+ agid[i].offset = (vol == 2) * IMAGE_SIZE + SECTOR_OFFSET(sec) + off;
+ }
+ }
+
+ fp.close();
+
+ return errOK;
+}
+
+int AgiLoader_v1::init() {
+ int ec = errOK;
+
+ switch (_vm->getGameID()) {
+ case GID_DDP:
+ ec = loadDir_DDP(_vm->_game.dirLogic, DDP_LOGDIR_SEC, DDP_LOGDIR_MAX);
+ if (ec == errOK)
+ ec = loadDir_DDP(_vm->_game.dirPic, DDP_PICDIR_SEC, DDP_PICDIR_MAX);
+ if (ec == errOK)
+ ec = loadDir_DDP(_vm->_game.dirView, DDP_VIEWDIR_SEC, DDP_VIEWDIR_MAX);
+ if (ec == errOK)
+ ec = loadDir_DDP(_vm->_game.dirSound, DDP_SNDDIR_SEC, DDP_SNDDIR_MAX);
+ break;
+
+ case GID_BC:
+ ec = loadDir_BC(_vm->_game.dirLogic, BC_LOGDIR_SEC, BC_LOGDIR_MAX);
+ if (ec == errOK)
+ ec = loadDir_BC(_vm->_game.dirPic, BC_PICDIR_SEC, BC_PICDIR_MAX);
+ if (ec == errOK)
+ ec = loadDir_BC(_vm->_game.dirView, BC_VIEWDIR_SEC, BC_VIEWDIR_MAX);
+ if (ec == errOK)
+ ec = loadDir_BC(_vm->_game.dirSound, BC_SNDDIR_SEC, BC_SNDDIR_MAX);
+ break;
+ }
+
+ return ec;
+}
+
+int AgiLoader_v1::deinit() {
+ int ec = errOK;
+ return ec;
+}
+
+uint8 *AgiLoader_v1::loadVolRes(struct AgiDir *agid) {
+ uint8 *data = NULL;
+ Common::File fp;
+ int offset = agid->offset;
+
+ if (offset == _EMPTY)
+ return NULL;
+
+ if (offset > IMAGE_SIZE) {
+ fp.open(_filenameDisk1);
+ offset -= IMAGE_SIZE;
+ } else {
+ fp.open(_filenameDisk0);
+ }
+
+ fp.seek(offset, SEEK_SET);
+
+ int signature = fp.readUint16BE();
+ if (signature != 0x1234) {
+ warning("AgiLoader_v1::loadVolRes: bad signature %04x", signature);
+ return NULL;
+ }
+
+ fp.readByte();
+ agid->len = fp.readUint16LE();
+ data = (uint8 *)calloc(1, agid->len + 32);
+ fp.read(data, agid->len);
+
+ fp.close();
+
+ return data;
+}
+
+int AgiLoader_v1::loadResource(int t, int n) {
+ int ec = errOK;
+ uint8 *data = NULL;
+
+ debugC(3, kDebugLevelResources, "(t = %d, n = %d)", t, n);
+ if (n > MAX_DIRS)
+ return errBadResource;
+
+ switch (t) {
+ case rLOGIC:
+ if (~_vm->_game.dirLogic[n].flags & RES_LOADED) {
+ debugC(3, kDebugLevelResources, "loading logic resource %d", n);
+ unloadResource(rLOGIC, n);
+
+ // load raw resource into data
+ data = loadVolRes(&_vm->_game.dirLogic[n]);
+
+ _vm->_game.logics[n].data = data;
+ ec = data ? _vm->decodeLogic(n) : errBadResource;
+
+ _vm->_game.logics[n].sIP = 2;
+ }
+
+ // if logic was cached, we get here
+ // reset code pointers incase it was cached
+
+ _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
+
+ debugC(3, kDebugLevelResources, "loading picture resource %d", n);
+ if (_vm->_game.dirPic[n].flags & RES_LOADED)
+ break;
+
+ // if loaded but not cached, unload it
+ // if cached but not loaded, etc
+ unloadResource(rPICTURE, n);
+ data = loadVolRes(&_vm->_game.dirPic[n]);
+
+ if (data != NULL) {
+ _vm->_game.pictures[n].rdata = data;
+ _vm->_game.dirPic[n].flags |= RES_LOADED;
+ } else {
+ ec = errBadResource;
+ }
+ break;
+ case rSOUND:
+ debugC(3, kDebugLevelResources, "loading sound resource %d", n);
+ if (_vm->_game.dirSound[n].flags & RES_LOADED)
+ break;
+
+ data = loadVolRes(&_vm->_game.dirSound[n]);
+
+ if (data != NULL) {
+ // Freeing of the raw resource from memory is delegated to the createFromRawResource-function
+ _vm->_game.sounds[n] = AgiSound::createFromRawResource(data, _vm->_game.dirSound[n].len, n, *_vm->_sound, _vm->_soundemu);
+ _vm->_game.dirSound[n].flags |= RES_LOADED;
+ } else {
+ ec = errBadResource;
+ }
+ break;
+ case rVIEW:
+ // Load a VIEW resource into memory...
+ // Since VIEWS alter the view table ALL the time
+ // can we cache the view? or must we reload it all
+ // the time?
+ if (_vm->_game.dirView[n].flags & RES_LOADED)
+ break;
+
+ debugC(3, kDebugLevelResources, "loading view resource %d", n);
+ unloadResource(rVIEW, n);
+ data = loadVolRes(&_vm->_game.dirView[n]);
+ if (data) {
+ _vm->_game.views[n].rdata = data;
+ _vm->_game.dirView[n].flags |= RES_LOADED;
+ ec = _vm->decodeView(n);
+ } else {
+ ec = errBadResource;
+ }
+ break;
+ default:
+ ec = errBadResource;
+ break;
+ }
+
+ return ec;
+}
+
+int AgiLoader_v1::unloadResource(int t, int n) {
+ switch (t) {
+ case rLOGIC:
+ _vm->unloadLogic(n);
+ break;
+ case rPICTURE:
+ _vm->_picture->unloadPicture(n);
+ break;
+ case rVIEW:
+ _vm->unloadView(n);
+ break;
+ case rSOUND:
+ _vm->_sound->unloadSound(n);
+ break;
+ }
+
+ return errOK;
+}
+
+int AgiLoader_v1::loadObjects(const char *fname) {
+ if (_vm->getGameID() == GID_BC) {
+ Common::File f;
+ f.open(_filenameDisk0);
+ f.seek(BC_OBJECTS, SEEK_SET);
+ return _vm->loadObjects(f);
+ }
+ return errOK;
+}
+
+int AgiLoader_v1::loadWords(const char *fname) {
+ if (_vm->getGameID() == GID_BC) {
+ Common::File f;
+ f.open(_filenameDisk0);
+ f.seek(BC_WORDS, SEEK_SET);
+ return _vm->loadWords_v1(f);
+ }
+ return errOK;
+}
+
+}
diff --git a/engines/agi/module.mk b/engines/agi/module.mk
index 2339d1019f..68d86f7b2e 100644
--- a/engines/agi/module.mk
+++ b/engines/agi/module.mk
@@ -11,6 +11,7 @@ MODULE_OBJS := \
id.o \
inv.o \
keyboard.o \
+ loader_v1.o \
loader_v2.o \
loader_v3.o \
logic.o \
@@ -18,12 +19,12 @@ MODULE_OBJS := \
menu.o \
motion.o \
objects.o \
+ opcodes.o \
op_cmd.o \
op_dbg.o \
op_test.o \
picture.o \
preagi.o \
- preagi_common.o \
preagi_mickey.o \
preagi_troll.o \
preagi_winnie.o \
diff --git a/engines/agi/motion.cpp b/engines/agi/motion.cpp
index 261a7f3e61..e4de232267 100644
--- a/engines/agi/motion.cpp
+++ b/engines/agi/motion.cpp
@@ -52,9 +52,9 @@ void AgiEngine::changePos(VtEntry *v) {
y += v->stepSize * dy[v->direction];
if (checkBlock(x, y) == b) {
- v->flags &= ~MOTION;
+ v->flags &= ~fMotion;
} else {
- v->flags |= MOTION;
+ v->flags |= fMotion;
v->direction = 0;
if (isEgoView(v))
_game.vars[vEgoDir] = 0;
@@ -63,7 +63,7 @@ void AgiEngine::changePos(VtEntry *v) {
void AgiEngine::motionWander(VtEntry *v) {
if (v->parm1--) {
- if (~v->flags & DIDNT_MOVE)
+ if (~v->flags & fDidntMove)
return;
}
@@ -94,14 +94,14 @@ void AgiEngine::motionFollowEgo(VtEntry *v) {
// Already at ego coordinates
if (dir == 0) {
v->direction = 0;
- v->motion = MOTION_NORMAL;
+ v->motion = kMotionNormal;
setflag(v->parm2, true);
return;
}
if (v->parm3 == 0xff) {
v->parm3 = 0;
- } else if (v->flags & DIDNT_MOVE) {
+ } else if (v->flags & fDidntMove) {
int d;
while ((v->direction = _rnd->getRandomNumber(8)) == 0) {
@@ -152,18 +152,20 @@ void AgiEngine::motionMoveObj(VtEntry *v) {
void AgiEngine::checkMotion(VtEntry *v) {
switch (v->motion) {
- case MOTION_WANDER:
+ case kMotionNormal:
+ break;
+ case kMotionWander:
motionWander(v);
break;
- case MOTION_FOLLOW_EGO:
+ case kMotionFollowEgo:
motionFollowEgo(v);
break;
- case MOTION_MOVE_OBJ:
+ case kMotionMoveObj:
motionMoveObj(v);
break;
}
- if ((_game.block.active && (~v->flags & IGNORE_BLOCKS)) && v->direction)
+ if ((_game.block.active && (~v->flags & fIgnoreBlocks)) && v->direction)
changePos(v);
}
@@ -178,7 +180,7 @@ void AgiEngine::checkAllMotions() {
VtEntry *v;
for (v = _game.viewTable; v < &_game.viewTable[MAX_VIEWTABLE]; v++) {
- if ((v->flags & (ANIMATED | UPDATE | DRAWN)) == (ANIMATED | UPDATE | DRAWN)
+ if ((v->flags & (fAnimated | fUpdate | fDrawn)) == (fAnimated | fUpdate | fDrawn)
&& v->stepTimeCount == 1) {
checkMotion(v);
}
@@ -192,11 +194,11 @@ void AgiEngine::checkAllMotions() {
* @param v Pointer to view table entry
*/
void AgiEngine::inDestination(VtEntry *v) {
- if (v->motion == MOTION_MOVE_OBJ) {
+ if (v->motion == kMotionMoveObj) {
v->stepSize = v->parm3;
setflag(v->parm4, true);
}
- v->motion = MOTION_NORMAL;
+ v->motion = kMotionNormal;
if (isEgoView(v))
_game.playerControl = true;
}
@@ -204,7 +206,7 @@ void AgiEngine::inDestination(VtEntry *v) {
/**
* Wrapper for static function motion_moveobj().
* This function is used by cmd_move_object() in the first motion cycle
- * after setting the motion mode to MOTION_MOVE_OBJ.
+ * after setting the motion mode to kMotionMoveObj.
* @param v Pointer to view table entry
*/
void AgiEngine::moveObj(VtEntry *v) {
diff --git a/engines/agi/objects.cpp b/engines/agi/objects.cpp
index e04c9742f3..efc8645287 100644
--- a/engines/agi/objects.cpp
+++ b/engines/agi/objects.cpp
@@ -34,7 +34,7 @@ int AgiEngine::allocObjects(int n) {
}
int AgiEngine::decodeObjects(uint8 *mem, uint32 flen) {
- unsigned int i, so, padsize;
+ unsigned int i, so, padsize, spos;
padsize = _game.gameFlags & ID_AMIGA ? 4 : 3;
@@ -64,11 +64,12 @@ int AgiEngine::decodeObjects(uint8 *mem, uint32 flen) {
return errNotEnoughMemory;
// build the object list
- for (i = 0, so = padsize; i < _game.numObjects; i++, so += padsize) {
+ spos = getVersion() >= 0x2000 ? padsize : 0;
+ for (i = 0, so = spos; i < _game.numObjects; i++, so += padsize) {
int offset;
(_objects + i)->location = *(mem + so + 2);
- offset = READ_LE_UINT16(mem + so) + padsize;
+ offset = READ_LE_UINT16(mem + so) + spos;
if ((uint) offset < flen) {
(_objects + i)->name = (char *)strdup((const char *)mem + offset);
@@ -84,20 +85,33 @@ int AgiEngine::decodeObjects(uint8 *mem, uint32 flen) {
int AgiEngine::loadObjects(const char *fname) {
Common::File fp;
- uint32 flen;
- uint8 *mem;
-
- _objects = NULL;
- _game.numObjects = 0;
debugC(5, kDebugLevelResources, "(Loading objects '%s')", fname);
if (!fp.open(fname))
return errBadFileOpen;
- fp.seek(0, SEEK_END);
- flen = fp.pos();
- fp.seek(0, SEEK_SET);
+ return readObjects(fp, fp.size());
+}
+
+/**
+ * Loads an object file that is in the common VOL resource format. Expects
+ * the file pointer to point to the last field in header, ie. file length.
+ * This is used at least by the V1 booter games.
+ */
+int AgiEngine::loadObjects(Common::File &fp) {
+ int flen = fp.readUint16LE();
+ return readObjects(fp, flen);
+}
+
+/**
+ * Read and decode objects, and store them in the internal structure.
+ *
+ * @param fp File pointer
+ * @param flen File length
+ */
+int AgiEngine::readObjects(Common::File &fp, int flen) {
+ uint8 *mem;
if ((mem = (uint8 *)calloc(1, flen + 32)) == NULL) {
fp.close();
diff --git a/engines/agi/op_cmd.cpp b/engines/agi/op_cmd.cpp
index bde62fe2d9..17addc0c05 100644
--- a/engines/agi/op_cmd.cpp
+++ b/engines/agi/op_cmd.cpp
@@ -41,23 +41,36 @@ namespace Agi {
#define p5 (p[5])
#define p6 (p[6])
-#define ip _curLogic->cIP
-#define vt _game.viewTable[p0]
-#define vt_v _game.viewTable[_game.vars[p0]]
-
-#define _v _game.vars
-
-void AgiEngine::cmd_increment(uint8 *p) {
- if (_v[p0] != 0xff)
- ++_v[p0];
+#define code state->_curLogic->data
+#define ip state->_curLogic->cIP
+#define vt state->viewTable[p0]
+#define vt_v state->viewTable[state->vars[p0]]
+
+#define _v state->vars
+
+#define getGameID() state->_vm->getGameID()
+#define getFeatures() state->_vm->getFeatures()
+#define getVersion() state->_vm->getVersion()
+#define getLanguage() state->_vm->getLanguage()
+#define setflag(a,b) state->_vm->setflag(a,b)
+#define getflag(a) state->_vm->getflag(a)
+
+void cmdIncrement(AgiGame *state, uint8 *p) {
+ if (getVersion() < 0x2000) {
+ if (_v[p0] < 0xf0)
+ ++_v[p0];
+ } else {
+ if (_v[p0] != 0xff)
+ ++_v[p0];
+ }
}
-void AgiEngine::cmd_decrement(uint8 *p) {
+void cmdDecrement(AgiGame *state, uint8 *p) {
if (_v[p0] != 0)
--_v[p0];
}
-void AgiEngine::cmd_assignn(uint8 *p) {
+void cmdAssignN(AgiGame *state, uint8 *p) {
_v[p0] = p1;
// WORKAROUND for a bug in fan _game "Get outta SQ"
@@ -71,84 +84,100 @@ void AgiEngine::cmd_assignn(uint8 *p) {
_v[p0] = 8;
}
-void AgiEngine::cmd_addn(uint8 *p) {
+void cmdAddN(AgiGame *state, uint8 *p) {
_v[p0] += p1;
}
-void AgiEngine::cmd_subn(uint8 *p) {
+void cmdSubN(AgiGame *state, uint8 *p) {
_v[p0] -= p1;
}
-void AgiEngine::cmd_assignv(uint8 *p) {
+void cmdAssignV(AgiGame *state, uint8 *p) {
_v[p0] = _v[p1];
}
-void AgiEngine::cmd_addv(uint8 *p) {
+void cmdAddV(AgiGame *state, uint8 *p) {
_v[p0] += _v[p1];
}
-void AgiEngine::cmd_subv(uint8 *p) {
+void cmdSubV(AgiGame *state, uint8 *p) {
_v[p0] -= _v[p1];
}
-void AgiEngine::cmd_mul_n(uint8 *p) {
+void cmdMulN(AgiGame *state, uint8 *p) {
_v[p0] *= p1;
}
-void AgiEngine::cmd_mul_v(uint8 *p) {
+void cmdMulV(AgiGame *state, uint8 *p) {
_v[p0] *= _v[p1];
}
-void AgiEngine::cmd_div_n(uint8 *p) {
+void cmdDivN(AgiGame *state, uint8 *p) {
_v[p0] /= p1;
}
-void AgiEngine::cmd_div_v(uint8 *p) {
+void cmdDivV(AgiGame *state, uint8 *p) {
_v[p0] /= _v[p1];
}
-void AgiEngine::cmd_random(uint8 *p) {
- _v[p2] = _rnd->getRandomNumber(p1 - p0) + p0;
+void cmdRandomV1(AgiGame *state, uint8 *p) {
+ _v[p0] = state->_vm->_rnd->getRandomNumber(250);
+}
+
+void cmdRandom(AgiGame *state, uint8 *p) {
+ _v[p2] = state->_vm->_rnd->getRandomNumber(p1 - p0) + p0;
}
-void AgiEngine::cmd_lindirectn(uint8 *p) {
+void cmdLindirectN(AgiGame *state, uint8 *p) {
_v[_v[p0]] = p1;
}
-void AgiEngine::cmd_lindirectv(uint8 *p) {
+void cmdLindirectV(AgiGame *state, uint8 *p) {
_v[_v[p0]] = _v[p1];
}
-void AgiEngine::cmd_rindirect(uint8 *p) {
+void cmdRindirect(AgiGame *state, uint8 *p) {
_v[p0] = _v[_v[p1]];
}
-void AgiEngine::cmd_set(uint8 *p) {
+void cmdSet(AgiGame *state, uint8 *p) {
setflag(*p, true);
}
-void AgiEngine::cmd_reset(uint8 *p) {
+void cmdReset(AgiGame *state, uint8 *p) {
setflag(*p, false);
}
-void AgiEngine::cmd_toggle(uint8 *p) {
+void cmdToggle(AgiGame *state, uint8 *p) {
setflag(*p, !getflag(*p));
}
-void AgiEngine::cmd_set_v(uint8 *p) {
- setflag(_v[p0], true);
+void cmdSetV(AgiGame *state, uint8 *p) {
+ if (getVersion() < 0x2000) {
+ _v[p0] = 1;
+ } else {
+ setflag(_v[p0], true);
+ }
}
-void AgiEngine::cmd_reset_v(uint8 *p) {
- setflag(_v[p0], false);
+void cmdResetV(AgiGame *state, uint8 *p) {
+ if (getVersion() < 0x2000) {
+ _v[p0] = 0;
+ } else {
+ setflag(_v[p0], false);
+ }
}
-void AgiEngine::cmd_toggle_v(uint8 *p) {
- setflag(_v[p0], !getflag(_v[p0]));
+void cmdToggleV(AgiGame *state, uint8 *p) {
+ if (getVersion() < 0x2000) {
+ _v[p0] ^= 1;
+ } else {
+ setflag(_v[p0], !getflag(_v[p0]));
+ }
}
-void AgiEngine::cmd_new_room(uint8 *p) {
- newRoom(p0);
+void cmdNewRoom(AgiGame *state, uint8 *p) {
+ state->_vm->newRoom(p0);
// WORKAROUND: Works around intro skipping bug (#1737343) in Gold Rush.
// Intro was skipped because the enter-keypress finalizing the entering
@@ -160,83 +189,83 @@ void AgiEngine::cmd_new_room(uint8 *p) {
// 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 (getGameID() == GID_GOLDRUSH && p0 == 73)
- _game.keypress = 0;
+ state->keypress = 0;
}
-void AgiEngine::cmd_new_room_f(uint8 *p) {
- newRoom(_v[p0]);
+void cmdNewRoomF(AgiGame *state, uint8 *p) {
+ state->_vm->newRoom(_v[p0]);
}
-void AgiEngine::cmd_load_view(uint8 *p) {
- agiLoadResource(rVIEW, p0);
+void cmdLoadView(AgiGame *state, uint8 *p) {
+ state->_vm->agiLoadResource(rVIEW, p0);
}
-void AgiEngine::cmd_load_logic(uint8 *p) {
- agiLoadResource(rLOGIC, p0);
+void cmdLoadLogic(AgiGame *state, uint8 *p) {
+ state->_vm->agiLoadResource(rLOGIC, p0);
}
-void AgiEngine::cmd_load_sound(uint8 *p) {
- agiLoadResource(rSOUND, p0);
+void cmdLoadSound(AgiGame *state, uint8 *p) {
+ state->_vm->agiLoadResource(rSOUND, p0);
}
-void AgiEngine::cmd_load_view_f(uint8 *p) {
- agiLoadResource(rVIEW, _v[p0]);
+void cmdLoadViewF(AgiGame *state, uint8 *p) {
+ state->_vm->agiLoadResource(rVIEW, _v[p0]);
}
-void AgiEngine::cmd_load_logic_f(uint8 *p) {
- agiLoadResource(rLOGIC, _v[p0]);
+void cmdLoadLogicF(AgiGame *state, uint8 *p) {
+ state->_vm->agiLoadResource(rLOGIC, _v[p0]);
}
-void AgiEngine::cmd_discard_view(uint8 *p) {
- agiUnloadResource(rVIEW, p0);
+void cmdDiscardView(AgiGame *state, uint8 *p) {
+ state->_vm->agiUnloadResource(rVIEW, p0);
}
-void AgiEngine::cmd_object_on_anything(uint8 *p) {
- vt.flags &= ~(ON_WATER | ON_LAND);
+void cmdObjectOnAnything(AgiGame *state, uint8 *p) {
+ vt.flags &= ~(fOnWater | fOnLand);
}
-void AgiEngine::cmd_object_on_land(uint8 *p) {
- vt.flags |= ON_LAND;
+void cmdObjectOnLand(AgiGame *state, uint8 *p) {
+ vt.flags |= fOnLand;
}
-void AgiEngine::cmd_object_on_water(uint8 *p) {
- vt.flags |= ON_WATER;
+void cmdObjectOnWater(AgiGame *state, uint8 *p) {
+ vt.flags |= fOnWater;
}
-void AgiEngine::cmd_observe_horizon(uint8 *p) {
- vt.flags &= ~IGNORE_HORIZON;
+void cmdObserveHorizon(AgiGame *state, uint8 *p) {
+ vt.flags &= ~fIgnoreHorizon;
}
-void AgiEngine::cmd_ignore_horizon(uint8 *p) {
- vt.flags |= IGNORE_HORIZON;
+void cmdIgnoreHorizon(AgiGame *state, uint8 *p) {
+ vt.flags |= fIgnoreHorizon;
}
-void AgiEngine::cmd_observe_objs(uint8 *p) {
- vt.flags &= ~IGNORE_OBJECTS;
+void cmdObserveObjs(AgiGame *state, uint8 *p) {
+ vt.flags &= ~fIgnoreObjects;
}
-void AgiEngine::cmd_ignore_objs(uint8 *p) {
- vt.flags |= IGNORE_OBJECTS;
+void cmdIgnoreObjs(AgiGame *state, uint8 *p) {
+ vt.flags |= fIgnoreObjects;
}
-void AgiEngine::cmd_observe_blocks(uint8 *p) {
- vt.flags &= ~IGNORE_BLOCKS;
+void cmdObserveBlocks(AgiGame *state, uint8 *p) {
+ vt.flags &= ~fIgnoreBlocks;
}
-void AgiEngine::cmd_ignore_blocks(uint8 *p) {
- vt.flags |= IGNORE_BLOCKS;
+void cmdIgnoreBlocks(AgiGame *state, uint8 *p) {
+ vt.flags |= fIgnoreBlocks;
}
-void AgiEngine::cmd_set_horizon(uint8 *p) {
- _game.horizon = p0;
+void cmdSetHorizon(AgiGame *state, uint8 *p) {
+ state->horizon = p0;
}
-void AgiEngine::cmd_get_priority(uint8 *p) {
+void cmdGetPriority(AgiGame *state, uint8 *p) {
_v[p1] = vt.priority;
}
-void AgiEngine::cmd_set_priority(uint8 *p) {
- vt.flags |= FIXED_PRIORITY;
+void cmdSetPriority(AgiGame *state, uint8 *p) {
+ vt.flags |= fFixedPriority;
vt.priority = p1;
// WORKAROUND: this fixes bug #1712585 in KQ4 (dwarf sprite priority)
@@ -253,250 +282,257 @@ void AgiEngine::cmd_set_priority(uint8 *p) {
// Therefore, this workaround only affects that specific part of this scene
// Ego is set to object 19 by script 54
if (getGameID() == GID_KQ4 && vt.currentView == 152) {
- _game.viewTable[19].flags |= FIXED_PRIORITY;
- _game.viewTable[19].priority = 7;
+ state->viewTable[19].flags |= fFixedPriority;
+ state->viewTable[19].priority = 7;
}
}
-void AgiEngine::cmd_set_priority_f(uint8 *p) {
- vt.flags |= FIXED_PRIORITY;
+void cmdSetPriorityF(AgiGame *state, uint8 *p) {
+ vt.flags |= fFixedPriority;
vt.priority = _v[p1];
}
-void AgiEngine::cmd_release_priority(uint8 *p) {
- vt.flags &= ~FIXED_PRIORITY;
+void cmdReleasePriority(AgiGame *state, uint8 *p) {
+ vt.flags &= ~fFixedPriority;
}
-void AgiEngine::cmd_set_upper_left(uint8 *p) { // do nothing (AGI 2.917)
+void cmdSetUpperLeft(AgiGame *state, uint8 *p) { // do nothing (AGI 2.917)
}
-void AgiEngine::cmd_start_update(uint8 *p) {
- startUpdate(&vt);
+void cmdStartUpdate(AgiGame *state, uint8 *p) {
+ state->_vm->startUpdate(&vt);
}
-void AgiEngine::cmd_stop_update(uint8 *p) {
- stopUpdate(&vt);
+void cmdStopUpdate(AgiGame *state, uint8 *p) {
+ state->_vm->stopUpdate(&vt);
}
-void AgiEngine::cmd_current_view(uint8 *p) {
+void cmdCurrentView(AgiGame *state, uint8 *p) {
_v[p1] = vt.currentView;
}
-void AgiEngine::cmd_current_cel(uint8 *p) {
+void cmdCurrentCel(AgiGame *state, uint8 *p) {
_v[p1] = vt.currentCel;
debugC(4, kDebugLevelScripts, "v%d=%d", p1, _v[p1]);
}
-void AgiEngine::cmd_current_loop(uint8 *p) {
+void cmdCurrentLoop(AgiGame *state, uint8 *p) {
_v[p1] = vt.currentLoop;
}
-void AgiEngine::cmd_last_cel(uint8 *p) {
+void cmdLastCel(AgiGame *state, uint8 *p) {
_v[p1] = vt.loopData->numCels - 1;
}
-void AgiEngine::cmd_set_cel(uint8 *p) {
- setCel(&vt, p1);
- vt.flags &= ~DONTUPDATE;
+void cmdSetCel(AgiGame *state, uint8 *p) {
+ state->_vm->setCel(&vt, p1);
+
+ if (getVersion() >= 0x2000) {
+ vt.flags &= ~fDontupdate;
+ }
}
-void AgiEngine::cmd_set_cel_f(uint8 *p) {
- setCel(&vt, _v[p1]);
- vt.flags &= ~DONTUPDATE;
+void cmdSetCelF(AgiGame *state, uint8 *p) {
+ state->_vm->setCel(&vt, _v[p1]);
+ vt.flags &= ~fDontupdate;
}
-void AgiEngine::cmd_set_view(uint8 *p) {
- setView(&vt, p1);
+void cmdSetView(AgiGame *state, uint8 *p) {
+ state->_vm->setView(&vt, p1);
}
-void AgiEngine::cmd_set_view_f(uint8 *p) {
- setView(&vt, _v[p1]);
+void cmdSetViewF(AgiGame *state, uint8 *p) {
+ state->_vm->setView(&vt, _v[p1]);
}
-void AgiEngine::cmd_set_loop(uint8 *p) {
- setLoop(&vt, p1);
+void cmdSetLoop(AgiGame *state, uint8 *p) {
+ state->_vm->setLoop(&vt, p1);
}
-void AgiEngine::cmd_set_loop_f(uint8 *p) {
- setLoop(&vt, _v[p1]);
+void cmdSetLoopF(AgiGame *state, uint8 *p) {
+ state->_vm->setLoop(&vt, _v[p1]);
}
-void AgiEngine::cmd_number_of_loops(uint8 *p) {
+void cmdNumberOfLoops(AgiGame *state, uint8 *p) {
_v[p1] = vt.numLoops;
}
-void AgiEngine::cmd_fix_loop(uint8 *p) {
- vt.flags |= FIX_LOOP;
+void cmdFixLoop(AgiGame *state, uint8 *p) {
+ vt.flags |= fFixLoop;
}
-void AgiEngine::cmd_release_loop(uint8 *p) {
- vt.flags &= ~FIX_LOOP;
+void cmdReleaseLoop(AgiGame *state, uint8 *p) {
+ vt.flags &= ~fFixLoop;
}
-void AgiEngine::cmd_step_size(uint8 *p) {
+void cmdStepSize(AgiGame *state, uint8 *p) {
vt.stepSize = _v[p1];
}
-void AgiEngine::cmd_step_time(uint8 *p) {
+void cmdStepTime(AgiGame *state, uint8 *p) {
vt.stepTime = vt.stepTimeCount = _v[p1];
}
-void AgiEngine::cmd_cycle_time(uint8 *p) {
+void cmdCycleTime(AgiGame *state, uint8 *p) {
vt.cycleTime = vt.cycleTimeCount = _v[p1];
}
-void AgiEngine::cmd_stop_cycling(uint8 *p) {
- vt.flags &= ~CYCLING;
+void cmdStopCycling(AgiGame *state, uint8 *p) {
+ vt.flags &= ~fCycling;
}
-void AgiEngine::cmd_start_cycling(uint8 *p) {
- vt.flags |= CYCLING;
+void cmdStartCycling(AgiGame *state, uint8 *p) {
+ vt.flags |= fCycling;
}
-void AgiEngine::cmd_normal_cycle(uint8 *p) {
- vt.cycle = CYCLE_NORMAL;
- vt.flags |= CYCLING;
+void cmdNormalCycle(AgiGame *state, uint8 *p) {
+ vt.cycle = kCycleNormal;
+ vt.flags |= fCycling;
}
-void AgiEngine::cmd_reverse_cycle(uint8 *p) {
- vt.cycle = CYCLE_REVERSE;
- vt.flags |= CYCLING;
+void cmdReverseCycle(AgiGame *state, uint8 *p) {
+ vt.cycle = kCycleReverse;
+ vt.flags |= fCycling;
}
-void AgiEngine::cmd_set_dir(uint8 *p) {
+void cmdSetDir(AgiGame *state, uint8 *p) {
vt.direction = _v[p1];
}
-void AgiEngine::cmd_get_dir(uint8 *p) {
+void cmdGetDir(AgiGame *state, uint8 *p) {
_v[p1] = vt.direction;
}
-void AgiEngine::cmd_get_room_f(uint8 *p) {
- _v[p1] = objectGetLocation(_v[p0]);
+void cmdGetRoomF(AgiGame *state, uint8 *p) {
+ _v[p1] = state->_vm->objectGetLocation(_v[p0]);
+}
+
+void cmdPut(AgiGame *state, uint8 *p) {
+ state->_vm->objectSetLocation(p0, _v[p1]);
}
-void AgiEngine::cmd_put(uint8 *p) {
- objectSetLocation(p0, _v[p1]);
+void cmdPutF(AgiGame *state, uint8 *p) {
+ state->_vm->objectSetLocation(_v[p0], _v[p1]);
}
-void AgiEngine::cmd_put_f(uint8 *p) {
- objectSetLocation(_v[p0], _v[p1]);
+void cmdDrop(AgiGame *state, uint8 *p) {
+ state->_vm->objectSetLocation(p0, 0);
}
-void AgiEngine::cmd_drop(uint8 *p) {
- objectSetLocation(p0, 0);
+void cmdGet(AgiGame *state, uint8 *p) {
+ state->_vm->objectSetLocation(p0, EGO_OWNED);
}
-void AgiEngine::cmd_get(uint8 *p) {
- objectSetLocation(p0, EGO_OWNED);
+void cmdGetV1(AgiGame *state, uint8 *p) {
+ state->_vm->objectSetLocation(p0, EGO_OWNED_V1);
}
-void AgiEngine::cmd_get_f(uint8 *p) {
- objectSetLocation(_v[p0], EGO_OWNED);
+void cmdGetF(AgiGame *state, uint8 *p) {
+ state->_vm->objectSetLocation(_v[p0], EGO_OWNED);
}
-void AgiEngine::cmd_word_to_string(uint8 *p) {
- strcpy(_game.strings[p0], _game.egoWords[p1].word);
+void cmdWordToString(AgiGame *state, uint8 *p) {
+ strcpy(state->strings[p0], state->egoWords[p1].word);
}
-void AgiEngine::cmd_open_dialogue(uint8 *p) {
- _game.hasWindow = true;
+void cmdOpenDialogue(AgiGame *state, uint8 *p) {
+ state->hasWindow = true;
}
-void AgiEngine::cmd_close_dialogue(uint8 *p) {
- _game.hasWindow = false;
+void cmdCloseDialogue(AgiGame *state, uint8 *p) {
+ state->hasWindow = false;
}
-void AgiEngine::cmd_close_window(uint8 *p) {
- closeWindow();
+void cmdCloseWindow(AgiGame *state, uint8 *p) {
+ state->_vm->closeWindow();
}
-void AgiEngine::cmd_status_line_on(uint8 *p) {
- _game.statusLine = true;
- writeStatus();
+void cmdStatusLineOn(AgiGame *state, uint8 *p) {
+ state->statusLine = true;
+ state->_vm->writeStatus();
}
-void AgiEngine::cmd_status_line_off(uint8 *p) {
- _game.statusLine = false;
- writeStatus();
+void cmdStatusLineOff(AgiGame *state, uint8 *p) {
+ state->statusLine = false;
+ state->_vm->writeStatus();
}
-void AgiEngine::cmd_show_obj(uint8 *p) {
- _sprites->showObj(p0);
+void cmdShowObj(AgiGame *state, uint8 *p) {
+ state->_vm->_sprites->showObj(p0);
}
-void AgiEngine::cmd_show_obj_v(uint8 *p) {
- _sprites->showObj(_v[p0]);
+void cmdShowObjV(AgiGame *state, uint8 *p) {
+ state->_vm->_sprites->showObj(_v[p0]);
}
-void AgiEngine::cmd_sound(uint8 *p) {
- _sound->startSound(p0, p1);
+void cmdSound(AgiGame *state, uint8 *p) {
+ state->_vm->_sound->startSound(p0, p1);
}
-void AgiEngine::cmd_stop_sound(uint8 *p) {
- _sound->stopSound();
+void cmdStopSound(AgiGame *state, uint8 *p) {
+ state->_vm->_sound->stopSound();
}
-void AgiEngine::cmd_menu_input(uint8 *p) {
- newInputMode(INPUT_MENU);
+void cmdMenuInput(AgiGame *state, uint8 *p) {
+ state->_vm->newInputMode(INPUT_MENU);
}
-void AgiEngine::cmd_enable_item(uint8 *p) {
- _menu->setItem(p0, true);
+void cmdEnableItem(AgiGame *state, uint8 *p) {
+ state->_vm->_menu->setItem(p0, true);
}
-void AgiEngine::cmd_disable_item(uint8 *p) {
- _menu->setItem(p0, false);
+void cmdDisableItem(AgiGame *state, uint8 *p) {
+ state->_vm->_menu->setItem(p0, false);
}
-void AgiEngine::cmd_submit_menu(uint8 *p) {
- _menu->submit();
+void cmdSubmitMenu(AgiGame *state, uint8 *p) {
+ state->_vm->_menu->submit();
}
-void AgiEngine::cmd_set_scan_start(uint8 *p) {
- _curLogic->sIP = _curLogic->cIP;
+void cmdSetScanStart(AgiGame *state, uint8 *p) {
+ state->_curLogic->sIP = state->_curLogic->cIP;
}
-void AgiEngine::cmd_reset_scan_start(uint8 *p) {
- _curLogic->sIP = 2;
+void cmdResetScanStart(AgiGame *state, uint8 *p) {
+ state->_curLogic->sIP = 2;
}
-void AgiEngine::cmd_save_game(uint8 *p) {
- _game.simpleSave ? saveGameSimple() : saveGameDialog();
+void cmdSaveGame(AgiGame *state, uint8 *p) {
+ state->simpleSave ? state->_vm->saveGameSimple() : state->_vm->saveGameDialog();
}
-void AgiEngine::cmd_load_game(uint8 *p) {
+void cmdLoadGame(AgiGame *state, uint8 *p) {
assert(1);
- _game.simpleSave ? loadGameSimple() : loadGameDialog();
+ state->simpleSave ? state->_vm->loadGameSimple() : state->_vm->loadGameDialog();
}
-void AgiEngine::cmd_init_disk(uint8 *p) { // do nothing
+void cmdInitDisk(AgiGame *state, uint8 *p) { // do nothing
}
-void AgiEngine::cmd_log(uint8 *p) { // do nothing
+void cmdLog(AgiGame *state, uint8 *p) { // do nothing
}
-void AgiEngine::cmd_trace_on(uint8 *p) { // do nothing
+void cmdTraceOn(AgiGame *state, uint8 *p) { // do nothing
}
-void AgiEngine::cmd_trace_info(uint8 *p) { // do nothing
+void cmdTraceInfo(AgiGame *state, uint8 *p) { // do nothing
}
-void AgiEngine::cmd_show_mem(uint8 *p) {
- messageBox("Enough memory");
+void cmdShowMem(AgiGame *state, uint8 *p) {
+ state->_vm->messageBox("Enough memory");
}
-void AgiEngine::cmd_init_joy(uint8 *p) { // do nothing
+void cmdInitJoy(AgiGame *state, uint8 *p) { // do nothing
}
-void AgiEngine::cmd_script_size(uint8 *p) {
+void cmdScriptSize(AgiGame *state, uint8 *p) {
debug(0, "script.size(%d)", p0);
}
-void AgiEngine::cmd_cancel_line(uint8 *p) {
- _game.inputBuffer[0] = 0;
- _game.cursorPos = 0;
- writePrompt();
+void cmdCancelLine(AgiGame *state, uint8 *p) {
+ state->inputBuffer[0] = 0;
+ state->cursorPos = 0;
+ state->_vm->writePrompt();
}
// This implementation is based on observations of Amiga's Gold Rush.
@@ -509,23 +545,23 @@ void AgiEngine::cmd_cancel_line(uint8 *p) {
// 4051 (When ego is stationary),
// 471 (When walking on the first screen's bridge),
// 71 (When walking around, using the mouse or the keyboard).
-void AgiEngine::cmd_obj_status_f(uint8 *p) {
+void cmdObjStatusF(AgiGame *state, 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
// Generate cycle description line
switch (vt_v.cycle) {
- case CYCLE_NORMAL:
+ case kCycleNormal:
cycleDesc = "normal cycle";
break;
- case CYCLE_END_OF_LOOP:
+ case kCycleEndOfLoop:
cycleDesc = "end of loop";
break;
- case CYCLE_REV_LOOP:
+ case kCycleRevLoop:
cycleDesc = "reverse loop";
break;
- case CYCLE_REVERSE:
+ case kCycleReverse:
cycleDesc = "reverse cycle";
break;
default:
@@ -535,16 +571,16 @@ void AgiEngine::cmd_obj_status_f(uint8 *p) {
// Generate motion description line
switch (vt_v.motion) {
- case MOTION_NORMAL:
+ case kMotionNormal:
motionDesc = "normal motion";
break;
- case MOTION_WANDER:
+ case kMotionWander:
motionDesc = "wandering";
break;
- case MOTION_FOLLOW_EGO:
+ case kMotionFollowEgo:
motionDesc = "following ego";
break;
- case MOTION_MOVE_OBJ:
+ case kMotionMoveObj:
// Amiga's Gold Rush! most probably uses "move to (x, y)"
// here with real values for x and y. The same output
// is used when moving the ego around using the mouse.
@@ -570,7 +606,7 @@ void AgiEngine::cmd_obj_status_f(uint8 *p) {
vt_v.stepSize,
cycleDesc,
motionDesc);
- messageBox(msg);
+ state->_vm->messageBox(msg);
}
// unknown commands:
@@ -581,49 +617,49 @@ void AgiEngine::cmd_obj_status_f(uint8 *p) {
// unk_174: Change priority table (used in KQ4) -- j5
// unk_177: Disable menus completely -- j5
// unk_181: Deactivate keypressed control (default control of ego)
-void AgiEngine::cmd_set_simple(uint8 *p) {
+void cmdSetSimple(AgiGame *state, uint8 *p) {
if (!(getFeatures() & (GF_AGI256 | GF_AGI256_2))) {
- _game.simpleSave = true;
+ state->simpleSave = true;
} else { // AGI256 and AGI256-2 use this unknown170 command to load 256 color pictures.
- // Load the picture. Similar to void AgiEngine::cmd_load_pic(uint8 *p).
- _sprites->eraseBoth();
- agiLoadResource(rPICTURE, _v[p0]);
+ // Load the picture. Similar to void cmdLoad_pic(AgiGame *state, uint8 *p).
+ state->_vm->_sprites->eraseBoth();
+ state->_vm->agiLoadResource(rPICTURE, _v[p0]);
- // Draw the picture. Similar to void AgiEngine::cmd_draw_pic(uint8 *p).
- _picture->decodePicture(_v[p0], false, true);
- _sprites->blitBoth();
- _game.pictureShown = 0;
+ // Draw the picture. Similar to void cmdDraw_pic(AgiGame *state, uint8 *p).
+ state->_vm->_picture->decodePicture(_v[p0], false, true);
+ state->_vm->_sprites->blitBoth();
+ state->pictureShown = 0;
- // Show the picture. Similar to void AgiEngine::cmd_show_pic(uint8 *p).
+ // Show the picture. Similar to void cmdShow_pic(AgiGame *state, uint8 *p).
setflag(fOutputMode, false);
- closeWindow();
- _picture->showPic();
- _game.pictureShown = 1;
+ state->_vm->closeWindow();
+ state->_vm->_picture->showPic();
+ state->pictureShown = 1;
// Simulate slowww computer. Many effects rely on this
- pause(kPausePicture);
+ state->_vm->pause(kPausePicture);
}
}
-void AgiEngine::cmd_pop_script(uint8 *p) {
+void cmdPopScript(AgiGame *state, uint8 *p) {
if (getVersion() >= 0x2915) {
debug(0, "pop.script");
}
}
-void AgiEngine::cmd_hold_key(uint8 *p) {
+void cmdHoldKey(AgiGame *state, uint8 *p) {
if (getVersion() >= 0x3098) {
- _egoHoldKey = true;
+ state->_vm->_egoHoldKey = true;
}
}
-void AgiEngine::cmd_discard_sound(uint8 *p) {
+void cmdDiscardSound(AgiGame *state, uint8 *p) {
if (getVersion() >= 0x2936) {
debug(0, "discard.sound");
}
}
-void AgiEngine::cmd_hide_mouse(uint8 *p) {
+void cmdHideMouse(AgiGame *state, 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).
@@ -631,37 +667,37 @@ void AgiEngine::cmd_hide_mouse(uint8 *p) {
// 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;
+ state->viewTable[0].flags &= ~fAdjEgoXY;
g_system->showMouse(false);
}
-void AgiEngine::cmd_allow_menu(uint8 *p) {
+void cmdAllowMenu(AgiGame *state, uint8 *p) {
if (getVersion() >= 0x3098) {
setflag(fMenusWork, ((p0 != 0) ? true : false));
}
}
-void AgiEngine::cmd_show_mouse(uint8 *p) {
+void cmdShowMouse(AgiGame *state, uint8 *p) {
g_system->showMouse(true);
}
-void AgiEngine::cmd_fence_mouse(uint8 *p) {
- _game.mouseFence.moveTo(p0, p1);
- _game.mouseFence.setWidth(p2 - p0);
- _game.mouseFence.setHeight(p3 - p1);
+void cmdFenceMouse(AgiGame *state, uint8 *p) {
+ state->mouseFence.moveTo(p0, p1);
+ state->mouseFence.setWidth(p2 - p0);
+ state->mouseFence.setHeight(p3 - p1);
}
-void AgiEngine::cmd_release_key(uint8 *p) {
+void cmdReleaseKey(AgiGame *state, uint8 *p) {
if (getVersion() >= 0x3098) {
- _egoHoldKey = false;
+ state->_vm->_egoHoldKey = false;
}
}
-void AgiEngine::cmd_adj_ego_move_to_x_y(uint8 *p) {
+void cmdAdjEgoMoveToXY(AgiGame *state, uint8 *p) {
int8 x, y;
- switch (logicNamesCmd[182].numArgs) {
+ switch (logicNamesCmd[182].argumentsLength()) {
// The 2 arguments version is used at least in Amiga Gold Rush!
// (v2.05 1989-03-09, Amiga AGI 2.316) in logics 130 and 150
// (Using arguments (0, 0), (0, 7), (0, 8), (9, 9) and (-9, 9)).
@@ -680,57 +716,67 @@ void AgiEngine::cmd_adj_ego_move_to_x_y(uint8 *p) {
// 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 != state->adjMouseX || y != state->adjMouseY)
+ state->viewTable[EGO_VIEW_TABLE].flags &= ~fAdjEgoXY;
- _game.adjMouseX = x;
- _game.adjMouseY = y;
+ state->adjMouseX = x;
+ state->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;
+ state->viewTable[0].flags |= fAdjEgoXY;
break;
}
}
-void AgiEngine::cmd_parse(uint8 *p) {
+void cmdParse(AgiGame *state, uint8 *p) {
_v[vWordNotFound] = 0;
setflag(fEnteredCli, false);
setflag(fSaidAcceptedInput, false);
- dictionaryWords(agiSprintf(_game.strings[p0]));
+ state->_vm->dictionaryWords(state->_vm->agiSprintf(state->strings[p0]));
}
-void AgiEngine::cmd_call(uint8 *p) {
+void cmdCall(AgiGame *state, 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 = state->_curLogic->cIP;
+ oldLognum = state->lognum;
- runLogic(p0);
+ state->_vm->runLogic(p0);
- _game.lognum = oldLognum;
- _curLogic = &_game.logics[_game.lognum];
- _curLogic->cIP = oldCIP;
+ state->lognum = oldLognum;
+ state->_curLogic = &state->logics[state->lognum];
+ state->_curLogic->cIP = oldCIP;
}
-void AgiEngine::cmd_call_f(uint8 *p) {
- cmd_call(&_v[p0]);
+void cmdCallF(AgiGame *state, uint8 *p) {
+ cmdCall(state, &_v[p0]);
+}
+
+void cmdDrawPicV1(AgiGame *state, uint8 *p) {
+ debugC(6, kDebugLevelScripts, "=== draw pic V1 %d ===", _v[p0]);
+ state->_vm->_picture->decodePicture(_v[p0], true);
+
+ state->_vm->clearPrompt();
+
+ // Simulate slowww computer. Many effects rely on this
+ state->_vm->pause(kPausePicture);
}
-void AgiEngine::cmd_draw_pic(uint8 *p) {
+void cmdDrawPic(AgiGame *state, uint8 *p) {
debugC(6, kDebugLevelScripts, "=== draw pic %d ===", _v[p0]);
- _sprites->eraseBoth();
- _picture->decodePicture(_v[p0], true);
- _sprites->blitBoth();
- _sprites->commitBoth();
- _game.pictureShown = 0;
+ state->_vm->_sprites->eraseBoth();
+ state->_vm->_picture->decodePicture(_v[p0], true);
+ state->_vm->_sprites->blitBoth();
+ state->_vm->_sprites->commitBoth();
+ state->pictureShown = 0;
debugC(6, kDebugLevelScripts, "--- end of draw pic %d ---", _v[p0]);
// WORKAROUND for a script bug which exists in SQ1, logic scripts
@@ -749,79 +795,93 @@ void AgiEngine::cmd_draw_pic(uint8 *p) {
setflag(103, false);
// Simulate slowww computer. Many effects rely on this
- pause(kPausePicture);
+ state->_vm->pause(kPausePicture);
}
-void AgiEngine::cmd_show_pic(uint8 *p) {
+void cmdShowPic(AgiGame *state, uint8 *p) {
debugC(6, kDebugLevelScripts, "=== show pic ===");
setflag(fOutputMode, false);
- closeWindow();
- _picture->showPic();
- _game.pictureShown = 1;
+ state->_vm->closeWindow();
+ state->_vm->_picture->showPic();
+ state->pictureShown = 1;
debugC(6, kDebugLevelScripts, "--- end of show pic ---");
}
-void AgiEngine::cmd_load_pic(uint8 *p) {
- _sprites->eraseBoth();
- agiLoadResource(rPICTURE, _v[p0]);
- _sprites->blitBoth();
- _sprites->commitBoth();
+void cmdLoadPic(AgiGame *state, uint8 *p) {
+ state->_vm->_sprites->eraseBoth();
+ state->_vm->agiLoadResource(rPICTURE, _v[p0]);
+ state->_vm->_sprites->blitBoth();
+ state->_vm->_sprites->commitBoth();
}
-void AgiEngine::cmd_discard_pic(uint8 *p) {
+void cmdLoadPicV1(AgiGame *state, uint8 *p) {
+ state->_vm->agiLoadResource(rPICTURE, _v[p0]);
+}
+
+void cmdDiscardPic(AgiGame *state, uint8 *p) {
debugC(6, kDebugLevelScripts, "--- discard pic ---");
// do nothing
}
-void AgiEngine::cmd_overlay_pic(uint8 *p) {
+void cmdOverlayPic(AgiGame *state, uint8 *p) {
debugC(6, kDebugLevelScripts, "--- overlay pic ---");
- _sprites->eraseBoth();
- _picture->decodePicture(_v[p0], false);
- _sprites->blitBoth();
- _game.pictureShown = 0;
- _sprites->commitBoth();
+ state->_vm->_sprites->eraseBoth();
+ state->_vm->_picture->decodePicture(_v[p0], false);
+ state->_vm->_sprites->blitBoth();
+ state->pictureShown = 0;
+ state->_vm->_sprites->commitBoth();
// Simulate slowww computer. Many effects rely on this
- pause(kPausePicture);
+ state->_vm->pause(kPausePicture);
}
-void AgiEngine::cmd_show_pri_screen(uint8 *p) {
- _debug.priority = 1;
- _sprites->eraseBoth();
- _picture->showPic();
- _sprites->blitBoth();
+void cmdShowPriScreen(AgiGame *state, uint8 *p) {
+ state->_vm->_debug.priority = 1;
+ state->_vm->_sprites->eraseBoth();
+ state->_vm->_picture->showPic();
+ state->_vm->_sprites->blitBoth();
- waitKey();
+ state->_vm->waitKey();
- _debug.priority = 0;
- _sprites->eraseBoth();
- _picture->showPic();
- _sprites->blitBoth();
+ state->_vm->_debug.priority = 0;
+ state->_vm->_sprites->eraseBoth();
+ state->_vm->_picture->showPic();
+ state->_vm->_sprites->blitBoth();
}
-void AgiEngine::cmd_animate_obj(uint8 *p) {
- if (vt.flags & ANIMATED)
- return;
+void cmdAnimateObj(AgiGame *state, uint8 *p) {
+ if (getVersion() < 0x2000) {
+ if (vt.flags & fDidntMove)
+ return;
+ } else {
+ if (vt.flags & fAnimated)
+ return;
+ }
debugC(4, kDebugLevelScripts, "animate vt entry #%d", p0);
- vt.flags = ANIMATED | UPDATE | CYCLING;
- vt.motion = MOTION_NORMAL;
- vt.cycle = CYCLE_NORMAL;
+ vt.flags = fAnimated | fUpdate | fCycling;
+
+ if (getVersion() < 0x2000) {
+ vt.flags |= fDidntMove;
+ }
+
+ vt.motion = kMotionNormal;
+ vt.cycle = kCycleNormal;
vt.direction = 0;
}
-void AgiEngine::cmd_unanimate_all(uint8 *p) {
+void cmdUnanimateAll(AgiGame *state, uint8 *p) {
int i;
for (i = 0; i < MAX_VIEWTABLE; i++)
- _game.viewTable[i].flags &= ~(ANIMATED | DRAWN);
+ state->viewTable[i].flags &= ~(fAnimated | fDrawn);
}
-void AgiEngine::cmd_draw(uint8 *p) {
- if (vt.flags & DRAWN)
+void cmdDraw(AgiGame *state, uint8 *p) {
+ if (vt.flags & fDrawn)
return;
if (vt.ySize <= 0 || vt.xSize <= 0)
@@ -829,18 +889,18 @@ void AgiEngine::cmd_draw(uint8 *p) {
debugC(4, kDebugLevelScripts, "draw entry %d", vt.entry);
- vt.flags |= UPDATE;
+ vt.flags |= fUpdate;
if (getVersion() >= 0x3000) {
- setLoop(&vt, vt.currentLoop);
- setCel(&vt, vt.currentCel);
+ state->_vm->setLoop(&vt, vt.currentLoop);
+ state->_vm->setCel(&vt, vt.currentCel);
}
- fixPosition(p0);
+ state->_vm->fixPosition(p0);
vt.xPos2 = vt.xPos;
vt.yPos2 = vt.yPos;
vt.celData2 = vt.celData;
- _sprites->eraseUpdSprites();
- vt.flags |= DRAWN;
+ state->_vm->_sprites->eraseUpdSprites();
+ vt.flags |= fDrawn;
// WORKAROUND: This fixes a bug with AGI Fanmade _game Space Trek.
// The original workaround checked if AGI version was <= 2.440, which could
@@ -854,30 +914,30 @@ void AgiEngine::cmd_draw(uint8 *p) {
// games are affected. If yes, then it'd be best to set this for Space
// Trek only
if (getFeatures() & GF_FANMADE) // See Sarien bug #546562
- vt.flags |= ANIMATED;
+ vt.flags |= fAnimated;
- _sprites->blitUpdSprites();
- vt.flags &= ~DONTUPDATE;
+ state->_vm->_sprites->blitUpdSprites();
+ vt.flags &= ~fDontupdate;
- _sprites->commitBlock(vt.xPos, vt.yPos - vt.ySize + 1, vt.xPos + vt.xSize - 1, vt.yPos, true);
+ state->_vm->_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);
}
-void AgiEngine::cmd_erase(uint8 *p) {
- if (~vt.flags & DRAWN)
+void cmdErase(AgiGame *state, uint8 *p) {
+ if (~vt.flags & fDrawn)
return;
- _sprites->eraseUpdSprites();
+ state->_vm->_sprites->eraseUpdSprites();
- if (vt.flags & UPDATE) {
- vt.flags &= ~DRAWN;
+ if (vt.flags & fUpdate) {
+ vt.flags &= ~fDrawn;
} else {
- _sprites->eraseNonupdSprites();
- vt.flags &= ~DRAWN;
- _sprites->blitNonupdSprites();
+ state->_vm->_sprites->eraseNonupdSprites();
+ vt.flags &= ~fDrawn;
+ state->_vm->_sprites->blitNonupdSprites();
}
- _sprites->blitUpdSprites();
+ state->_vm->_sprites->blitUpdSprites();
int x1, y1, x2, y2;
@@ -886,10 +946,10 @@ void AgiEngine::cmd_erase(uint8 *p) {
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));
- _sprites->commitBlock(x1, y1, x2, y2, true);
+ state->_vm->_sprites->commitBlock(x1, y1, x2, y2, true);
}
-void AgiEngine::cmd_position(uint8 *p) {
+void cmdPosition(AgiGame *state, uint8 *p) {
vt.xPos = vt.xPos2 = p1;
vt.yPos = vt.yPos2 = p2;
@@ -907,10 +967,15 @@ void AgiEngine::cmd_position(uint8 *p) {
// strictly need the identical workaround in the position.v-command but it does make
// for a nice symmetry.
if (getFeatures() & GF_CLIPCOORDS)
- clipViewCoordinates(&vt);
+ state->_vm->clipViewCoordinates(&vt);
}
-void AgiEngine::cmd_position_f(uint8 *p) {
+void cmdPositionV1(AgiGame *state, uint8 *p) {
+ vt.xPos = p1;
+ vt.yPos = p2;
+}
+
+void cmdPositionF(AgiGame *state, uint8 *p) {
vt.xPos = vt.xPos2 = _v[p1];
vt.yPos = vt.yPos2 = _v[p2];
@@ -918,19 +983,24 @@ void AgiEngine::cmd_position_f(uint8 *p) {
// with an accompanying identical workaround in position-command (i.e. command 0x25).
// See that workaround's comment for more in-depth information.
if (getFeatures() & GF_CLIPCOORDS)
- clipViewCoordinates(&vt);
+ state->_vm->clipViewCoordinates(&vt);
+}
+
+void cmdPositionFV1(AgiGame *state, uint8 *p) {
+ vt.xPos = _v[p1];
+ vt.yPos = _v[p2];
}
-void AgiEngine::cmd_get_posn(uint8 *p) {
- _game.vars[p1] = (unsigned char)vt.xPos;
- _game.vars[p2] = (unsigned char)vt.yPos;
+void cmdGetPosn(AgiGame *state, uint8 *p) {
+ state->vars[p1] = (unsigned char)vt.xPos;
+ state->vars[p2] = (unsigned char)vt.yPos;
}
-void AgiEngine::cmd_reposition(uint8 *p) {
+void cmdReposition(AgiGame *state, uint8 *p) {
int dx = (int8) _v[p1], dy = (int8) _v[p2];
debugC(4, kDebugLevelScripts, "dx=%d, dy=%d", dx, dy);
- vt.flags |= UPDATE_POS;
+ vt.flags |= fUpdatePos;
if (dx < 0 && vt.xPos < -dx)
vt.xPos = 0;
@@ -942,109 +1012,154 @@ void AgiEngine::cmd_reposition(uint8 *p) {
else
vt.yPos += dy;
- fixPosition(p0);
+ state->_vm->fixPosition(p0);
}
-void AgiEngine::cmd_reposition_to(uint8 *p) {
+void cmdRepositionV1(AgiGame *state, uint8 *p) {
+ vt.xPos2 = vt.xPos;
+ vt.yPos2 = vt.yPos;
+ vt.flags |= fUpdatePos;
+
+ vt.xPos = (vt.xPos + p1) & 0xff;
+ vt.yPos = (vt.yPos + p2) & 0xff;
+}
+
+void cmdRepositionTo(AgiGame *state, uint8 *p) {
vt.xPos = p1;
vt.yPos = p2;
- vt.flags |= UPDATE_POS;
- fixPosition(p0);
+ vt.flags |= fUpdatePos;
+ state->_vm->fixPosition(p0);
}
-void AgiEngine::cmd_reposition_to_f(uint8 *p) {
+void cmdRepositionToF(AgiGame *state, uint8 *p) {
vt.xPos = _v[p1];
vt.yPos = _v[p2];
- vt.flags |= UPDATE_POS;
- fixPosition(p0);
+ vt.flags |= fUpdatePos;
+ state->_vm->fixPosition(p0);
+}
+
+void cmdAddToPic(AgiGame *state, uint8 *p) {
+ state->_vm->_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);
+void cmdAddToPicV1(AgiGame *state, uint8 *p) {
+ state->_vm->_sprites->addToPic(p0, p1, p2, p3, p4, p5, -1);
}
-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]);
+void cmdAddToPicF(AgiGame *state, uint8 *p) {
+ state->_vm->_sprites->addToPic(_v[p0], _v[p1], _v[p2], _v[p3], _v[p4], _v[p5], _v[p6]);
}
-void AgiEngine::cmd_force_update(uint8 *p) {
- _sprites->eraseBoth();
- _sprites->blitBoth();
- _sprites->commitBoth();
+void cmdForceUpdate(AgiGame *state, uint8 *p) {
+ state->_vm->_sprites->eraseBoth();
+ state->_vm->_sprites->blitBoth();
+ state->_vm->_sprites->commitBoth();
}
-void AgiEngine::cmd_reverse_loop(uint8 *p) {
+void cmdReverseLoop(AgiGame *state, uint8 *p) {
debugC(4, kDebugLevelScripts, "o%d, f%d", p0, p1);
- vt.cycle = CYCLE_REV_LOOP;
- vt.flags |= (DONTUPDATE | UPDATE | CYCLING);
+ vt.cycle = kCycleRevLoop;
+ vt.flags |= (fDontupdate | fUpdate | fCycling);
vt.parm1 = p1;
setflag(p1, false);
}
-void AgiEngine::cmd_end_of_loop(uint8 *p) {
+void cmdReverseLoopV1(AgiGame *state, uint8 *p) {
debugC(4, kDebugLevelScripts, "o%d, f%d", p0, p1);
- vt.cycle = CYCLE_END_OF_LOOP;
- vt.flags |= (DONTUPDATE | UPDATE | CYCLING);
+ vt.cycle = kCycleRevLoop;
+ state->_vm->setCel(&vt, 0);
+ vt.flags |= (fDontupdate | fUpdate | fCycling);
+ vt.parm1 = p1;
+ vt.parm3 = 0;
+}
+
+void cmdEndOfLoop(AgiGame *state, uint8 *p) {
+ debugC(4, kDebugLevelScripts, "o%d, f%d", p0, p1);
+ vt.cycle = kCycleEndOfLoop;
+ vt.flags |= (fDontupdate | fUpdate | fCycling);
vt.parm1 = p1;
setflag(p1, false);
}
-void AgiEngine::cmd_block(uint8 *p) {
+void cmdEndOfLoopV1(AgiGame *state, uint8 *p) {
+ debugC(4, kDebugLevelScripts, "o%d, f%d", p0, p1);
+ vt.cycle = kCycleEndOfLoop;
+ state->_vm->setCel(&vt, 0);
+ vt.flags |= (fDontupdate | fUpdate | fCycling);
+ vt.parm1 = p1;
+ vt.parm3 = 0;
+}
+
+void cmdBlock(AgiGame *state, 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;
+ state->block.active = true;
+ state->block.x1 = p0;
+ state->block.y1 = p1;
+ state->block.x2 = p2;
+ state->block.y2 = p3;
}
-void AgiEngine::cmd_unblock(uint8 *p) {
- _game.block.active = false;
+void cmdUnblock(AgiGame *state, uint8 *p) {
+ state->block.active = false;
}
-void AgiEngine::cmd_normal_motion(uint8 *p) {
- vt.motion = MOTION_NORMAL;
+void cmdNormalMotion(AgiGame *state, uint8 *p) {
+ vt.motion = kMotionNormal;
}
-void AgiEngine::cmd_stop_motion(uint8 *p) {
+void cmdStopMotion(AgiGame *state, uint8 *p) {
vt.direction = 0;
- vt.motion = MOTION_NORMAL;
+ vt.motion = kMotionNormal;
if (p0 == 0) { // ego only
_v[vEgoDir] = 0;
- _game.playerControl = false;
+ state->playerControl = false;
}
}
-void AgiEngine::cmd_start_motion(uint8 *p) {
- vt.motion = MOTION_NORMAL;
+void cmdStopMotionV1(AgiGame *state, uint8 *p) {
+ vt.flags &= ~fAnimated;
+}
+
+void cmdStartMotion(AgiGame *state, uint8 *p) {
+ vt.motion = kMotionNormal;
if (p0 == 0) { // ego only
_v[vEgoDir] = 0;
- _game.playerControl = true;
+ state->playerControl = true;
}
}
-void AgiEngine::cmd_player_control(uint8 *p) {
- _game.playerControl = true;
- _game.viewTable[0].motion = MOTION_NORMAL;
+void cmdStartMotionV1(AgiGame *state, uint8 *p) {
+ vt.flags |= fAnimated;
}
-void AgiEngine::cmd_program_control(uint8 *p) {
- _game.playerControl = false;
+void cmdPlayerControl(AgiGame *state, uint8 *p) {
+ state->playerControl = true;
+ state->viewTable[0].motion = kMotionNormal;
}
-void AgiEngine::cmd_follow_ego(uint8 *p) {
- vt.motion = MOTION_FOLLOW_EGO;
+void cmdProgramControl(AgiGame *state, uint8 *p) {
+ state->playerControl = false;
+}
+
+void cmdFollowEgo(AgiGame *state, uint8 *p) {
+ vt.motion = kMotionFollowEgo;
vt.parm1 = p1 > vt.stepSize ? p1 : vt.stepSize;
vt.parm2 = p2;
vt.parm3 = 0xff;
- setflag(p2, false);
- vt.flags |= UPDATE;
+
+ if (getVersion() < 0x2000) {
+ _v[p2] = 0;
+ vt.flags |= fUpdate | fAnimated;
+ } else {
+ setflag(p2, false);
+ vt.flags |= fUpdate;
+ }
}
-void AgiEngine::cmd_move_obj(uint8 *p) {
+void cmdMoveObj(AgiGame *state, 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;
+ vt.motion = kMotionMoveObj;
vt.parm1 = p1;
vt.parm2 = p2;
vt.parm3 = vt.stepSize;
@@ -1053,19 +1168,24 @@ void AgiEngine::cmd_move_obj(uint8 *p) {
if (p3 != 0)
vt.stepSize = p3;
- setflag(p4, false);
- vt.flags |= UPDATE;
+ if (getVersion() < 0x2000) {
+ _v[p4] = 0;
+ vt.flags |= fUpdate | fAnimated;
+ } else {
+ setflag(p4, false);
+ vt.flags |= fUpdate;
+ }
if (p0 == 0)
- _game.playerControl = false;
+ state->playerControl = false;
// AGI 2.272 (ddp, xmas) doesn't call move_obj!
if (getVersion() > 0x2272)
- moveObj(&vt);
+ state->_vm->moveObj(&vt);
}
-void AgiEngine::cmd_move_obj_f(uint8 *p) {
- vt.motion = MOTION_MOVE_OBJ;
+void cmdMoveObjF(AgiGame *state, uint8 *p) {
+ vt.motion = kMotionMoveObj;
vt.parm1 = _v[p1];
vt.parm2 = _v[p2];
vt.parm3 = vt.stepSize;
@@ -1075,66 +1195,70 @@ void AgiEngine::cmd_move_obj_f(uint8 *p) {
vt.stepSize = _v[p3];
setflag(p4, false);
- vt.flags |= UPDATE;
+ vt.flags |= fUpdate;
if (p0 == 0)
- _game.playerControl = false;
+ state->playerControl = false;
// AGI 2.272 (ddp, xmas) doesn't call move_obj!
if (getVersion() > 0x2272)
- moveObj(&vt);
+ state->_vm->moveObj(&vt);
}
-void AgiEngine::cmd_wander(uint8 *p) {
+void cmdWander(AgiGame *state, uint8 *p) {
if (p0 == 0)
- _game.playerControl = false;
+ state->playerControl = false;
- vt.motion = MOTION_WANDER;
- vt.flags |= UPDATE;
+ vt.motion = kMotionWander;
+ if (getVersion() < 0x2000) {
+ vt.flags |= fUpdate | fAnimated;
+ } else {
+ vt.flags |= fUpdate;
+ }
}
-void AgiEngine::cmd_set_game_id(uint8 *p) {
- if (_curLogic->texts && (p0 - 1) <= _curLogic->numTexts)
- strncpy(_game.id, _curLogic->texts[p0 - 1], 8);
+void cmdSetGameID(AgiGame *state, uint8 *p) {
+ if (state->_curLogic->texts && (p0 - 1) <= state->_curLogic->numTexts)
+ strncpy(state->id, state->_curLogic->texts[p0 - 1], 8);
else
- _game.id[0] = 0;
+ state->id[0] = 0;
- debug(0, "Game ID: \"%s\"", _game.id);
+ debug(0, "Game ID: \"%s\"", state->id);
}
-void AgiEngine::cmd_pause(uint8 *p) {
- int tmp = _game.clockEnabled;
+void cmdPause(AgiGame *state, uint8 *p) {
+ int tmp = state->clockEnabled;
const char *b[] = { "Continue", NULL };
const char *b_ru[] = { "\x8f\xe0\xae\xa4\xae\xab\xa6\xa8\xe2\xec", NULL };
- _game.clockEnabled = false;
+ state->clockEnabled = false;
switch (getLanguage()) {
case Common::RU_RUS:
- selectionBox(" \x88\xa3\xe0\xa0 \xae\xe1\xe2\xa0\xad\xae\xa2\xab\xa5\xad\xa0. \n\n\n", b_ru);
+ state->_vm->selectionBox(" \x88\xa3\xe0\xa0 \xae\xe1\xe2\xa0\xad\xae\xa2\xab\xa5\xad\xa0. \n\n\n", b_ru);
break;
default:
- selectionBox(" Game is paused. \n\n\n", b);
+ state->_vm->selectionBox(" Game is paused. \n\n\n", b);
break;
}
- _game.clockEnabled = tmp;
+ state->clockEnabled = tmp;
}
-void AgiEngine::cmd_set_menu(uint8 *p) {
- debugC(4, kDebugLevelScripts, "text %02x of %02x", p0, _curLogic->numTexts);
+void cmdSetMenu(AgiGame *state, uint8 *p) {
+ debugC(4, kDebugLevelScripts, "text %02x of %02x", p0, state->_curLogic->numTexts);
- if (_curLogic->texts != NULL && p0 <= _curLogic->numTexts)
- _menu->add(_curLogic->texts[p0 - 1]);
+ if (state->_curLogic->texts != NULL && p0 <= state->_curLogic->numTexts)
+ state->_vm->_menu->add(state->_curLogic->texts[p0 - 1]);
}
-void AgiEngine::cmd_set_menu_item(uint8 *p) {
- debugC(4, kDebugLevelScripts, "text %02x of %02x", p0, _curLogic->numTexts);
+void cmdSetMenuItem(AgiGame *state, uint8 *p) {
+ debugC(4, kDebugLevelScripts, "text %02x of %02x", p0, state->_curLogic->numTexts);
- if (_curLogic->texts != NULL && p0 <= _curLogic->numTexts)
- _menu->addItem(_curLogic->texts[p0 - 1], p1);
+ if (state->_curLogic->texts != NULL && p0 <= state->_curLogic->numTexts)
+ state->_vm->_menu->addItem(state->_curLogic->texts[p0 - 1], p1);
}
-void AgiEngine::cmd_version(uint8 *p) {
+void cmdVersion(AgiGame *state, uint8 *p) {
char verMsg[64];
char ver2Msg[] =
"\n"
@@ -1171,89 +1295,94 @@ void AgiEngine::cmd_version(uint8 *p) {
strncpy(q + 1 + gap, verMsg, strlen(verMsg));
sprintf(msg, q, maj, min);
- messageBox(msg);
+ state->_vm->messageBox(msg);
}
-void AgiEngine::cmd_configure_screen(uint8 *p) {
- _game.lineMinPrint = p0;
- _game.lineUserInput = p1;
- _game.lineStatus = p2;
+void cmdConfigureScreen(AgiGame *state, uint8 *p) {
+ state->lineMinPrint = p0;
+ state->lineUserInput = p1;
+ state->lineStatus = p2;
}
-void AgiEngine::cmd_text_screen(uint8 *p) {
+void cmdTextScreen(AgiGame *state, uint8 *p) {
debugC(4, kDebugLevelScripts, "switching to text mode");
- _game.gfxMode = false;
+ state->gfxMode = false;
// Simulates the "bright background bit" of the PC video
// controller.
- if (_game.colorBg)
- _game.colorBg |= 0x08;
+ if (state->colorBg)
+ state->colorBg |= 0x08;
- _gfx->clearScreen(_game.colorBg);
+ state->_vm->_gfx->clearScreen(state->colorBg);
}
-void AgiEngine::cmd_graphics(uint8 *p) {
+void cmdGraphics(AgiGame *state, uint8 *p) {
debugC(4, kDebugLevelScripts, "switching to graphics mode");
- if (!_game.gfxMode) {
- _game.gfxMode = true;
- _gfx->clearScreen(0);
- _picture->showPic();
- writeStatus();
- writePrompt();
+ if (!state->gfxMode) {
+ state->gfxMode = true;
+ state->_vm->_gfx->clearScreen(0);
+ state->_vm->_picture->showPic();
+ state->_vm->writeStatus();
+ state->_vm->writePrompt();
}
}
-void AgiEngine::cmd_set_text_attribute(uint8 *p) {
- _game.colorFg = p0;
- _game.colorBg = p1;
+void cmdSetTextAttribute(AgiGame *state, uint8 *p) {
+ state->colorFg = p0;
+ state->colorBg = p1;
- if (_game.gfxMode) {
- if (_game.colorBg != 0) {
- _game.colorFg = 0;
- _game.colorBg = 15;
+ if (state->gfxMode) {
+ if (state->colorBg != 0) {
+ state->colorFg = 0;
+ state->colorBg = 15;
}
}
}
-void AgiEngine::cmd_status(uint8 *p) {
- inventory();
+void cmdStatus(AgiGame *state, uint8 *p) {
+ state->_vm->inventory();
}
-void AgiEngine::cmd_quit(uint8 *p) {
+void cmdQuit(AgiGame *state, uint8 *p) {
const char *buttons[] = { "Quit", "Continue", NULL };
- _sound->stopSound();
+ state->_vm->_sound->stopSound();
if (p0) {
- quitGame();
+ state->_vm->quitGame();
} else {
- if (selectionBox(" Quit the game, or continue? \n\n\n", buttons) == 0) {
- quitGame();
+ if (state->_vm->selectionBox(" Quit the game, or continue? \n\n\n", buttons) == 0) {
+ state->_vm->quitGame();
}
}
}
-void AgiEngine::cmd_restart_game(uint8 *p) {
+void cmdQuitV1(AgiGame *state, uint8 *p) {
+ state->_vm->_sound->stopSound();
+ state->_vm->quitGame();
+}
+
+void cmdRestartGame(AgiGame *state, uint8 *p) {
const char *buttons[] = { "Restart", "Continue", NULL };
int sel;
- _sound->stopSound();
+ state->_vm->_sound->stopSound();
sel = getflag(fAutoRestart) ? 0 :
- selectionBox(" Restart _game, or continue? \n\n\n", buttons);
+ state->_vm->selectionBox(" Restart _game, or continue? \n\n\n", buttons);
if (sel == 0) {
- _restartGame = true;
+ state->_vm->_restartGame = true;
setflag(fRestartGame, true);
- _menu->enableAll();
+ state->_vm->_menu->enableAll();
}
}
-void AgiEngine::cmd_distance(uint8 *p) {
+void cmdDistance(AgiGame *state, uint8 *p) {
int16 x1, y1, x2, y2, d;
- VtEntry *v0 = &_game.viewTable[p0];
- VtEntry *v1 = &_game.viewTable[p1];
+ VtEntry *v0 = &state->viewTable[p0];
+ VtEntry *v1 = &state->viewTable[p1];
- if (v0->flags & DRAWN && v1->flags & DRAWN) {
+ if (v0->flags & fDrawn && v1->flags & fDrawn) {
x1 = v0->xPos + v0->xSize / 2;
y1 = v0->yPos;
x2 = v1->xPos + v1->xSize / 2;
@@ -1299,24 +1428,24 @@ void AgiEngine::cmd_distance(uint8 *p) {
_v[p2] = (unsigned char)d;
}
-void AgiEngine::cmd_accept_input(uint8 *p) {
+void cmdAcceptInput(AgiGame *state, uint8 *p) {
debugC(4, kDebugLevelScripts | kDebugLevelInput, "input normal");
- newInputMode(INPUT_NORMAL);
- _game.inputEnabled = true;
- writePrompt();
+ state->_vm->newInputMode(INPUT_NORMAL);
+ state->inputEnabled = true;
+ state->_vm->writePrompt();
}
-void AgiEngine::cmd_prevent_input(uint8 *p) {
+void cmdPreventInput(AgiGame *state, uint8 *p) {
debugC(4, kDebugLevelScripts | kDebugLevelInput, "no input");
- newInputMode(INPUT_NONE);
- _game.inputEnabled = false;
+ state->_vm->newInputMode(INPUT_NONE);
+ state->inputEnabled = false;
- clearPrompt();
+ state->_vm->clearPrompt();
}
-void AgiEngine::cmd_get_string(uint8 *p) {
+void cmdGetString(AgiGame *state, uint8 *p) {
int tex, row, col;
debugC(4, kDebugLevelScripts, "%d %d %d %d %d", p0, p1, p2, p3, p4);
@@ -1332,63 +1461,63 @@ void AgiEngine::cmd_get_string(uint8 *p) {
if (col > 39)
col = 39;
- newInputMode(INPUT_GETSTRING);
+ state->_vm->newInputMode(INPUT_GETSTRING);
- if (_curLogic->texts != NULL && _curLogic->numTexts >= tex) {
- int len = strlen(_curLogic->texts[tex]);
+ if (state->_curLogic->texts != NULL && state->_curLogic->numTexts >= tex) {
+ int len = strlen(state->_curLogic->texts[tex]);
- printText(_curLogic->texts[tex], 0, col, row, len, _game.colorFg, _game.colorBg);
- getString(col + len - 1, row, p4, p0);
+ state->_vm->printText(state->_curLogic->texts[tex], 0, col, row, len, state->colorFg, state->colorBg);
+ state->_vm->getString(col + len - 1, row, p4, p0);
// SGEO: display input char
- _gfx->printCharacter((col + len), row, _game.cursorChar, _game.colorFg, _game.colorBg);
+ state->_vm->_gfx->printCharacter((col + len), row, state->cursorChar, state->colorFg, state->colorBg);
}
do {
- mainCycle();
- } while (_game.inputMode == INPUT_GETSTRING && !(shouldQuit() || _restartGame));
+ state->_vm->mainCycle();
+ } while (state->inputMode == INPUT_GETSTRING && !(state->_vm->shouldQuit() || state->_vm->_restartGame));
}
-void AgiEngine::cmd_get_num(uint8 *p) {
+void cmdGetNum(AgiGame *state, uint8 *p) {
debugC(4, kDebugLevelScripts, "%d %d", p0, p1);
- newInputMode(INPUT_GETSTRING);
+ state->_vm->newInputMode(INPUT_GETSTRING);
- if (_curLogic->texts != NULL && _curLogic->numTexts >= (p0 - 1)) {
- int len = strlen(_curLogic->texts[p0 - 1]);
+ if (state->_curLogic->texts != NULL && state->_curLogic->numTexts >= (p0 - 1)) {
+ int len = strlen(state->_curLogic->texts[p0 - 1]);
- printText(_curLogic->texts[p0 - 1], 0, 0, 22, len, _game.colorFg, _game.colorBg);
- getString(len - 1, 22, 3, MAX_STRINGS);
+ state->_vm->printText(state->_curLogic->texts[p0 - 1], 0, 0, 22, len, state->colorFg, state->colorBg);
+ state->_vm->getString(len - 1, 22, 3, MAX_STRINGS);
// CM: display input char
- _gfx->printCharacter((p3 + len), 22, _game.cursorChar, _game.colorFg, _game.colorBg);
+ state->_vm->_gfx->printCharacter((p3 + len), 22, state->cursorChar, state->colorFg, state->colorBg);
}
do {
- mainCycle();
- } while (_game.inputMode == INPUT_GETSTRING && !(shouldQuit() || _restartGame));
+ state->_vm->mainCycle();
+ } while (state->inputMode == INPUT_GETSTRING && !(state->_vm->shouldQuit() || state->_vm->_restartGame));
- _v[p1] = atoi(_game.strings[MAX_STRINGS]);
+ _v[p1] = atoi(state->strings[MAX_STRINGS]);
- debugC(4, kDebugLevelScripts, "[%s] -> %d", _game.strings[MAX_STRINGS], _v[p1]);
+ debugC(4, kDebugLevelScripts, "[%s] -> %d", state->strings[MAX_STRINGS], _v[p1]);
- clearLines(22, 22, _game.colorBg);
- flushLines(22, 22);
+ state->_vm->clearLines(22, 22, state->colorBg);
+ state->_vm->flushLines(22, 22);
}
-void AgiEngine::cmd_set_cursor_char(uint8 *p) {
- if (_curLogic->texts != NULL && (p0 - 1) <= _curLogic->numTexts) {
- _game.cursorChar = *_curLogic->texts[p0 - 1];
+void cmdSetCursorChar(AgiGame *state, uint8 *p) {
+ if (state->_curLogic->texts != NULL && (p0 - 1) <= state->_curLogic->numTexts) {
+ state->cursorChar = *state->_curLogic->texts[p0 - 1];
} else {
// default
- _game.cursorChar = '_';
+ state->cursorChar = '_';
}
}
-void AgiEngine::cmd_set_key(uint8 *p) {
+void cmdSetKey(AgiGame *state, uint8 *p) {
int key;
- if (_game.lastController >= MAX_CONTROLLERS) {
+ if (state->lastController >= MAX_CONTROLLERS) {
warning("Number of set.keys exceeded %d", MAX_CONTROLLERS);
return;
}
@@ -1397,35 +1526,37 @@ void AgiEngine::cmd_set_key(uint8 *p) {
key = 256 * p1 + p0;
- _game.controllers[_game.lastController].keycode = key;
- _game.controllers[_game.lastController].controller = p2;
- _game.lastController++;
+ state->controllers[state->lastController].keycode = key;
+ state->controllers[state->lastController].controller = p2;
+ state->lastController++;
- _game.controllerOccured[p2] = false;
+ state->controllerOccured[p2] = false;
}
-void AgiEngine::cmd_set_string(uint8 *p) {
+void cmdSetString(AgiGame *state, uint8 *p) {
// CM: to avoid crash in Groza (str = 150)
if (p0 > MAX_STRINGS)
return;
- strcpy(_game.strings[p0], _curLogic->texts[p1 - 1]);
+ strcpy(state->strings[p0], state->_curLogic->texts[p1 - 1]);
}
-void AgiEngine::cmd_display(uint8 *p) {
+void cmdDisplay(AgiGame *state, uint8 *p) {
+ // V1 has 4 args
+ int t = (getVersion() >= 0x2000 ? p2 : p3);
int len = 40;
- char *s = wordWrapString(_curLogic->texts[p2 - 1], &len);
+ char *s = state->_vm->wordWrapString(state->_curLogic->texts[t - 1], &len);
- printText(s, p1, 0, p0, 40, _game.colorFg, _game.colorBg);
+ state->_vm->printText(s, p1, 0, p0, 40, state->colorFg, state->colorBg);
free(s);
}
-void AgiEngine::cmd_display_f(uint8 *p) {
- printText(_curLogic->texts[_v[p2] - 1], _v[p1], 0, _v[p0], 40, _game.colorFg, _game.colorBg);
+void cmdDisplayF(AgiGame *state, uint8 *p) {
+ state->_vm->printText(state->_curLogic->texts[_v[p2] - 1], _v[p1], 0, _v[p0], 40, state->colorFg, state->colorBg);
}
-void AgiEngine::cmd_clear_text_rect(uint8 *p) {
+void cmdClearTextRect(AgiGame *state, uint8 *p) {
int c, x1, y1, x2, y2;
if ((c = p4) != 0)
@@ -1446,21 +1577,21 @@ void AgiEngine::cmd_clear_text_rect(uint8 *p) {
if (y2 > GFX_HEIGHT)
y2 = GFX_HEIGHT - 1;
- _gfx->drawRectangle(x1, y1, x2, y2, c);
- _gfx->flushBlock(x1, y1, x2, y2);
+ state->_vm->_gfx->drawRectangle(x1, y1, x2, y2, c);
+ state->_vm->_gfx->flushBlock(x1, y1, x2, y2);
}
-void AgiEngine::cmd_toggle_monitor(uint8 *p) {
+void cmdToggleMonitor(AgiGame *state, uint8 *p) {
debug(0, "toggle.monitor");
}
-void AgiEngine::cmd_echo_line(uint8 *p) {
- strcpy((char *)_game.inputBuffer, (const char *)_game.echoBuffer);
- _game.cursorPos = strlen((char *)_game.inputBuffer);
- _game.hasPrompt = 0;
+void cmdEchoLine(AgiGame *state, uint8 *p) {
+ strcpy((char *)state->inputBuffer, (const char *)state->echoBuffer);
+ state->cursorPos = strlen((char *)state->inputBuffer);
+ state->hasPrompt = 0;
}
-void AgiEngine::cmd_clear_lines(uint8 *p) {
+void cmdClearLines(AgiGame *state, uint8 *p) {
uint8 l;
// Residence 44 calls clear.lines(24,0,0), see Sarien bug #558423
@@ -1470,42 +1601,42 @@ void AgiEngine::cmd_clear_lines(uint8 *p) {
// #1935838 and #1935842
l = (l <= 24) ? l : 24;
- clearLines(p0, l, p2);
- flushLines(p0, l);
+ state->_vm->clearLines(p0, l, p2);
+ state->_vm->flushLines(p0, l);
}
-void AgiEngine::cmd_print(uint8 *p) {
+void cmdPrint(AgiGame *state, uint8 *p) {
int n = p0 < 1 ? 1 : p0;
- print(_curLogic->texts[n - 1], 0, 0, 0);
+ state->_vm->print(state->_curLogic->texts[n - 1], 0, 0, 0);
}
-void AgiEngine::cmd_print_f(uint8 *p) {
+void cmdPrintF(AgiGame *state, uint8 *p) {
int n = _v[p0] < 1 ? 1 : _v[p0];
- print(_curLogic->texts[n - 1], 0, 0, 0);
+ state->_vm->print(state->_curLogic->texts[n - 1], 0, 0, 0);
}
-void AgiEngine::cmd_print_at(uint8 *p) {
+void cmdPrintAt(AgiGame *state, uint8 *p) {
int n = p0 < 1 ? 1 : p0;
debugC(4, kDebugLevelScripts, "%d %d %d %d", p0, p1, p2, p3);
- print(_curLogic->texts[n - 1], p1, p2, p3);
+ state->_vm->print(state->_curLogic->texts[n - 1], p1, p2, p3);
}
-void AgiEngine::cmd_print_at_v(uint8 *p) {
+void cmdPrintAtV(AgiGame *state, uint8 *p) {
int n = _v[p0] < 1 ? 1 : _v[p0];
- print(_curLogic->texts[n - 1], p1, p2, p3);
+ state->_vm->print(state->_curLogic->texts[n - 1], p1, p2, p3);
}
-void AgiEngine::cmd_push_script(uint8 *p) {
+void cmdPushScript(AgiGame *state, uint8 *p) {
// We run AGIMOUSE always as a side effect
if (getFeatures() & GF_AGIMOUSE || true) {
- _game.vars[27] = _mouse.button;
- _game.vars[28] = _mouse.x / 2;
- _game.vars[29] = _mouse.y;
+ state->vars[27] = state->_vm->_mouse.button;
+ state->vars[28] = state->_vm->_mouse.x / 2;
+ state->vars[29] = state->_vm->_mouse.y;
} else {
if (getVersion() >= 0x2915) {
debug(0, "push.script");
@@ -1513,35 +1644,35 @@ void AgiEngine::cmd_push_script(uint8 *p) {
}
}
-void AgiEngine::cmd_set_pri_base(uint8 *p) {
+void cmdSetPriBase(AgiGame *state, uint8 *p) {
int i, x, pri;
debug(0, "Priority base set to %d", p0);
- // _game.alt_pri = true;
+ // state->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;
+ state->priTable[i] = pri;
}
}
-void AgiEngine::cmd_mouse_posn(uint8 *p) {
- _v[p0] = WIN_TO_PIC_X(_mouse.x);
- _v[p1] = WIN_TO_PIC_Y(_mouse.y);
+void cmdMousePosn(AgiGame *state, uint8 *p) {
+ _v[p0] = WIN_TO_PIC_X(state->_vm->_mouse.x);
+ _v[p1] = WIN_TO_PIC_Y(state->_vm->_mouse.y);
}
-void AgiEngine::cmd_shake_screen(uint8 *p) {
+void cmdShakeScreen(AgiGame *state, 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 (getFeatures() & GF_AGIPAL) {
- _gfx->setAGIPal(p0);
+ state->_vm->_gfx->setAGIPal(p0);
return;
} else {
warning("It looks like GF_AGIPAL flag is missing");
@@ -1550,212 +1681,60 @@ void AgiEngine::cmd_shake_screen(uint8 *p) {
// Disables input while shaking to prevent bug
// #1678230: AGI: Entering text while screen is shaking
- bool originalValue = _game.inputEnabled;
- _game.inputEnabled = false;
+ bool originalValue = state->inputEnabled;
+ state->inputEnabled = false;
- _gfx->shakeStart();
+ state->_vm->_gfx->shakeStart();
- _sprites->commitBoth(); // Fixes SQ1 demo
+ state->_vm->_sprites->commitBoth(); // Fixes SQ1 demo
for (i = 4 * p0; i; i--) {
- _gfx->shakeScreen(i & 1);
- _gfx->flushBlock(0, 0, GFX_WIDTH - 1, GFX_HEIGHT - 1);
- mainCycle();
+ state->_vm->_gfx->shakeScreen(i & 1);
+ state->_vm->_gfx->flushBlock(0, 0, GFX_WIDTH - 1, GFX_HEIGHT - 1);
+ state->_vm->mainCycle();
}
- _gfx->shakeEnd();
+ state->_vm->_gfx->shakeEnd();
// Sets input back to what it was
- _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];
+ state->inputEnabled = originalValue;
+}
+
+void cmdSetSpeed(AgiGame *state, uint8 *p) {
+ // V1 command
+ (void)state;
+ (void)p;
+ // speed = _v[p0];
+}
+
+void cmdSetItemView(AgiGame *state, uint8 *p) {
+ // V1 command
+ (void)state;
+ (void)p;
+}
+
+void cmdCallV1(AgiGame *state, uint8 *p) {
+ state->_vm->agiLoadResource(rLOGIC, p0);
+ state->logic_list[++state->max_logics];
+ _v[13] = 1;
+}
+
+void cmdNewRoomV1(AgiGame *state, uint8 *p) {
+ warning("cmdNewRoomV1()");
+ state->_vm->agiLoadResource(rLOGIC, p0);
+ state->max_logics = 1;
+ state->logic_list[1] = p0;
+ _v[13] = 1;
+}
+
+void cmdNewRoomVV1(AgiGame *state, uint8 *p) {
+ warning("cmdNewRoomVV1()");
+ state->_vm->agiLoadResource(rLOGIC, _v[p0]);
+ state->max_logics = 1;
+ state->logic_list[1] = _v[p0];
+ _v[13] = 1;
+}
+
+void cmdUnknown(AgiGame *state, uint8 *p) {
+ warning("Skipping unknown opcode %2X", *(code + ip - 1));
}
/**
@@ -1763,11 +1742,15 @@ void AgiEngine::setupOpcodes() {
* @param n Number of the logic resource to execute
*/
int AgiEngine::runLogic(int n) {
+ AgiGame *state = &_game;
uint8 op = 0;
uint8 p[CMD_BSIZE] = { 0 };
- uint8 *code = NULL;
int num = 0;
ScriptPos sp;
+ //int logic_index = 0;
+
+ state->logic_list[0] = 0;
+ state->max_logics = 0;
debugC(2, kDebugLevelScripts, "=================");
debugC(2, kDebugLevelScripts, "runLogic(%d)", n);
@@ -1783,10 +1766,9 @@ int AgiEngine::runLogic(int n) {
}
_game.lognum = n;
- _curLogic = &_game.logics[_game.lognum];
+ _game._curLogic = &_game.logics[_game.lognum];
- code = _curLogic->data;
- _curLogic->cIP = _curLogic->sIP;
+ _game._curLogic->cIP = _game._curLogic->sIP;
_timerHack = 0;
while (ip < _game.logics[n].size && !(shouldQuit() || _restartGame)) {
@@ -1833,19 +1815,39 @@ int AgiEngine::runLogic(int n) {
debugC(2, kDebugLevelScripts, "%sreturn() // Logic %d", st, n);
debugC(2, kDebugLevelScripts, "=================");
+// if (getVersion() < 0x2000) {
+// if (logic_index < state->max_logics) {
+// n = state->logic_list[++logic_index];
+// state->_curLogic = &state->logics[n];
+// state->lognum = n;
+// ip = 2;
+// warning("running logic %d\n", n);
+// break;
+// }
+// _v[13]=0;
+// }
+
_game.execStack.pop_back();
return 1;
default:
- num = logicNamesCmd[op].numArgs;
+ num = logicNamesCmd[op].argumentsLength();
memmove(p, code + ip, num);
memset(p + num, 0, CMD_BSIZE - num);
debugC(2, kDebugLevelScripts, "%s%s(%d %d %d)", st, logicNamesCmd[op].name, p[0], p[1], p[2]);
- (this->*_agiCommands[op])(p);
+ _agiCommands[op](&_game, p);
ip += num;
}
+// if ((op == 0x0B || op == 0x3F || op == 0x40) && logic_index < state->max_logics) {
+// n = state->logic_list[++logic_index];
+// state->_curLogic = &state->logics[n];
+// state->lognum = n;
+// ip = 2;
+// warning("running logic %d\n", n);
+// }
+
if (_game.exitAllLogics)
break;
}
@@ -1858,7 +1860,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]);
- (this->*_agiCommands[op])(p);
+ _agiCommands[op](&_game, p);
}
} // End of namespace Agi
diff --git a/engines/agi/op_dbg.cpp b/engines/agi/op_dbg.cpp
index be73dbefae..87e235cf17 100644
--- a/engines/agi/op_dbg.cpp
+++ b/engines/agi/op_dbg.cpp
@@ -28,248 +28,17 @@ namespace Agi {
#define ip (_game.logics[lognum].cIP)
#define code (_game.logics[lognum].data)
-#ifdef _L
-#undef _L
-#endif
-
-#define _L(a,b,c) { a, b, c }
-
-struct AgiLogicnames logicNamesTest[] = {
- _L("", 0, 0x00),
- _L("equaln", 2, 0x80),
- _L("equalv", 2, 0xC0),
- _L("lessn", 2, 0x80),
- _L("lessv", 2, 0xC0),
- _L("greatern", 2, 0x80),
- _L("greaterv", 2, 0xC0),
- _L("isset", 1, 0x00),
- _L("issetv", 1, 0x80),
- _L("has", 1, 0x00),
- _L("obj.in.room", 2, 0x40),
- _L("posn", 5, 0x00),
- _L("controller", 1, 0x00),
- _L("have.key", 0, 0x00),
-
- // Not 0 args. Has variable number.
- _L("said", 0, 0x00),
-
- _L("compare.strings", 2, 0x00),
- _L("obj.in.box", 5, 0x00),
- _L("center.posn", 5, 0x00),
- _L("right.posn", 5, 0x00),
-
- // Haven't seen an official name for this command so tried to name it descriptively.
- _L("in.motion.using.mouse", 0, 0x00)
-};
-
-struct AgiLogicnames logicNamesIf[] = {
- _L("OR", 0, 0x00),
- _L("NOT", 0, 0x00),
- _L("ELSE", 0, 0x00),
- _L("IF", 0, 0x00)
-};
-
-struct AgiLogicnames logicNamesCmd[] = {
- _L("return", 0, 0x00), // 00
- _L("increment", 1, 0x80), // 01
- _L("decrement", 1, 0x80), // 02
- _L("assignn", 2, 0x80), // 03
- _L("assignv", 2, 0xC0), // 04
- _L("addn", 2, 0x80), // 05
- _L("addv", 2, 0xC0), // 06
- _L("subn", 2, 0x80), // 07
- _L("subv", 2, 0xC0), // 08
- _L("lindirectv", 2, 0xC0), // 09
- _L("rindirect", 2, 0xC0), // 0A
- _L("lindirectn", 2, 0x80), // 0B
- _L("set", 1, 0x00), // 0C
- _L("reset", 1, 0x00), // 0D
- _L("toggle", 1, 0x00), // 0E
- _L("set.v", 1, 0x80), // 0F
- _L("reset.v", 1, 0x80), // 10
- _L("toggle.v", 1, 0x80), // 11
- _L("new.room", 1, 0x00), // 12
- _L("new.room.v", 1, 0x80), // 13
- _L("load.logics", 1, 0x00), // 14
- _L("load.logics.v", 1, 0x80), // 15
- _L("call", 1, 0x00), // 16
- _L("call.v", 1, 0x80), // 17
- _L("load.pic", 1, 0x80), // 18
- _L("draw.pic", 1, 0x80), // 19
- _L("show.pic", 0, 0x00), // 1A
- _L("discard.pic", 1, 0x80), // 1B
- _L("overlay.pic", 1, 0x80), // 1C
- _L("show.pri.screen", 0, 0x00), // 1D
- _L("load.view", 1, 0x00), // 1E
- _L("load.view.v", 1, 0x80), // 1F
- _L("discard.view", 1, 0x00), // 20
- _L("animate.obj", 1, 0x00), // 21
- _L("unanimate.all", 0, 0x00), // 22
- _L("draw", 1, 0x00), // 23
- _L("erase", 1, 0x00), // 24
- _L("position", 3, 0x00), // 25
- _L("position.v", 3, 0x60), // 26
- _L("get.posn", 3, 0x60), // 27
- _L("reposition", 3, 0x60), // 28
- _L("set.view", 2, 0x00), // 29
- _L("set.view.v", 2, 0x40), // 2A
- _L("set.loop", 2, 0x00), // 2B
- _L("set.loop.v", 2, 0x40), // 2C
- _L("fix.loop", 1, 0x00), // 2D
- _L("release.loop", 1, 0x00), // 2E
- _L("set.cel", 2, 0x00), // 2F
- _L("set.cel.v", 2, 0x40), // 30
- _L("last.cel", 2, 0x40), // 31
- _L("current.cel", 2, 0x40), // 32
- _L("current.loop", 2, 0x40), // 33
- _L("current.view", 2, 0x40), // 34
- _L("number.of.loops", 2, 0x40), // 35
- _L("set.priority", 2, 0x00), // 36
- _L("set.priority.v", 2, 0x40), // 37
- _L("release.priority", 1, 0x00), // 38
- _L("get.priority", 2, 0x40), // 39
- _L("stop.update", 1, 0x00), // 3A
- _L("start.update", 1, 0x00), // 3B
- _L("force.update", 1, 0x00), // 3C
- _L("ignore.horizon", 1, 0x00), // 3D
- _L("observe.horizon", 1, 0x00), // 3E
- _L("set.horizon", 1, 0x00), // 3F
- _L("object.on.water", 1, 0x00), // 40
- _L("object.on.land", 1, 0x00), // 41
- _L("object.on.anything", 1, 0x00), // 42
- _L("ignore.objs", 1, 0x00), // 43
- _L("observe.objs", 1, 0x00), // 44
- _L("distance", 3, 0x20), // 45
- _L("stop.cycling", 1, 0x00), // 46
- _L("start.cycling", 1, 0x00), // 47
- _L("normal.cycle", 1, 0x00), // 48
- _L("end.of.loop", 2, 0x00), // 49
- _L("reverse.cycle", 1, 0x00), // 4A
- _L("reverse.loop", 2, 0x00), // 4B
- _L("cycle.time", 2, 0x40), // 4C
- _L("stop.motion", 1, 0x00), // 4D
- _L("start.motion", 1, 0x00), // 4E
- _L("step.size", 2, 0x40), // 4F
- _L("step.time", 2, 0x40), // 50
- _L("move.obj", 5, 0x00), // 51
- _L("move.obj.v", 5, 0x70), // 52
- _L("follow.ego", 3, 0x00), // 53
- _L("wander", 1, 0x00), // 54
- _L("normal.motion", 1, 0x00), // 55
- _L("set.dir", 2, 0x40), // 56
- _L("get.dir", 2, 0x40), // 57
- _L("ignore.blocks", 1, 0x00), // 58
- _L("observe.blocks", 1, 0x00), // 59
- _L("block", 4, 0x00), // 5A
- _L("unblock", 0, 0x00), // 5B
- _L("get", 1, 0x00), // 5C
- _L("get.v", 1, 0x80), // 5D
- _L("drop", 1, 0x00), // 5E
- _L("put", 2, 0x00), // 5F
- _L("put.v", 2, 0x40), // 60
- _L("get.room.v", 2, 0xC0), // 61
- _L("load.sound", 1, 0x00), // 62
- _L("sound", 2, 0x00), // 63
- _L("stop.sound", 0, 0x00), // 64
- _L("print", 1, 0x00), // 65
- _L("print.v", 1, 0x80), // 66
- _L("display", 3, 0x00), // 67
- _L("display.v", 3, 0xE0), // 68
- _L("clear.lines", 3, 0x00), // 69
- _L("text.screen", 0, 0x00), // 6A
- _L("graphics", 0, 0x00), // 6B
- _L("set.cursor.char", 1, 0x00), // 6C
- _L("set.text.attribute", 2, 0x00), // 6D
- _L("shake.screen", 1, 0x00), // 6E
- _L("configure.screen", 3, 0x00), // 6F
- _L("status.line.on", 0, 0x00), // 70
- _L("status.line.off", 0, 0x00), // 71
- _L("set.string", 2, 0x00), // 72
- _L("get.string", 5, 0x00), // 73
- _L("word.to.string", 2, 0x00), // 74
- _L("parse", 1, 0x00), // 75
- _L("get.num", 2, 0x40), // 76
- _L("prevent.input", 0, 0x00), // 77
- _L("accept.input", 0, 0x00), // 78
- _L("set.key", 3, 0x00), // 79
- _L("add.to.pic", 7, 0x00), // 7A
- _L("add.to.pic.v", 7, 0xFE), // 7B
- _L("status", 0, 0x00), // 7C
- _L("save.game", 0, 0x00), // 7D
- _L("restore.game", 0, 0x00), // 7E
- _L("init.disk", 0, 0x00), // 7F
- _L("restart.game", 0, 0x00), // 80
- _L("show.obj", 1, 0x00), // 81
- _L("random", 3, 0x20), // 82
- _L("program.control", 0, 0x00), // 83
- _L("player.control", 0, 0x00), // 84
- _L("obj.status.v", 1, 0x80), // 85
- // 0 args for AGI version 2.089
- _L("quit", 1, 0x00), // 86
-
- _L("show.mem", 0, 0x00), // 87
- _L("pause", 0, 0x00), // 88
- _L("echo.line", 0, 0x00), // 89
- _L("cancel.line", 0, 0x00), // 8A
- _L("init.joy", 0, 0x00), // 8B
- _L("toggle.monitor", 0, 0x00), // 8C
- _L("version", 0, 0x00), // 8D
- _L("script.size", 1, 0x00), // 8E
- _L("set.game.id", 1, 0x00), // 8F
- _L("log", 1, 0x00), // 90
- _L("set.scan.start", 0, 0x00), // 91
- _L("reset.scan.start", 0, 0x00), // 92
- _L("reposition.to", 3, 0x00), // 93
- _L("reposition.to.v", 3, 0x60), // 94
- _L("trace.on", 0, 0x00), // 95
- _L("trace.info", 3, 0x00), // 96
-
- // 3 args for AGI versions before 2.440
- _L("print.at", 4, 0x00), // 97
- _L("print.at.v", 4, 0x80), // 98
-
- _L("discard.view.v", 1, 0x80), // 99
- _L("clear.text.rect", 5, 0x00), // 9A
- _L("set.upper.left", 2, 0x00), // 9B
- _L("set.menu", 1, 0x00), // 9C
- _L("set.menu.item", 2, 0x00), // 9D
- _L("submit.menu", 0, 0x00), // 9E
- _L("enable.item", 1, 0x00), // 9F
- _L("disable.item", 1, 0x00), // A0
- _L("menu.input", 0, 0x00), // A1
- _L("show.obj.v", 1, 0x01), // A2
- _L("open.dialogue", 0, 0x00), // A3
- _L("close.dialogue", 0, 0x00), // A4
- _L("mul.n", 2, 0x80), // A5
- _L("mul.v", 2, 0xC0), // A6
- _L("div.n", 2, 0x80), // A7
- _L("div.v", 2, 0xC0), // A8
- _L("close.window", 0, 0x00), // A9
-
- _L("set.simple", 1, 0x00), // AA
- _L("push.script", 0, 0x00), // AB
- _L("pop.script", 0, 0x00), // AC
- _L("hold.key", 0, 0x00), // AD
- _L("set.pri.base", 1, 0x00), // AE
- _L("discard.sound", 1, 0x00), // AF
-
- // 1 arg for AGI version 3.002.086
- _L("hide.mouse", 0, 0x00), // B0
-
- _L("allow.menu", 1, 0x00), // B1
- _L("show.mouse", 0, 0x00), // B2
- _L("fence.mouse", 4, 0x00), // B3
- _L("mouse.posn", 2, 0x00), // B4
- _L("release.key", 0, 0x00), // B5
-
- // 2 args for at least the Amiga Gold Rush! (v2.05 1989-03-09) using Amiga AGI 2.316.
- _L("adj.ego.move.to.xy", 0, 0x00), // B6
- _L(NULL, 0, 0x00)
+AgiInstruction logicNamesIf[] = {
+ { "OR", "", NULL },
+ { "NOT", "", NULL },
+ { "ELSE", "", NULL },
+ { "IF", "", NULL }
};
void AgiEngine::debugConsole(int lognum, int mode, const char *str) {
- AgiLogicnames *x;
- uint8 a, c, z;
+ AgiInstruction *x;
+ uint8 a, z;
+ const char *c;
if (str) {
debug(0, " %s", str);
@@ -302,8 +71,8 @@ void AgiEngine::debugConsole(int lognum, int mode, const char *str) {
break;
default:
x = mode == lCOMMAND_MODE ? logicNamesCmd : logicNamesTest;
- a = (unsigned char)(x + *(code + ip))->numArgs;
- c = (unsigned char)(x + *(code + ip))->argMask;
+ a = x[*(code + ip)].argumentsLength();
+ c = x[*(code + ip)].args;
if (_debug.opcodes) {
debugN(0, "%02X %02X %02X %02X %02X %02X %02X %02X %02X\n"
@@ -321,12 +90,12 @@ void AgiEngine::debugConsole(int lognum, int mode, const char *str) {
debugN(0, "%s ", (x + *(code + ip))->name);
for (z = 1; a > 0;) {
- if (~c & 0x80) {
+ if (*c == 'n') {
debugN(0, "%d", *(code + (ip + z)));
} else {
debugN(0, "v%d[%d]", *(code + (ip + z)), getvar(*(code + (ip + z))));
}
- c <<= 1;
+ c++;
z++;
if (--a > 0)
debugN(0, ",");
diff --git a/engines/agi/op_test.cpp b/engines/agi/op_test.cpp
index 0660a614b6..a44c68e0fc 100644
--- a/engines/agi/op_test.cpp
+++ b/engines/agi/op_test.cpp
@@ -23,18 +23,180 @@
#include "agi/agi.h"
#include "agi/opcodes.h"
+#include "common/endian.h"
namespace Agi {
-#define ip (_game.logics[lognum].cIP)
-#define code (_game.logics[lognum].data)
+#define ip (state->_curLogic->cIP)
+#define code (state->_curLogic->data)
+
+#define getvar(a) state->_vm->getvar(a)
+#define getflag(a) state->_vm->getflag(a)
#define testEqual(v1, v2) (getvar(v1) == (v2))
#define testLess(v1, v2) (getvar(v1) < (v2))
#define testGreater(v1, v2) (getvar(v1) > (v2))
#define testIsSet(flag) (getflag(flag))
-#define testHas(obj) (objectGetLocation(obj) == EGO_OWNED)
-#define testObjInRoom(obj, v) (objectGetLocation(obj) == getvar(v))
+#define testHas(obj) (state->_vm->objectGetLocation(obj) == EGO_OWNED)
+#define testHasV1(obj) (state->_vm->objectGetLocation(obj) == EGO_OWNED_V1)
+#define testObjInRoom(obj, v) (state->_vm->objectGetLocation(obj) == getvar(v))
+
+void condEqual(AgiGame *state, uint8 *p) {
+ if (p[0] == 11)
+ state->_vm->_timerHack++;
+ state->testResult = testEqual(p[0], p[1]);
+}
+
+void condEqualV(AgiGame *state, uint8 *p) {
+ if (p[0] == 11 || p[1] == 11)
+ state->_vm->_timerHack++;
+ state->testResult = testEqual(p[0], getvar(p[1]));
+}
+
+void condLess(AgiGame *state, uint8 *p) {
+ if (p[0] == 11)
+ state->_vm->_timerHack++;
+ state->testResult = testLess(p[0], p[1]);
+}
+
+void condLessV(AgiGame *state, uint8 *p) {
+ if (p[0] == 11 || p[1] == 11)
+ state->_vm->_timerHack++;
+ state->testResult = testLess(p[0], getvar(p[1]));
+}
+
+void condGreater(AgiGame *state, uint8 *p) {
+ if (p[0] == 11)
+ state->_vm->_timerHack++;
+ state->testResult = testGreater(p[0], p[1]);
+}
+
+void condGreaterV(AgiGame *state, uint8 *p) {
+ if (p[0] == 11 || p[1] == 11)
+ state->_vm->_timerHack++;
+ state->testResult = testGreater(p[0], getvar(p[1]));
+}
+
+void condIsSet(AgiGame *state, uint8 *p) {
+ state->testResult = testIsSet(p[0]);
+}
+
+void condIsSetV(AgiGame *state, uint8 *p) {
+ state->testResult = testIsSet(getvar(p[1]));
+}
+
+void condIsSetV1(AgiGame *state, uint8 *p) {
+ state->testResult = getvar(p[0]) > 0;
+}
+
+void condHas(AgiGame *state, uint8 *p) {
+ state->testResult = testHas(p[0]);
+}
+
+void condHasV1(AgiGame *state, uint8 *p) {
+ state->testResult = testHasV1(p[0]);
+}
+
+void condObjInRoom(AgiGame *state, uint8 *p) {
+ state->testResult = testObjInRoom(p[0], p[1]);
+}
+
+void condPosn(AgiGame *state, uint8 *p) {
+ state->testResult = state->_vm->testPosn(p[0], p[1], p[2], p[3], p[4]);
+}
+
+void condController(AgiGame *state, uint8 *p) {
+ state->testResult = state->_vm->testController(p[0]);
+}
+
+void condHaveKey(AgiGame *state, uint8 *p) {
+ state->testResult = state->_vm->testKeypressed();
+}
+
+void condSaid(AgiGame *state, uint8 *p) {
+ int ec = state->_vm->testSaid(p[0], p + 1);
+ state->testResult = ec;
+}
+
+void condSaid1(AgiGame *state, uint8 *p) {
+ state->testResult = false;
+
+ if (!getflag(fEnteredCli))
+ return;
+
+ int id0 = READ_LE_UINT16(p);
+
+ if ((id0 == 1 || id0 == state->egoWords[0].id))
+ state->testResult = true;
+}
+
+void condSaid2(AgiGame *state, uint8 *p) {
+ state->testResult = false;
+
+ if (!getflag(fEnteredCli))
+ return;
+
+ int id0 = READ_LE_UINT16(p);
+ int id1 = READ_LE_UINT16(p + 2);
+
+ if ((id0 == 1 || id0 == state->egoWords[0].id) &&
+ (id1 == 1 || id1 == state->egoWords[1].id))
+ state->testResult = true;
+}
+
+void condSaid3(AgiGame *state, uint8 *p) {
+ state->testResult = false;
+
+ if (!getflag(fEnteredCli))
+ return;
+
+ int id0 = READ_LE_UINT16(p);
+ int id1 = READ_LE_UINT16(p + 2);
+ int id2 = READ_LE_UINT16(p + 4);
+
+ if ((id0 == 1 || id0 == state->egoWords[0].id) &&
+ (id1 == 1 || id1 == state->egoWords[1].id) &&
+ (id2 == 1 || id2 == state->egoWords[2].id))
+ state->testResult = true;
+}
+
+void condBit(AgiGame *state, uint8 *p) {
+ state->testResult = (getvar(p[1]) >> p[0]) & 1;
+}
+
+void condCompareStrings(AgiGame *state, uint8 *p) {
+ debugC(7, kDebugLevelScripts, "comparing [%s], [%s]", state->strings[p[0]], state->strings[p[1]]);
+ state->testResult = state->_vm->testCompareStrings(p[0], p[1]);
+}
+
+void condObjInBox(AgiGame *state, uint8 *p) {
+ state->testResult = state->_vm->testObjInBox(p[0], p[1], p[2], p[3], p[4]);
+}
+
+void condCenterPosn(AgiGame *state, uint8 *p) {
+ state->testResult = state->_vm->testObjCenter(p[0], p[1], p[2], p[3], p[4]);
+}
+
+void condRightPosn(AgiGame *state, uint8 *p) {
+ state->testResult = state->_vm->testObjRight(p[0], p[1], p[2], p[3], p[4]);
+}
+
+void condUnknown13(AgiGame *state, uint8 *p) {
+ // My current theory is that this command checks whether the ego is currently moving
+ // and that that movement has been caused using the mouse and not using the keyboard.
+ // I base this theory on the game's behavior on an Amiga emulator, not on disassembly.
+ // This command is used at least in the Amiga version of Gold Rush! v2.05 1989-03-09
+ // (AGI 2.316) in logics 1, 3, 5, 6, 137 and 192 (Logic.192 revealed this command's nature).
+ // TODO: Check this command's implementation using disassembly just to be sure.
+ int ec = state->viewTable[0].flags & fAdjEgoXY;
+ debugC(7, kDebugLevelScripts, "op_test: in.motion.using.mouse = %s (Amiga-specific testcase 19)", ec ? "true" : "false");
+ state->testResult = ec;
+}
+
+void condUnknown(AgiGame *state, uint8 *p) {
+ warning("Skipping unknown test command %2X", *(code + ip - 1));
+ state->testResult = false;
+}
uint8 AgiEngine::testCompareStrings(uint8 s1, uint8 s2) {
char ms1[MAX_STRINGLEN];
@@ -147,6 +309,7 @@ uint8 AgiEngine::testObjRight(uint8 n, uint8 x1, uint8 y1, uint8 x2, uint8 y2) {
// When player has entered something, it is parsed elsewhere
uint8 AgiEngine::testSaid(uint8 nwords, uint8 *cc) {
+ AgiGame *state = &_game;
int c, n = _game.numEgoWords;
int z = 0;
@@ -202,210 +365,110 @@ uint8 AgiEngine::testSaid(uint8 nwords, uint8 *cc) {
}
int AgiEngine::testIfCode(int lognum) {
- int ec = true;
- int retval = true;
- uint8 op = 0;
- uint8 notTest = false;
- uint8 orTest = false;
- uint16 lastIp = ip;
- uint8 p[16] = { 0 };
- bool end_test = false;
-
- while (retval && !(shouldQuit() || _restartGame) && !end_test) {
+ AgiGame *state = &_game;
+ uint8 op;
+ uint8 p[16];
+
+ int notMode = false;
+ int orMode = false;
+ int endTest = false;
+ int result = true;
+
+ while (!(shouldQuit() || _restartGame) && !endTest) {
if (_debug.enabled && (_debug.logic0 || lognum))
debugConsole(lognum, lTEST_MODE, NULL);
- lastIp = ip;
op = *(code + ip++);
memmove(p, (code + ip), 16);
switch (op) {
- case 0xFF: // END IF, TEST true
- end_test = true;
- break;
- case 0xFD:
- notTest = !notTest;
- continue;
- case 0xFC: // OR
- // if or_test is ON and we hit 0xFC, end of OR, then
- // or is STILL false so break.
- if (orTest) {
- ec = false;
- retval = false;
- end_test = true;
+ case 0xFC:
+ if (orMode) {
+ // We have reached the end of an OR expression without
+ // a single test command evaluating as true. Thus the OR
+ // expression evalutes as false which means the whole
+ // expression evaluates as false. So skip until the
+ // ending 0xFF and return.
+ skipInstructionsUntil(0xFF);
+ result = false;
+ endTest = true;
+ } else {
+ orMode = true;
}
-
- orTest = true;
continue;
-
+ case 0xFD:
+ notMode = true;
+ continue;
case 0x00:
- // return true?
- end_test = true;
- break;
- case 0x01:
- ec = testEqual(p[0], p[1]);
- if (p[0] == 11)
- _timerHack++;
- break;
- case 0x02:
- ec = testEqual(p[0], getvar(p[1]));
- if (p[0] == 11 || p[1] == 11)
- _timerHack++;
- break;
- case 0x03:
- ec = testLess(p[0], p[1]);
- if (p[0] == 11)
- _timerHack++;
- break;
- case 0x04:
- ec = testLess(p[0], getvar(p[1]));
- if (p[0] == 11 || p[1] == 11)
- _timerHack++;
- break;
- case 0x05:
- ec = testGreater(p[0], p[1]);
- if (p[0] == 11)
- _timerHack++;
- break;
- case 0x06:
- ec = testGreater(p[0], getvar(p[1]));
- if (p[0] == 11 || p[1] == 11)
- _timerHack++;
- break;
- case 0x07:
- ec = testIsSet(p[0]);
- break;
- case 0x08:
- ec = testIsSet(getvar(p[0]));
- break;
- case 0x09:
- ec = testHas(p[0]);
- break;
- case 0x0A:
- ec = testObjInRoom(p[0], p[1]);
- break;
- case 0x0B:
- ec = testPosn(p[0], p[1], p[2], p[3], p[4]);
- break;
- case 0x0C:
- ec = testController(p[0]);
- break;
- case 0x0D:
- ec = testKeypressed();
- break;
- case 0x0E:
- ec = testSaid(p[0], (uint8 *) code + (ip + 1));
- ip = lastIp;
- ip++; // skip opcode
- ip += p[0] * 2; // skip num_words * 2
- ip++; // skip num_words opcode
- break;
- case 0x0F:
- debugC(7, kDebugLevelScripts, "comparing [%s], [%s]", _game.strings[p[0]], _game.strings[p[1]]);
- ec = testCompareStrings(p[0], p[1]);
- break;
- case 0x10:
- ec = testObjInBox(p[0], p[1], p[2], p[3], p[4]);
- break;
- case 0x11:
- ec = testObjCenter(p[0], p[1], p[2], p[3], p[4]);
- break;
- case 0x12:
- ec = testObjRight(p[0], p[1], p[2], p[3], p[4]);
- break;
- case 0x13: // Unknown test command 19
- // My current theory is that this command checks whether the ego is currently moving
- // and that that movement has been caused using the mouse and not using the keyboard.
- // I base this theory on the game's behavior on an Amiga emulator, not on disassembly.
- // This command is used at least in the Amiga version of Gold Rush! v2.05 1989-03-09
- // (AGI 2.316) in logics 1, 3, 5, 6, 137 and 192 (Logic.192 revealed this command's nature).
- // TODO: Check this command's implementation using disassembly just to be sure.
- ec = _game.viewTable[0].flags & ADJ_EGO_XY;
- debugC(7, kDebugLevelScripts, "op_test: in.motion.using.mouse = %s (Amiga-specific testcase 19)", ec ? "true" : "false");
- break;
+ case 0xFF:
+ endTest = true;
+ continue;
+
default:
- ec = false;
- end_test = true;
- }
-
- if (!end_test) {
- if (op <= 0x12)
- ip += logicNamesTest[op].numArgs;
-
- // exchange ec value
- if (notTest)
- ec = !ec;
-
- // not is only enabled for 1 test command
- notTest = false;
-
- if (orTest && ec) {
- // a true inside an OR statement passes
- // ENTIRE statement scan for end of OR
-
- // CM: test for opcode < 0xfc changed from 'op' to
- // '*(code+ip)', to avoid problem with the 0xfd (NOT)
- // opcode byte. Changed a bad ip += ... ip++ construct.
- // This should fix the crash with Larry's logic.0 code:
- //
- // if ((isset(4) ||
- // !isset(2) ||
- // v30 == 2 ||
- // v30 == 1)) {
- // goto Label1;
- // }
- //
- // The bytecode is:
- // ff fc 07 04 fd 07 02 01 1e 02 01 1e 01 fc ff
-
- // find end of OR
- while (*(code + ip) != 0xFC) {
- if (*(code + ip) == 0x0E) { // said
- ip++;
-
- // cover count + ^words
- ip += 1 + ((*(code + ip)) * 2);
- continue;
- }
-
- if (*(code + ip) < 0xFC)
- ip += logicNamesTest[*(code + ip)].numArgs;
- ip++;
+ // Evaluate the command and skip the rest of the instruction
+ _agiCondCommands[op](state, p);
+ skipInstruction(op);
+
+ // NOT mode is enabled only for one instruction
+ if (notMode)
+ state->testResult = !state->testResult;
+ notMode = false;
+
+ if (orMode) {
+ if (state->testResult) {
+ // We are in OR mode and the last test command evaluated
+ // as true, thus the whole OR expression evaluates as
+ // true. So skip the rest of the OR expression and
+ // continue normally.
+ skipInstructionsUntil(0xFC);
+ orMode = false;
+ continue;
}
- ip++;
-
- orTest = false;
- retval = true;
} else {
- retval = orTest ? retval || ec : retval && ec;
+ result &= state->testResult;
+ if (!result) {
+ // Since we are in AND mode and the last test command
+ // evaluated as false, the whole expression also evaluates
+ // as false. So skip until the ending 0xFF and return.
+ skipInstructionsUntil(0xFF);
+ endTest = true;
+ continue;
+ }
}
+ break;
}
}
- // if false, scan for end of IP?
- if (retval)
+ // Skip the following IF block if the condition evaluates as false
+ if (result)
ip += 2;
- else {
- ip = lastIp;
- while (*(code + ip) != 0xff) {
- if (*(code + ip) == 0x0e) {
- ip++;
- ip += (*(code + ip)) * 2 + 1;
- } else if (*(code + ip) < 0xfc) {
- ip += logicNamesTest[*(code + ip)].numArgs;
- ip++;
- } else {
- ip++;
- }
- }
- ip++; // skip over 0xFF
+ else
ip += READ_LE_UINT16(code + ip) + 2;
- }
if (_debug.enabled && (_debug.logic0 || lognum))
- debugConsole(lognum, 0xFF, retval ? "=true" : "=false");
+ debugConsole(lognum, 0xFF, result ? "=true" : "=false");
+
+ return result;
+}
- return retval;
+void AgiEngine::skipInstruction(byte op) {
+ AgiGame *state = &_game;
+ if (op >= 0xFC)
+ return;
+ if (op == 0x0E && state->_vm->getVersion() >= 0x2000) // said
+ ip += *(code + ip) * 2 + 1;
+ else
+ ip += logicNamesTest[op].argumentsLength();
+}
+
+void AgiEngine::skipInstructionsUntil(byte v) {
+ AgiGame *state = &_game;
+ while (1) {
+ byte op = *(code + ip++);
+ if (op == v)
+ return;
+ skipInstruction(op);
+ }
}
} // End of namespace Agi
diff --git a/engines/agi/opcodes.cpp b/engines/agi/opcodes.cpp
new file mode 100644
index 0000000000..c2cecefc52
--- /dev/null
+++ b/engines/agi/opcodes.cpp
@@ -0,0 +1,381 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "agi/agi.h"
+#include "agi/opcodes.h"
+
+namespace Agi {
+
+AgiInstruction *logicNamesTest;
+AgiInstruction *logicNamesCmd;
+
+AgiInstruction insV1Test[] = {
+ { "", "", &condUnknown }, // 00
+ { "equaln", "vn", &condEqual }, // 01
+ { "equalv", "vv", &condEqualV }, // 02
+ { "lessn", "vn", &condLess }, // 03
+ { "lessv", "vv", &condLessV }, // 04
+ { "greatern", "vn", &condGreater }, // 05
+ { "greaterv", "vv", &condGreaterV }, // 06
+ { "isset", "v", &condIsSetV1 }, // 07
+ { "has", "n", &condHasV1 }, // 08
+ { "said", "nnnn", &condSaid2 }, // 09
+ { "posn", "nnnnn", &condPosn }, // 0A
+ { "controller", "n", &condController }, // 0B
+ { "obj.in.room", "nv", &condObjInRoom }, // 0C
+ { "said", "nnnnnn", &condSaid3 }, // 0D
+ { "have.key", "", &condHaveKey }, // 0E
+ { "said", "nn", &condSaid1 }, // 0F
+ { "bit", "nv", &condBit }, // 10
+};
+
+AgiInstruction insV1[] = {
+ { "return", "", NULL }, // 00
+ { "increment", "v", &cmdIncrement }, // 01
+ { "decrement", "v", &cmdDecrement }, // 02
+ { "assignn", "vn", &cmdAssignN }, // 03
+ { "assignv", "vv", &cmdAssignV }, // 04
+ { "addn", "vn", &cmdAddN }, // 05
+ { "addv", "vv", &cmdAddV }, // 06
+ { "subn", "vn", &cmdSubN }, // 07
+ { "subv", "vv", &cmdSubV }, // 08
+ { "load.view", "n", &cmdLoadView }, // 09
+ { "animate.obj", "n", &cmdAnimateObj }, // 0A
+ { "new.room", "n", &cmdNewRoomV1 }, // 0B
+ { "draw.pic", "v", &cmdDrawPicV1 }, // 0C
+ { "print", "s", &cmdPrint }, // 0D TODO
+ { "status", "", &cmdStatus }, // 0E TODO
+ { "save.game", "", &cmdSaveGame }, // 0F TODO
+ { "restore.game", "", &cmdLoadGame }, // 10 TODO
+ { "init.disk", "", &cmdInitDisk }, // 11 TODO
+ { "restart.game", "", &cmdRestartGame }, // 12 TODO
+ { "random", "v", &cmdRandomV1 }, // 13
+ { "get", "n", &cmdGetV1 }, // 14
+ { "drop", "n", &cmdDrop }, // 15
+ { "draw", "n", &cmdDraw }, // 16 TODO
+ { "erase", "n", &cmdErase }, // 17 TODO
+ { "position", "nnn", &cmdPositionV1 }, // 18
+ { "position.v", "nvv", &cmdPositionFV1 }, // 19
+ { "get.posn", "nvv", &cmdGetPosn }, // 1A
+ { "set.cel", "nn", &cmdSetCel }, // 1B
+ { "set.loop", "nn", &cmdSetLoop }, // 1C
+ { "end.of.loop", "nn", &cmdEndOfLoopV1 }, // 1D
+ { "reverse.loop", "nn", &cmdReverseLoopV1 }, // 1E
+ { "move.obj", "nnnnn", &cmdMoveObj }, // 1F
+ { "set.view", "nn", &cmdSetView }, // 20
+ { "follow.ego", "nnn", &cmdFollowEgo }, // 21
+ { "block", "", &cmdBlock }, // 22
+ { "unblock", "", &cmdUnblock }, // 23
+ { "ignore.blocks", "n", &cmdIgnoreBlocks }, // 24
+ { "observe.blocks", "n", &cmdObserveBlocks }, // 25
+ { "wander", "n", &cmdWander }, // 26
+ { "reposition", "nvv", &cmdRepositionV1 }, // 27
+ { "stop.motion", "n", &cmdStopMotionV1 }, // 28
+ { "start.motion", "n", &cmdStartMotionV1 }, // 29
+ { "stop.cycling", "n", &cmdStopCycling }, // 2A
+ { "start.cycling", "n", &cmdStartCycling }, // 2B
+ { "stop.update", "n", &cmdStopUpdate }, // 2C
+ { "start.update", "n", &cmdStartUpdate }, // 2D
+ { "program.control", "", &cmdProgramControl }, // 2E
+ { "player.control", "", &cmdPlayerControl }, // 2F
+ { "set.priority", "nn", &cmdSetPriority }, // 30
+ { "release.priority", "n", &cmdReleasePriority }, // 31
+ { "add.to.pic", "nnnnnn", &cmdAddToPicV1 }, // 32
+ { "set.horizon", "n", &cmdSetHorizon }, // 33
+ { "ignore.horizon", "n", &cmdIgnoreHorizon }, // 34
+ { "observe.horizon", "n", &cmdObserveHorizon }, // 35
+ { "load.logics", "n", &cmdLoadLogic }, // 36 TODO
+ { "object.on.water", "n", &cmdObjectOnWater }, // 37
+ { "load.pic", "v", &cmdLoadPicV1 }, // 38
+ { "load.sound", "n", &cmdLoadSound }, // 39
+ { "sound", "nn", &cmdSound }, // 3A
+ { "stop.sound", "", &cmdStopSound }, // 3B
+ { "set.v", "v", &cmdSetV }, // 3C
+ { "reset.v", "v", &cmdResetV }, // 3D
+ { "toggle.v", "v", &cmdToggleV }, // 3E
+ { "new.room.v", "v", &cmdNewRoomVV1 }, // 3F TODO
+ { "call", "n", &cmdCallV1 }, // 40 TODO
+ { "quit", "", &cmdQuitV1 }, // 41
+ { "set.speed", "v", &cmdSetSpeed }, // 42
+ { "move.obj.v", "nvvvv", &cmdMoveObjF }, // 43
+ { "...", "nn", &cmdUnknown }, // 44
+ { "get.v", "v", &cmdUnknown }, // 45
+ { "assign.v", "vv", &cmdUnknown }, // 46
+ { "...", "n", &cmdUnknown }, // 47 # printvar.v
+ { "get.priority", "nv", &cmdGetPriority }, // 48
+ { "ignore.objs", "n", &cmdIgnoreObjs }, // 49
+ { "observe.objs", "n", &cmdObserveObjs }, // 4A
+ { "distance", "nnv", &cmdDistance }, // 4B
+ { "object.on.land", "n", &cmdObjectOnLand }, // 4C
+ { "...", "nv", &cmdUnknown }, // 4D # set.priority.f
+ { "...", "", &cmdUnknown }, // 4E # show.obj
+ { "load.logics", "n", &cmdLoadLogic }, // 4F # load.global.logics
+ { "display", "nnns", &cmdDisplay }, // 50 TODO: 4 vs 3 args
+ { "prevent.input???", "", &cmdUnknown }, // 51
+ { "...", "", &cmdUnknown }, // 52 # nop
+ { "...", "n", &cmdUnknown }, // 53 # text.screen
+ { "...", "", &cmdUnknown }, // 54 ???
+ { "stop.motion", "", &cmdStopMotion }, // 55 or force.update??
+ { "discard.view", "n", &cmdDiscardView }, // 56
+ { "discard.pic", "v", &cmdDiscardPic }, // 57
+ { "set.item.view", "nn", &cmdSetItemView }, // 58
+ { "...", "", &cmdUnknown }, // 59 # reverse.cycle
+ { "last.cel", "nv", &cmdLastCel }, // 5A
+ { "set.cel.v", "nv", &cmdSetCelF }, // 5B
+ { "...", "", &cmdUnknown }, // 5C # normal.cycle
+ { "load.view", "n", &cmdLoadView }, // 5D
+ { "...", "", &cmdUnknown }, // 5E
+ { "...", "", &cmdUnknown }, // 5F
+ { "setbit", "nv", &cmdUnknown }, // 60
+ { "...", "nv", &cmdUnknown }, // 61 # clearbit
+};
+
+AgiInstruction insV2Test[] = {
+ { "", "", &condUnknown }, // 00
+ { "equaln", "vn", &condEqual }, // 01
+ { "equalv", "vv", &condEqualV }, // 02
+ { "lessn", "vn", &condLess }, // 03
+ { "lessv", "vv", &condLessV }, // 04
+ { "greatern", "vn", &condGreater }, // 05
+ { "greaterv", "vv", &condGreaterV }, // 06
+ { "isset", "n", &condIsSet }, // 07
+ { "issetv", "v", &condIsSetV }, // 08
+ { "has", "n", &condHas }, // 09
+ { "obj.in.room", "nv", &condObjInRoom}, // 0A
+ { "posn", "nnnnn", &condPosn }, // 0B
+ { "controller", "n", &condController }, // 0C
+ { "have.key", "", &condHaveKey}, // 0D
+ { "said", "", &condSaid }, // 0E
+ { "compare.strings", "ss", &condCompareStrings }, // 0F
+ { "obj.in.box", "nnnnn", &condObjInBox }, // 10
+ { "center.posn", "nnnnn", &condCenterPosn }, // 11
+ { "right.posn", "nnnnn", &condRightPosn }, // 12
+ { "in.motion.using.mouse", "", &condUnknown13 } // 13
+};
+
+AgiInstruction insV2[] = {
+ { "return", "", NULL },
+ { "increment", "v", &cmdIncrement },
+ { "decrement", "v", &cmdDecrement },
+ { "assignn", "vn", &cmdAssignN },
+ { "assignv", "vv", &cmdAssignV },
+ { "addn", "vn", &cmdAddN },
+ { "addv", "vv", &cmdAddV },
+ { "subn", "vn", &cmdSubN },
+ { "subv", "vv", &cmdSubV },
+ { "lindirectv", "vv", &cmdLindirectV },
+ { "lindirect", "vv", &cmdRindirect },
+ { "lindirectn", "vn", &cmdLindirectN },
+ { "set", "n", &cmdSet },
+ { "reset", "n", &cmdReset },
+ { "toggle", "n", &cmdToggle },
+ { "set.v", "v", &cmdSetV },
+ { "reset.v", "v", &cmdResetV },
+ { "toggle.v", "v", &cmdToggleV },
+ { "new.room", "n", &cmdNewRoom },
+ { "new.room.v", "v", &cmdNewRoomF },
+ { "load.logics", "n", &cmdLoadLogic },
+ { "load.logics.v", "v", &cmdLoadLogicF },
+ { "call", "n", &cmdCall },
+ { "call.v", "v", &cmdCallF },
+ { "load.pic", "v", &cmdLoadPic },
+ { "draw.pic", "v", &cmdDrawPic },
+ { "show.pic", "", &cmdShowPic },
+ { "discard.pic", "v", &cmdDiscardPic },
+ { "overlay.pic", "v", &cmdOverlayPic },
+ { "show.pri.screen", "", &cmdShowPriScreen },
+ { "load.view", "n", &cmdLoadView },
+ { "load.view.v", "v", &cmdLoadViewF },
+ { "discard.view", "n", &cmdDiscardView },
+ { "animate.obj", "n", &cmdAnimateObj },
+ { "unanimate.all", "", &cmdUnanimateAll },
+ { "draw", "n", &cmdDraw },
+ { "erase", "n", &cmdErase },
+ { "position", "nnn", &cmdPosition },
+ { "position.v", "nvv", &cmdPositionF },
+ { "get.posn", "nvv", &cmdGetPosn },
+ { "reposition", "nvv", &cmdReposition },
+ { "set.view", "nn", &cmdSetView },
+ { "set.view.v", "nv", &cmdSetViewF },
+ { "set.loop", "nn", &cmdSetLoop },
+ { "set.loop.v", "nv", &cmdSetLoopF },
+ { "fix.loop", "n", &cmdFixLoop },
+ { "release.loop", "n", &cmdReleaseLoop },
+ { "set.cel", "nn", &cmdSetCel },
+ { "set.cel.v", "nv", &cmdSetCelF },
+ { "last.cel", "nv", &cmdLastCel },
+ { "current.cel", "nv", &cmdCurrentCel },
+ { "current.loop", "nv", &cmdCurrentLoop },
+ { "current.view", "nv", &cmdCurrentView },
+ { "number.of.loops", "nv", &cmdNumberOfLoops },
+ { "set.priority", "nn", &cmdSetPriority },
+ { "set.priority.v", "nv", &cmdSetPriorityF },
+ { "release.priority", "n", &cmdReleasePriority },
+ { "get.priority", "nn", &cmdGetPriority },
+ { "stop.update", "n", &cmdStopUpdate },
+ { "start.update", "n", &cmdStartUpdate },
+ { "force.update", "n", &cmdForceUpdate },
+ { "ignore.horizon", "n", &cmdIgnoreHorizon },
+ { "observe.horizon", "n", &cmdObserveHorizon },
+ { "set.horizon", "n", &cmdSetHorizon },
+ { "object.on.water", "n", &cmdObjectOnWater },
+ { "object.on.land", "n", &cmdObjectOnLand },
+ { "object.on.anything", "n", &cmdObjectOnAnything },
+ { "ignore.objs", "n", &cmdIgnoreObjs },
+ { "observe.objs", "n", &cmdObserveObjs },
+ { "distance", "nnv", &cmdDistance },
+ { "stop.cycling", "n", &cmdStopCycling },
+ { "start.cycling", "n", &cmdStartCycling },
+ { "normal.cycle", "n", &cmdNormalCycle },
+ { "end.of.loop", "nn", &cmdEndOfLoop },
+ { "reverse.cycle", "n", &cmdReverseCycle },
+ { "reverse.loop", "nn", &cmdReverseLoop },
+ { "cycle.time", "nv", &cmdCycleTime },
+ { "stop.motion", "n", &cmdStopMotion },
+ { "start.motion", "n", &cmdStartMotion },
+ { "step.size", "nv", &cmdStepSize },
+ { "step.time", "nv", &cmdStepTime },
+ { "move.obj", "nnnnn", &cmdMoveObj },
+ { "move.obj.v", "nvvvv", &cmdMoveObjF },
+ { "follow.ego", "nnn", &cmdFollowEgo },
+ { "wander", "n", &cmdWander },
+ { "normal.motion", "n", &cmdNormalMotion },
+ { "set.dir", "nv", &cmdSetDir },
+ { "get.dir", "nv", &cmdGetDir },
+ { "ignore.blocks", "n", &cmdIgnoreBlocks },
+ { "observe.blocks", "n", &cmdObserveBlocks },
+ { "block", "nnnn", &cmdBlock },
+ { "unblock", "", &cmdUnblock },
+ { "get", "n", &cmdGet },
+ { "get.v", "v", &cmdGetF },
+ { "drop", "n", &cmdDrop },
+ { "put", "nn", &cmdPut },
+ { "put.v", "vv", &cmdPutF },
+ { "get.room.v", "vv", &cmdGetRoomF },
+ { "load.sound", "n", &cmdLoadSound },
+ { "sound", "nn", &cmdSound },
+ { "stop.sound", "", &cmdStopSound },
+ { "print", "s", &cmdPrint },
+ { "print.v", "v", &cmdPrintF },
+ { "display", "nns", &cmdDisplay },
+ { "display.v", "vvv", &cmdDisplayF },
+ { "clear.lines", "nns", &cmdClearLines },
+ { "text.screen", "", &cmdTextScreen },
+ { "graphics", "", &cmdGraphics },
+ { "set.cursor.char", "s", &cmdSetCursorChar },
+ { "set.text.attribute", "nn", &cmdSetTextAttribute },
+ { "shake.screen", "n", &cmdShakeScreen },
+ { "configure.screen", "nnn", &cmdConfigureScreen },
+ { "status.line.on", "", &cmdStatusLineOn },
+ { "status.line.off", "", &cmdStatusLineOff },
+ { "set.string", "ns", &cmdSetString },
+ { "get.string", "ns", &cmdGetString },
+ { "word.to.string", "nn", &cmdWordToString },
+ { "parse", "n", &cmdParse },
+ { "get.num", "nv", &cmdGetNum },
+ { "prevent.input", "", &cmdPreventInput },
+ { "accept.input", "", &cmdAcceptInput },
+ { "set.key", "nnn", &cmdSetKey },
+ { "add.to.pic", "nnnnnnn", &cmdAddToPic },
+ { "add.to.pic.v", "vvvvvvv", &cmdAddToPicF },
+ { "status", "", &cmdStatus },
+ { "save.game", "", &cmdSaveGame },
+ { "restore.game", "", &cmdLoadGame },
+ { "init.disk", "", &cmdInitDisk },
+ { "restart.game", "", &cmdRestartGame },
+ { "show.obj", "n", &cmdShowObj },
+ { "random", "nnv", &cmdRandom },
+ { "program.control", "", &cmdProgramControl },
+ { "player.control", "", &cmdPlayerControl },
+ { "obj.status.v", "v", &cmdObjStatusF },
+ { "quit", "n", &cmdQuit },
+ { "show.mem", "", &cmdShowMem },
+ { "pause", "", &cmdPause },
+ { "echo.line", "", &cmdEchoLine },
+ { "cancel.line", "", &cmdCancelLine },
+ { "init.joy", "", &cmdInitJoy },
+ { "toggle.monitor", "", &cmdToggleMonitor },
+ { "version", "", &cmdVersion },
+ { "script.size", "n", &cmdScriptSize },
+ { "set.game.id", "s", &cmdSetGameID },
+ { "log", "s", &cmdLog },
+ { "set.scan.start", "", &cmdSetScanStart },
+ { "reset.scan.start", "", &cmdResetScanStart },
+ { "reposition.to", "nnn", &cmdRepositionTo },
+ { "reposition.to.v", "nvv", &cmdRepositionToF },
+ { "trace.on", "", &cmdTraceOn },
+ { "trace.info", "nnn", &cmdTraceInfo },
+ { "print.at", "snnn", &cmdPrintAt },
+ { "print.at.v", "vnnn", &cmdPrintAtV },
+ { "discard.view.v", "v", &cmdDiscardView},
+ { "clear.text.rect", "nnnnn", &cmdClearTextRect },
+ { "set.upper.left", "nn", &cmdSetUpperLeft },
+ { "set.menu", "s", &cmdSetMenu },
+ { "set.menu.member", "sn", &cmdSetMenuItem },
+ { "submit.menu", "", &cmdSubmitMenu },
+ { "enable.member", "n", &cmdEnableItem },
+ { "disable.member", "n", &cmdDisableItem },
+ { "menu.input", "", &cmdMenuInput },
+ { "show.obj.v", "v", &cmdShowObjV },
+ { "open.dialogue", "", &cmdOpenDialogue },
+ { "close.dialogue", "", &cmdCloseDialogue },
+ { "mul.n", "vn", &cmdMulN },
+ { "mul.v", "vv", &cmdMulV },
+ { "div.n", "vn", &cmdDivN },
+ { "div.v", "vv", &cmdDivV },
+ { "close.window", "", &cmdCloseWindow },
+ { "set.simple", "n", &cmdSetSimple },
+ { "push.script", "", &cmdPushScript },
+ { "pop.script", "", &cmdPopScript },
+ { "hold.key", "", &cmdHoldKey },
+ { "set.pri.base", "n", &cmdSetPriBase },
+ { "discard.sound", "n", &cmdDiscardSound },
+ { "hide.mouse", "", &cmdHideMouse },
+ { "allow.menu", "n", &cmdAllowMenu },
+ { "show.mouse", "", &cmdShowMouse },
+ { "fence.mouse", "nnnn", &cmdFenceMouse },
+ { "mouse.posn", "vv", &cmdMousePosn },
+ { "release.key", "", &cmdReleaseKey },
+ { "adj.ego.move.to.xy", "", &cmdAdjEgoMoveToXY }
+};
+
+void AgiEngine::setupOpcodes() {
+ if (getVersion() >= 0x2000) {
+ for (int i = 0; i <= ARRAYSIZE(insV2Test); ++i)
+ _agiCondCommands[i] = insV2Test[i].func;
+ for (int i = 0; i < ARRAYSIZE(insV2); ++i)
+ _agiCommands[i] = insV2[i].func;
+
+ logicNamesTest = insV2Test;
+ logicNamesCmd = insV2;
+ } else {
+ for (int i = 0; i <= ARRAYSIZE(insV1Test); ++i)
+ _agiCondCommands[i] = insV1Test[i].func;
+ for (int i = 0; i < ARRAYSIZE(insV1); ++i)
+ _agiCommands[i] = insV1[i].func;
+
+ logicNamesTest = insV1Test;
+ logicNamesCmd = insV1;
+ }
+}
+
+}
diff --git a/engines/agi/opcodes.h b/engines/agi/opcodes.h
index b0d2051f0b..7f0f287550 100644
--- a/engines/agi/opcodes.h
+++ b/engines/agi/opcodes.h
@@ -23,17 +23,251 @@
#ifndef AGI_OPCODES_H
#define AGI_OPCODES_H
+#include <string.h>
+
namespace Agi {
-struct AgiLogicnames {
+struct AgiInstruction {
const char *name;
- uint16 numArgs;
- uint16 argMask;
+ const char *args;
+ AgiCommand func;
+
+ int argumentsLength() { return strlen(args); }
};
-extern AgiLogicnames logicNamesTest[];
-extern AgiLogicnames logicNamesCmd[];
-extern AgiLogicnames logicNamesIf[];
+extern AgiInstruction *logicNamesTest;
+extern AgiInstruction *logicNamesCmd;
+
+void cmdIncrement(AgiGame *state, uint8 *p);
+void cmdDecrement(AgiGame *state, uint8 *p);
+void cmdAssignN(AgiGame *state, uint8 *p);
+void cmdAssignV(AgiGame *state, uint8 *p);
+void cmdAddN(AgiGame *state, uint8 *p);
+void cmdAddV(AgiGame *state, uint8 *p);
+void cmdSubN(AgiGame *state, uint8 *p);
+void cmdSubV(AgiGame *state, uint8 *p); // 0x08
+void cmdLindirectV(AgiGame *state, uint8 *p);
+void cmdRindirect(AgiGame *state, uint8 *p);
+void cmdLindirectN(AgiGame *state, uint8 *p);
+void cmdSet(AgiGame *state, uint8 *p);
+void cmdReset(AgiGame *state, uint8 *p);
+void cmdToggle(AgiGame *state, uint8 *p);
+void cmdSetV(AgiGame *state, uint8 *p);
+void cmdResetV(AgiGame *state, uint8 *p); // 0x10
+void cmdToggleV(AgiGame *state, uint8 *p);
+void cmdNewRoom(AgiGame *state, uint8 *p);
+void cmdNewRoomF(AgiGame *state, uint8 *p);
+void cmdLoadLogic(AgiGame *state, uint8 *p);
+void cmdLoadLogicF(AgiGame *state, uint8 *p);
+void cmdCall(AgiGame *state, uint8 *p);
+void cmdCallF(AgiGame *state, uint8 *p);
+void cmdLoadPic(AgiGame *state, uint8 *p); // 0x18
+void cmdLoadPicV1(AgiGame *state, uint8 *p);
+void cmdDrawPic(AgiGame *state, uint8 *p);
+void cmdDrawPicV1(AgiGame *state, uint8 *p);
+void cmdShowPic(AgiGame *state, uint8 *p);
+void cmdDiscardPic(AgiGame *state, uint8 *p);
+void cmdOverlayPic(AgiGame *state, uint8 *p);
+void cmdShowPriScreen(AgiGame *state, uint8 *p);
+void cmdLoadView(AgiGame *state, uint8 *p);
+void cmdLoadViewF(AgiGame *state, uint8 *p);
+void cmdDiscardView(AgiGame *state, uint8 *p); // 0x20
+void cmdAnimateObj(AgiGame *state, uint8 *p);
+void cmdUnanimateAll(AgiGame *state, uint8 *p);
+void cmdDraw(AgiGame *state, uint8 *p);
+void cmdErase(AgiGame *state, uint8 *p);
+void cmdPosition(AgiGame *state, uint8 *p);
+void cmdPositionV1(AgiGame *state, uint8 *p);
+void cmdPositionF(AgiGame *state, uint8 *p);
+void cmdPositionFV1(AgiGame *state, uint8 *p);
+void cmdGetPosn(AgiGame *state, uint8 *p);
+void cmdReposition(AgiGame *state, uint8 *p); // 0x28
+void cmdRepositionV1(AgiGame *state, uint8 *p); // 0x28
+void cmdSetView(AgiGame *state, uint8 *p);
+void cmdSetViewF(AgiGame *state, uint8 *p);
+void cmdSetLoop(AgiGame *state, uint8 *p);
+void cmdSetLoopF(AgiGame *state, uint8 *p);
+void cmdFixLoop(AgiGame *state, uint8 *p);
+void cmdReleaseLoop(AgiGame *state, uint8 *p);
+void cmdSetCel(AgiGame *state, uint8 *p);
+void cmdSetCelF(AgiGame *state, uint8 *p); // 0x30
+void cmdLastCel(AgiGame *state, uint8 *p);
+void cmdCurrentCel(AgiGame *state, uint8 *p);
+void cmdCurrentLoop(AgiGame *state, uint8 *p);
+void cmdCurrentView(AgiGame *state, uint8 *p);
+void cmdNumberOfLoops(AgiGame *state, uint8 *p);
+void cmdSetPriority(AgiGame *state, uint8 *p);
+void cmdSetPriorityF(AgiGame *state, uint8 *p);
+void cmdReleasePriority(AgiGame *state, uint8 *p); // 0x38
+void cmdGetPriority(AgiGame *state, uint8 *p);
+void cmdStopUpdate(AgiGame *state, uint8 *p);
+void cmdStartUpdate(AgiGame *state, uint8 *p);
+void cmdForceUpdate(AgiGame *state, uint8 *p);
+void cmdIgnoreHorizon(AgiGame *state, uint8 *p);
+void cmdObserveHorizon(AgiGame *state, uint8 *p);
+void cmdSetHorizon(AgiGame *state, uint8 *p);
+void cmdObjectOnWater(AgiGame *state, uint8 *p); // 0x40
+void cmdObjectOnLand(AgiGame *state, uint8 *p);
+void cmdObjectOnAnything(AgiGame *state, uint8 *p);
+void cmdIgnoreObjs(AgiGame *state, uint8 *p);
+void cmdObserveObjs(AgiGame *state, uint8 *p);
+void cmdDistance(AgiGame *state, uint8 *p);
+void cmdStopCycling(AgiGame *state, uint8 *p);
+void cmdStartCycling(AgiGame *state, uint8 *p);
+void cmdNormalCycle(AgiGame *state, uint8 *p); // 0x48
+void cmdEndOfLoop(AgiGame *state, uint8 *p);
+void cmdEndOfLoopV1(AgiGame *state, uint8 *p);
+void cmdReverseCycle(AgiGame *state, uint8 *p);
+void cmdReverseLoop(AgiGame *state, uint8 *p);
+void cmdReverseLoopV1(AgiGame *state, uint8 *p);
+void cmdCycleTime(AgiGame *state, uint8 *p);
+void cmdStopMotion(AgiGame *state, uint8 *p);
+void cmdStopMotionV1(AgiGame *state, uint8 *p);
+void cmdStartMotion(AgiGame *state, uint8 *p);
+void cmdStartMotionV1(AgiGame *state, uint8 *p);
+void cmdStepSize(AgiGame *state, uint8 *p);
+void cmdStepTime(AgiGame *state, uint8 *p); // 0x50
+void cmdMoveObj(AgiGame *state, uint8 *p);
+void cmdMoveObjF(AgiGame *state, uint8 *p);
+void cmdFollowEgo(AgiGame *state, uint8 *p);
+void cmdWander(AgiGame *state, uint8 *p);
+void cmdNormalMotion(AgiGame *state, uint8 *p);
+void cmdSetDir(AgiGame *state, uint8 *p);
+void cmdGetDir(AgiGame *state, uint8 *p);
+void cmdIgnoreBlocks(AgiGame *state, uint8 *p); // 0x58
+void cmdObserveBlocks(AgiGame *state, uint8 *p);
+void cmdBlock(AgiGame *state, uint8 *p);
+void cmdUnblock(AgiGame *state, uint8 *p);
+void cmdGet(AgiGame *state, uint8 *p);
+void cmdGetV1(AgiGame *state, uint8 *p);
+void cmdGetF(AgiGame *state, uint8 *p);
+void cmdDrop(AgiGame *state, uint8 *p);
+void cmdPut(AgiGame *state, uint8 *p);
+void cmdPutF(AgiGame *state, uint8 *p); // 0x60
+void cmdGetRoomF(AgiGame *state, uint8 *p);
+void cmdLoadSound(AgiGame *state, uint8 *p);
+void cmdSound(AgiGame *state, uint8 *p);
+void cmdStopSound(AgiGame *state, uint8 *p);
+void cmdPrint(AgiGame *state, uint8 *p);
+void cmdPrintF(AgiGame *state, uint8 *p);
+void cmdDisplay(AgiGame *state, uint8 *p);
+void cmdDisplayF(AgiGame *state, uint8 *p); // 0x68
+void cmdClearLines(AgiGame *state, uint8 *p);
+void cmdTextScreen(AgiGame *state, uint8 *p);
+void cmdGraphics(AgiGame *state, uint8 *p);
+void cmdSetCursorChar(AgiGame *state, uint8 *p);
+void cmdSetTextAttribute(AgiGame *state, uint8 *p);
+void cmdShakeScreen(AgiGame *state, uint8 *p);
+void cmdConfigureScreen(AgiGame *state, uint8 *p);
+void cmdStatusLineOn(AgiGame *state, uint8 *p); // 0x70
+void cmdStatusLineOff(AgiGame *state, uint8 *p);
+void cmdSetString(AgiGame *state, uint8 *p);
+void cmdGetString(AgiGame *state, uint8 *p);
+void cmdWordToString(AgiGame *state, uint8 *p);
+void cmdParse(AgiGame *state, uint8 *p);
+void cmdGetNum(AgiGame *state, uint8 *p);
+void cmdPreventInput(AgiGame *state, uint8 *p);
+void cmdAcceptInput(AgiGame *state, uint8 *p); // 0x78
+void cmdSetKey(AgiGame *state, uint8 *p);
+void cmdAddToPic(AgiGame *state, uint8 *p);
+void cmdAddToPicV1(AgiGame *state, uint8 *p);
+void cmdAddToPicF(AgiGame *state, uint8 *p);
+void cmdStatus(AgiGame *state, uint8 *p);
+void cmdSaveGame(AgiGame *state, uint8 *p);
+void cmdLoadGame(AgiGame *state, uint8 *p);
+void cmdInitDisk(AgiGame *state, uint8 *p);
+void cmdRestartGame(AgiGame *state, uint8 *p); // 0x80
+void cmdShowObj(AgiGame *state, uint8 *p);
+void cmdRandom(AgiGame *state, uint8 *p);
+void cmdRandomV1(AgiGame *state, uint8 *p);
+void cmdProgramControl(AgiGame *state, uint8 *p);
+void cmdPlayerControl(AgiGame *state, uint8 *p);
+void cmdObjStatusF(AgiGame *state, uint8 *p);
+void cmdQuit(AgiGame *state, uint8 *p);
+void cmdQuitV1(AgiGame *state, uint8 *p);
+void cmdShowMem(AgiGame *state, uint8 *p);
+void cmdPause(AgiGame *state, uint8 *p); // 0x88
+void cmdEchoLine(AgiGame *state, uint8 *p);
+void cmdCancelLine(AgiGame *state, uint8 *p);
+void cmdInitJoy(AgiGame *state, uint8 *p);
+void cmdToggleMonitor(AgiGame *state, uint8 *p);
+void cmdVersion(AgiGame *state, uint8 *p);
+void cmdScriptSize(AgiGame *state, uint8 *p);
+void cmdSetGameID(AgiGame *state, uint8 *p);
+void cmdLog(AgiGame *state, uint8 *p); // 0x90
+void cmdSetScanStart(AgiGame *state, uint8 *p);
+void cmdResetScanStart(AgiGame *state, uint8 *p);
+void cmdRepositionTo(AgiGame *state, uint8 *p);
+void cmdRepositionToF(AgiGame *state, uint8 *p);
+void cmdTraceOn(AgiGame *state, uint8 *p);
+void cmdTraceInfo(AgiGame *state, uint8 *p);
+void cmdPrintAt(AgiGame *state, uint8 *p);
+void cmdPrintAtV(AgiGame *state, uint8 *p); // 0x98
+//void cmdDiscardView(AgiGame *state, uint8 *p); // Opcode repeated from 0x20 ?
+void cmdClearTextRect(AgiGame *state, uint8 *p);
+void cmdSetUpperLeft(AgiGame *state, uint8 *p);
+void cmdSetMenu(AgiGame *state, uint8 *p);
+void cmdSetMenuItem(AgiGame *state, uint8 *p);
+void cmdSubmitMenu(AgiGame *state, uint8 *p);
+void cmdEnableItem(AgiGame *state, uint8 *p);
+void cmdDisableItem(AgiGame *state, uint8 *p); // 0xa0
+void cmdMenuInput(AgiGame *state, uint8 *p);
+void cmdShowObjV(AgiGame *state, uint8 *p);
+void cmdOpenDialogue(AgiGame *state, uint8 *p);
+void cmdCloseDialogue(AgiGame *state, uint8 *p);
+void cmdMulN(AgiGame *state, uint8 *p);
+void cmdMulV(AgiGame *state, uint8 *p);
+void cmdDivN(AgiGame *state, uint8 *p);
+void cmdDivV(AgiGame *state, uint8 *p); // 0xa8
+void cmdCloseWindow(AgiGame *state, uint8 *p);
+void cmdSetSimple(AgiGame *state, uint8 *p);
+void cmdPushScript(AgiGame *state, uint8 *p);
+void cmdPopScript(AgiGame *state, uint8 *p);
+void cmdHoldKey(AgiGame *state, uint8 *p);
+void cmdSetPriBase(AgiGame *state, uint8 *p);
+void cmdDiscardSound(AgiGame *state, uint8 *p);
+void cmdHideMouse(AgiGame *state, uint8 *p); // 0xb0
+void cmdAllowMenu(AgiGame *state, uint8 *p);
+void cmdShowMouse(AgiGame *state, uint8 *p);
+void cmdFenceMouse(AgiGame *state, uint8 *p);
+void cmdMousePosn(AgiGame *state, uint8 *p);
+void cmdReleaseKey(AgiGame *state, uint8 *p);
+void cmdAdjEgoMoveToXY(AgiGame *state, uint8 *p);
+
+void cmdSetSpeed(AgiGame *state, uint8 *p);
+void cmdSetItemView(AgiGame *state, uint8 *p);
+void cmdCallV1(AgiGame *state, uint8 *p);
+void cmdNewRoomV1(AgiGame *state, uint8 *p);
+void cmdNewRoomVV1(AgiGame *state, uint8 *p);
+void cmdUnknown(AgiGame *state, uint8 *p);
+
+void condEqual(AgiGame *state, uint8 *p);
+void condEqualV(AgiGame *state, uint8 *p);
+void condLess(AgiGame *state, uint8 *p);
+void condLessV(AgiGame *state, uint8 *p);
+void condGreater(AgiGame *state, uint8 *p);
+void condGreaterV(AgiGame *state, uint8 *p);
+void condIsSet(AgiGame *state, uint8 *p);
+void condIsSetV(AgiGame *state, uint8 *p);
+void condHas(AgiGame *state, uint8 *p);
+void condHasV1(AgiGame *state, uint8 *p);
+void condObjInRoom(AgiGame *state, uint8 *p);
+void condPosn(AgiGame *state, uint8 *p);
+void condController(AgiGame *state, uint8 *p);
+void condHaveKey(AgiGame *state, uint8 *p);
+void condSaid(AgiGame *state, uint8 *p);
+void condCompareStrings(AgiGame *state, uint8 *p);
+void condObjInBox(AgiGame *state, uint8 *p);
+void condCenterPosn(AgiGame *state, uint8 *p);
+void condRightPosn(AgiGame *state, uint8 *p);
+void condUnknown13(AgiGame *state, uint8 *p);
+void condUnknown(AgiGame *state, uint8 *p);
+
+void condIsSetV1(AgiGame *state, uint8 *p);
+void condSaid1(AgiGame *state, uint8 *p);
+void condSaid2(AgiGame *state, uint8 *p);
+void condSaid3(AgiGame *state, uint8 *p);
+void condBit(AgiGame *state, uint8 *p);
} // End of namespace Agi
diff --git a/engines/agi/preagi.cpp b/engines/agi/preagi.cpp
index c1a6cd33fe..34180b543f 100644
--- a/engines/agi/preagi.cpp
+++ b/engines/agi/preagi.cpp
@@ -22,18 +22,13 @@
#include "common/config-manager.h"
#include "common/debug-channels.h"
+#include "common/events.h"
#include "common/random.h"
#include "common/textconsole.h"
-#include "audio/mididrv.h"
-
#include "agi/preagi.h"
#include "agi/graphics.h"
-
-// preagi engines
-#include "agi/preagi_mickey.h"
-#include "agi/preagi_troll.h"
-#include "agi/preagi_winnie.h"
+#include "agi/keyboard.h"
namespace Agi {
@@ -59,19 +54,6 @@ PreAgiEngine::PreAgiEngine(OSystem *syst, const AGIGameDescription *gameDesc) :
}
void PreAgiEngine::initialize() {
- // TODO: Some sound emulation modes do not fit our current music
- // drivers, and I'm not sure what they are. For now, they might
- // as well be called "PC Speaker" and "Not PC Speaker".
-
- switch (MidiDriver::getMusicType(MidiDriver::detectDevice(MDT_PCSPK))) {
- case MT_PCSPK:
- _soundemu = SOUND_EMU_PC;
- break;
- default:
- _soundemu = SOUND_EMU_NONE;
- break;
- }
-
if (ConfMan.hasKey("render_mode")) {
_renderMode = Common::parseRenderMode(ConfMan.get("render_mode").c_str());
} else if (ConfMan.hasKey("platform")) {
@@ -89,9 +71,7 @@ void PreAgiEngine::initialize() {
}
_gfx = new GfxMgr(this);
- //_sound = new SoundMgr(this, _mixer);
_picture = new PictureMgr(this, _gfx);
- //_sprites = new SpritesMgr(this, _gfx);
_gfx->initMachine();
@@ -111,7 +91,6 @@ void PreAgiEngine::initialize() {
_game.lineMinPrint = 0; // hardcoded
_gfx->initVideo();
- //_sound->initSound();
_speakerStream = new Audio::PCSpeaker(_mixer->getOutputRate());
_mixer->playStream(Audio::Mixer::kSFXSoundType, &_speakerHandle,
@@ -126,8 +105,6 @@ void PreAgiEngine::initialize() {
memset(&_game.dirPic[i], 0, sizeof(struct AgiDir));
memset(&_game.dirSound[i], 0, sizeof(struct AgiDir));
}
-
- debugC(2, kDebugLevelMain, "Init sound");
}
PreAgiEngine::~PreAgiEngine() {
@@ -135,50 +112,181 @@ PreAgiEngine::~PreAgiEngine() {
delete _speakerStream;
}
+int PreAgiEngine::rnd(int hi) {
+ return (_rnd->getRandomNumber(hi - 1) + 1);
+}
+
+// Screen functions
+void PreAgiEngine::clearScreen(int attr, bool overrideDefault) {
+ if (overrideDefault)
+ _defaultColor = attr;
-Common::Error PreAgiEngine::go() {
- setflag(fSoundOn, true); // enable sound
+ _gfx->clearScreen((attr & 0xF0) / 0x10);
+}
-//
-// FIXME (Fingolfin asks): Why are Mickey, Winnie and Troll standalone classes
-// instead of being subclasses of PreAgiEngine ?
-//
+void PreAgiEngine::clearGfxScreen(int attr) {
+ _gfx->drawRectangle(0, 0, GFX_WIDTH - 1, IDI_MAX_ROW_PIC * 8 -1, (attr & 0xF0) / 0x10);
+}
- // run preagi engine main loop
- switch (getGameID()) {
- case GID_MICKEY:
- {
- Mickey *mickey = new Mickey(this);
- mickey->init();
- mickey->run();
- delete mickey;
- }
- break;
- case GID_WINNIE:
- {
- Winnie *winnie = new Winnie(this);
- winnie->init();
- winnie->run();
- delete winnie;
+// String functions
+
+void PreAgiEngine::drawStr(int row, int col, int attr, const char *buffer) {
+ int code;
+
+ if (attr == kColorDefault)
+ attr = _defaultColor;
+
+ for (int iChar = 0; iChar < (int)strlen(buffer); iChar++) {
+ code = buffer[iChar];
+
+ switch (code) {
+ case '\n':
+ case 0x8D:
+ if (++row == 200 / 8) return;
+ col = 0;
+ break;
+
+ case '|':
+ // swap attribute nibbles
+ break;
+
+ default:
+ _gfx->putTextCharacter(1, col * 8 , row * 8, static_cast<char>(code), attr & 0x0f, (attr & 0xf0) / 0x10, false, getGameID() == GID_MICKEY ? mickey_fontdata : ibm_fontdata);
+
+ if (++col == 320 / 8) {
+ col = 0;
+ if (++row == 200 / 8) return;
+ }
}
- break;
- case GID_TROLL:
- {
- Troll *troll = new Troll(this);
- troll->init();
- troll->run();
- delete troll;
+ }
+}
+
+void PreAgiEngine::drawStrMiddle(int row, int attr, const char *buffer) {
+ int col = (25 / 2) - (strlen(buffer) / 2); // 25 = 320 / 8 (maximum column)
+ drawStr(row, col, attr, buffer);
+}
+
+void PreAgiEngine::clearTextArea() {
+ int start = IDI_MAX_ROW_PIC;
+
+ if (getGameID() == GID_TROLL)
+ start = 21;
+
+ for (int row = start; row < 200 / 8; row++) {
+ clearRow(row);
+ }
+}
+
+void PreAgiEngine::clearRow(int row) {
+ drawStr(row, 0, IDA_DEFAULT, " "); // 40 spaces
+}
+
+void PreAgiEngine::printStr(const char* szMsg) {
+ clearTextArea();
+ drawStr(21, 0, IDA_DEFAULT, szMsg);
+ _gfx->doUpdate();
+ _system->updateScreen();
+}
+
+void PreAgiEngine::XOR80(char *buffer) {
+ for (size_t i = 0; i < strlen(buffer); i++)
+ if (buffer[i] & 0x80)
+ buffer[i] ^= 0x80;
+}
+
+void PreAgiEngine::printStrXOR(char *szMsg) {
+ XOR80(szMsg);
+ printStr(szMsg);
+}
+
+// Input functions
+
+int PreAgiEngine::getSelection(SelectionTypes type) {
+ Common::Event event;
+ GUI::Debugger *console = getDebugger();
+
+ while (!shouldQuit()) {
+ while (_eventMan->pollEvent(event)) {
+ switch (event.type) {
+ case Common::EVENT_RTL:
+ case Common::EVENT_QUIT:
+ return 0;
+ case Common::EVENT_RBUTTONUP:
+ return 0;
+ case Common::EVENT_LBUTTONUP:
+ if (type == kSelYesNo || type == kSelAnyKey)
+ return 1;
+ case Common::EVENT_KEYDOWN:
+ if (event.kbd.keycode == Common::KEYCODE_d && (event.kbd.flags & Common::KBD_CTRL) && console) {
+ console->attach();
+ console->onFrame();
+ //FIXME: If not cleared, clicking again will start the console
+ event.kbd.keycode = Common::KEYCODE_INVALID;
+ event.kbd.flags = 0;
+ continue;
+ }
+ switch (event.kbd.keycode) {
+ case Common::KEYCODE_y:
+ if (type == kSelYesNo)
+ return 1;
+ case Common::KEYCODE_n:
+ if (type == kSelYesNo)
+ return 0;
+ case Common::KEYCODE_ESCAPE:
+ if (type == kSelNumber || type == kSelAnyKey)
+ return 0;
+ case Common::KEYCODE_1:
+ case Common::KEYCODE_2:
+ case Common::KEYCODE_3:
+ case Common::KEYCODE_4:
+ case Common::KEYCODE_5:
+ case Common::KEYCODE_6:
+ case Common::KEYCODE_7:
+ case Common::KEYCODE_8:
+ case Common::KEYCODE_9:
+ if (type == kSelNumber)
+ return event.kbd.keycode - Common::KEYCODE_1 + 1;
+ case Common::KEYCODE_SPACE:
+ if (type == kSelSpace)
+ return 1;
+ case Common::KEYCODE_BACKSPACE:
+ if (type == kSelBackspace)
+ return 0;
+ default:
+ if (event.kbd.flags & Common::KBD_CTRL)
+ break;
+ if (type == kSelYesNo) {
+ return 2;
+ } else if (type == kSelNumber) {
+ return 10;
+ } else if (type == kSelAnyKey || type == kSelBackspace) {
+ return 1;
+ }
+ }
+ break;
+ default:
+ break;
+ }
}
- break;
- default:
- error("Unknown preagi engine");
- break;
+ _system->updateScreen();
+ _system->delayMillis(10);
}
- return Common::kNoError;
+ return 0;
}
-int PreAgiEngine::rnd(int hi) {
- return (_rnd->getRandomNumber(hi - 1) + 1);
+void PreAgiEngine::playNote(int16 frequency, int32 length) {
+ _speakerStream->play(Audio::PCSpeaker::kWaveFormSquare, frequency, length);
+ waitForTimer(length);
+}
+
+void PreAgiEngine::waitForTimer(int msec_delay) {
+ uint32 start_time = _system->getMillis();
+
+ while (_system->getMillis() < start_time + msec_delay) {
+ _gfx->doUpdate();
+ _system->updateScreen();
+ _system->delayMillis(10);
+ }
}
} // End of namespace Agi
diff --git a/engines/agi/preagi.h b/engines/agi/preagi.h
index 1a178497ad..14ff483d9f 100644
--- a/engines/agi/preagi.h
+++ b/engines/agi/preagi.h
@@ -24,20 +24,36 @@
#define AGI_PREAGI_H
#include "agi/agi.h"
-#include "agi/preagi_common.h"
#include "audio/softsynth/pcspk.h"
namespace Agi {
+// default attributes
+#define IDA_DEFAULT 0x0F
+#define IDA_DEFAULT_REV 0xF0
+
+#define IDI_SND_OSCILLATOR_FREQUENCY 1193180
+#define IDI_SND_TIMER_RESOLUTION 0.0182
+
+#define kColorDefault 0x1337
+
+#define IDI_MAX_ROW_PIC 20
+
+enum SelectionTypes {
+ kSelYesNo,
+ kSelNumber,
+ kSelSpace,
+ kSelAnyKey,
+ kSelBackspace
+};
+
class PreAgiEngine : public AgiBase {
int _gameId;
protected:
- Common::Error go();
void initialize();
-public:
void pollTimer() {}
int getKeypress() { return 0; }
bool isKeypress() { return false; }
@@ -49,10 +65,7 @@ public:
return _gameId;
}
- //SoundMgr *_sound;
PictureMgr *_picture;
- PreAGI_Console *_console;
- GUI::Debugger *getDebugger() { return _console; }
void clearImageStack() {}
void recordImageStackCall(uint8 type, int16 p1, int16 p2, int16 p3,
diff --git a/engines/agi/preagi_common.cpp b/engines/agi/preagi_common.cpp
deleted file mode 100644
index d437dc08f2..0000000000
--- a/engines/agi/preagi_common.cpp
+++ /dev/null
@@ -1,205 +0,0 @@
-/* ScummVM - Graphic Adventure Engine
- *
- * ScummVM is the legal property of its developers, whose names
- * are too numerous to list here. Please refer to the COPYRIGHT
- * file distributed with this source distribution.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
-
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
-
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- */
-
-#include "agi/preagi.h"
-#include "agi/graphics.h"
-#include "agi/keyboard.h"
-
-#include "agi/preagi_common.h"
-
-#include "common/events.h"
-
-namespace Agi {
-
-// Screen functions
-void PreAgiEngine::clearScreen(int attr, bool overrideDefault) {
- if (overrideDefault)
- _defaultColor = attr;
-
- _gfx->clearScreen((attr & 0xF0) / 0x10);
-}
-
-void PreAgiEngine::clearGfxScreen(int attr) {
- _gfx->drawRectangle(0, 0, GFX_WIDTH - 1, IDI_MAX_ROW_PIC * 8 -1, (attr & 0xF0) / 0x10);
-}
-
-// String functions
-
-void PreAgiEngine::drawStr(int row, int col, int attr, const char *buffer) {
- int code;
-
- if (attr == kColorDefault)
- attr = _defaultColor;
-
- for (int iChar = 0; iChar < (int)strlen(buffer); iChar++) {
- code = buffer[iChar];
-
- switch (code) {
- case '\n':
- case 0x8D:
- if (++row == 200 / 8) return;
- col = 0;
- break;
-
- case '|':
- // swap attribute nibbles
- break;
-
- default:
- _gfx->putTextCharacter(1, col * 8 , row * 8, static_cast<char>(code), attr & 0x0f, (attr & 0xf0) / 0x10, false, getGameID() == GID_MICKEY ? mickey_fontdata : ibm_fontdata);
-
- if (++col == 320 / 8) {
- col = 0;
- if (++row == 200 / 8) return;
- }
- }
- }
-}
-
-void PreAgiEngine::drawStrMiddle(int row, int attr, const char *buffer) {
- int col = (25 / 2) - (strlen(buffer) / 2); // 25 = 320 / 8 (maximum column)
- drawStr(row, col, attr, buffer);
-}
-
-void PreAgiEngine::clearTextArea() {
- int start = IDI_MAX_ROW_PIC;
-
- if (getGameID() == GID_TROLL)
- start = 21;
-
- for (int row = start; row < 200 / 8; row++) {
- clearRow(row);
- }
-}
-
-void PreAgiEngine::clearRow(int row) {
- drawStr(row, 0, IDA_DEFAULT, " "); // 40 spaces
-}
-
-void PreAgiEngine::printStr(const char* szMsg) {
- clearTextArea();
- drawStr(21, 0, IDA_DEFAULT, szMsg);
- _gfx->doUpdate();
- _system->updateScreen();
-}
-
-void PreAgiEngine::XOR80(char *buffer) {
- for (size_t i = 0; i < strlen(buffer); i++)
- if (buffer[i] & 0x80)
- buffer[i] ^= 0x80;
-}
-
-void PreAgiEngine::printStrXOR(char *szMsg) {
- XOR80(szMsg);
- printStr(szMsg);
-}
-
-// Input functions
-
-int PreAgiEngine::getSelection(SelectionTypes type) {
- Common::Event event;
-
- while (!shouldQuit()) {
- while (_eventMan->pollEvent(event)) {
- switch (event.type) {
- case Common::EVENT_RTL:
- case Common::EVENT_QUIT:
- return 0;
- case Common::EVENT_RBUTTONUP:
- return 0;
- case Common::EVENT_LBUTTONUP:
- if (type == kSelYesNo || type == kSelAnyKey)
- return 1;
- case Common::EVENT_KEYDOWN:
- if (event.kbd.keycode == Common::KEYCODE_d && (event.kbd.flags & Common::KBD_CTRL) && _console) {
- _console->attach();
- _console->onFrame();
- //FIXME: If not cleared, clicking again will start the console
- event.kbd.keycode = Common::KEYCODE_INVALID;
- event.kbd.flags = 0;
- continue;
- }
- switch (event.kbd.keycode) {
- case Common::KEYCODE_y:
- if (type == kSelYesNo)
- return 1;
- case Common::KEYCODE_n:
- if (type == kSelYesNo)
- return 0;
- case Common::KEYCODE_ESCAPE:
- if (type == kSelNumber || type == kSelAnyKey)
- return 0;
- case Common::KEYCODE_1:
- case Common::KEYCODE_2:
- case Common::KEYCODE_3:
- case Common::KEYCODE_4:
- case Common::KEYCODE_5:
- case Common::KEYCODE_6:
- case Common::KEYCODE_7:
- case Common::KEYCODE_8:
- case Common::KEYCODE_9:
- if (type == kSelNumber)
- return event.kbd.keycode - Common::KEYCODE_1 + 1;
- case Common::KEYCODE_SPACE:
- if (type == kSelSpace)
- return 1;
- case Common::KEYCODE_BACKSPACE:
- if (type == kSelBackspace)
- return 0;
- default:
- if (event.kbd.flags & Common::KBD_CTRL)
- break;
- if (type == kSelYesNo) {
- return 2;
- } else if (type == kSelNumber) {
- return 10;
- } else if (type == kSelAnyKey || type == kSelBackspace) {
- return 1;
- }
- }
- break;
- default:
- break;
- }
- }
- _system->updateScreen();
- _system->delayMillis(10);
- }
- return 0;
-}
-
-void PreAgiEngine::playNote(int16 frequency, int32 length) {
- _speakerStream->play(Audio::PCSpeaker::kWaveFormSquare, frequency, length);
- waitForTimer(length);
-}
-
-void PreAgiEngine::waitForTimer(int msec_delay) {
- uint32 start_time = _system->getMillis();
-
- while (_system->getMillis() < start_time + msec_delay) {
- _gfx->doUpdate();
- _system->updateScreen();
- _system->delayMillis(10);
- }
-}
-
-}
diff --git a/engines/agi/preagi_common.h b/engines/agi/preagi_common.h
deleted file mode 100644
index a557f69977..0000000000
--- a/engines/agi/preagi_common.h
+++ /dev/null
@@ -1,51 +0,0 @@
-/* ScummVM - Graphic Adventure Engine
- *
- * ScummVM is the legal property of its developers, whose names
- * are too numerous to list here. Please refer to the COPYRIGHT
- * file distributed with this source distribution.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
-
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
-
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- */
-
-
-
-#ifndef AGI_PREAGI_COMMON_H
-#define AGI_PREAGI_COMMON_H
-
-namespace Agi {
-
-// default attributes
-#define IDA_DEFAULT 0x0F
-#define IDA_DEFAULT_REV 0xF0
-
-#define IDI_SND_OSCILLATOR_FREQUENCY 1193180
-#define IDI_SND_TIMER_RESOLUTION 0.0182
-
-#define kColorDefault 0x1337
-
-#define IDI_MAX_ROW_PIC 20
-
-enum SelectionTypes {
- kSelYesNo,
- kSelNumber,
- kSelSpace,
- kSelAnyKey,
- kSelBackspace
-};
-
-} // End of namespace Agi
-
-#endif
diff --git a/engines/agi/preagi_mickey.cpp b/engines/agi/preagi_mickey.cpp
index 21eb780916..6d1eb445a2 100644
--- a/engines/agi/preagi_mickey.cpp
+++ b/engines/agi/preagi_mickey.cpp
@@ -32,7 +32,7 @@
namespace Agi {
-int Mickey::getDat(int iRoom) {
+int MickeyEngine::getDat(int iRoom) {
if (((iRoom > 0) && (iRoom < 24)) || iRoom == 154 || iRoom == 155) return IDI_MSA_PLANET_EARTH;
if ((iRoom >= 30) && (iRoom <= 39)) return IDI_MSA_PLANET_VENUS;
if ((iRoom >= 40) && (iRoom <= 69)) return IDI_MSA_PLANET_NEPTUNE;
@@ -45,7 +45,7 @@ int Mickey::getDat(int iRoom) {
return IDI_MSA_PLANET_SPACESHIP;
}
-void Mickey::readExe(int ofs, uint8 *buffer, long buflen) {
+void MickeyEngine::readExe(int ofs, uint8 *buffer, long buflen) {
Common::File infile;
if (!infile.open("mickey.exe"))
return;
@@ -54,11 +54,11 @@ void Mickey::readExe(int ofs, uint8 *buffer, long buflen) {
infile.close();
}
-void Mickey::getDatFileName(int iRoom, char *szFile) {
+void MickeyEngine::getDatFileName(int iRoom, char *szFile) {
sprintf(szFile, IDS_MSA_PATH_DAT, IDS_MSA_NAME_DAT[getDat(iRoom)]);
}
-void Mickey::readDatHdr(char *szFile, MSA_DAT_HEADER *hdr) {
+void MickeyEngine::readDatHdr(char *szFile, MSA_DAT_HEADER *hdr) {
Common::File infile;
if (!infile.open(szFile))
@@ -83,7 +83,7 @@ void Mickey::readDatHdr(char *szFile, MSA_DAT_HEADER *hdr) {
infile.close();
}
-void Mickey::readOfsData(int offset, int iItem, uint8 *buffer, long buflen) {
+void MickeyEngine::readOfsData(int offset, int iItem, uint8 *buffer, long buflen) {
uint16 ofs[256];
readExe(offset, buffer, buflen);
@@ -97,11 +97,11 @@ void Mickey::readOfsData(int offset, int iItem, uint8 *buffer, long buflen) {
// User Interface
-bool Mickey::chooseY_N(int ofsPrompt, bool fErrorMsg) {
+bool MickeyEngine::chooseY_N(int ofsPrompt, bool fErrorMsg) {
printExeStr(ofsPrompt);
- while (!_vm->shouldQuit()) {
- switch (_vm->getSelection(kSelYesNo)) {
+ while (!shouldQuit()) {
+ switch (getSelection(kSelYesNo)) {
case 0: return false;
case 1: return true;
default:
@@ -117,15 +117,15 @@ bool Mickey::chooseY_N(int ofsPrompt, bool fErrorMsg) {
return false;
}
-int Mickey::choose1to9(int ofsPrompt) {
+int MickeyEngine::choose1to9(int ofsPrompt) {
int answer = 0;
printExeStr(ofsPrompt);
- while (!_vm->shouldQuit()) {
- answer = _vm->getSelection(kSelNumber);
+ while (!shouldQuit()) {
+ answer = getSelection(kSelNumber);
if (answer == 10) {
printExeStr(IDO_MSA_PRESS_1_TO_9);
- if (_vm->getSelection(kSelAnyKey) == 0)
+ if (getSelection(kSelAnyKey) == 0)
return 0;
printExeStr(ofsPrompt);
} else return answer;
@@ -134,38 +134,38 @@ int Mickey::choose1to9(int ofsPrompt) {
return 0;
}
-void Mickey::printStr(char *buffer) {
+void MickeyEngine::printStr(char *buffer) {
int pc = 1;
int nRows, iCol, iRow;
nRows = *buffer + IDI_MSA_ROW_MENU_0;
- _vm->clearTextArea();
+ clearTextArea();
for (iRow = IDI_MSA_ROW_MENU_0; iRow < nRows; iRow++) {
iCol = *(buffer + pc++);
- _vm->drawStr(iRow, iCol, IDA_DEFAULT, buffer + pc);
+ drawStr(iRow, iCol, IDA_DEFAULT, buffer + pc);
pc += strlen(buffer + pc) + 1;
}
// Show the string on screen
- _vm->_gfx->doUpdate();
- _vm->_system->updateScreen();
+ _gfx->doUpdate();
+ _system->updateScreen();
}
-void Mickey::printLine(const char *buffer) {
- _vm->clearTextArea();
+void MickeyEngine::printLine(const char *buffer) {
+ clearTextArea();
- _vm->drawStr(22, 18 - strlen(buffer) / 2, IDA_DEFAULT, buffer);
+ drawStr(22, 18 - strlen(buffer) / 2, IDA_DEFAULT, buffer);
// Show the string on screen
- _vm->_gfx->doUpdate();
- _vm->_system->updateScreen();
+ _gfx->doUpdate();
+ _system->updateScreen();
waitAnyKey(true);
}
-void Mickey::printExeStr(int ofs) {
+void MickeyEngine::printExeStr(int ofs) {
uint8 buffer[256] = {0};
if (!ofs)
@@ -175,7 +175,7 @@ void Mickey::printExeStr(int ofs) {
printStr((char *)buffer);
}
-void Mickey::printExeMsg(int ofs) {
+void MickeyEngine::printExeMsg(int ofs) {
if (!ofs)
return;
@@ -183,9 +183,9 @@ void Mickey::printExeMsg(int ofs) {
waitAnyKey(true);
}
-void Mickey::printDatString(int iStr) {
+void MickeyEngine::printDatString(int iStr) {
char buffer[256];
- int iDat = getDat(_game.iRoom);
+ int iDat = getDat(_gameStateMickey.iRoom);
MSA_DAT_HEADER hdr;
char szFile[256] = {0};
@@ -205,7 +205,7 @@ void Mickey::printDatString(int iStr) {
printStr(buffer);
}
-void Mickey::printDesc(int iRoom) {
+void MickeyEngine::printDesc(int iRoom) {
MSA_DAT_HEADER hdr;
char szFile[256] = {0};
@@ -228,20 +228,20 @@ void Mickey::printDesc(int iRoom) {
free(buffer);
}
-bool Mickey::checkMenu() {
+bool MickeyEngine::checkMenu() {
MSA_MENU menu;
int iSel0, iSel1;
MSA_DAT_HEADER hdr;
char szFile[256] = {0};
Common::File infile;
- getDatFileName(_game.iRoom, szFile);
+ getDatFileName(_gameStateMickey.iRoom, szFile);
readDatHdr(szFile, &hdr);
if (!infile.open(szFile))
return false;
char *buffer = new char[sizeof(MSA_MENU)];
- infile.seek(hdr.ofsRoom[_game.iRoom - 1] + IDI_MSA_OFS_DAT, SEEK_SET);
+ infile.seek(hdr.ofsRoom[_gameStateMickey.iRoom - 1] + IDI_MSA_OFS_DAT, SEEK_SET);
infile.read((uint8 *)buffer, sizeof(MSA_MENU));
infile.close();
@@ -255,7 +255,7 @@ bool Mickey::checkMenu() {
return parse(menu.cmd[iSel0].data[iSel1], menu.arg[iSel0].data[iSel1]);
}
-void Mickey::drawMenu(MSA_MENU menu, int sel0, int sel1) {
+void MickeyEngine::drawMenu(MSA_MENU menu, int sel0, int sel1) {
int iWord;
int iRow;
int sel;
@@ -263,7 +263,7 @@ void Mickey::drawMenu(MSA_MENU menu, int sel0, int sel1) {
// draw menu
- _vm->clearTextArea();
+ clearTextArea();
for (iRow = 0; iRow < 2; iRow++) {
for (iWord = 0; iWord < menu.row[iRow].count; iWord++) {
@@ -277,17 +277,17 @@ void Mickey::drawMenu(MSA_MENU menu, int sel0, int sel1) {
else
attr = IDA_DEFAULT;
- _vm->drawStr(IDI_MSA_ROW_MENU_0 + iRow, menu.row[iRow].entry[iWord].x0,
+ drawStr(IDI_MSA_ROW_MENU_0 + iRow, menu.row[iRow].entry[iWord].x0,
attr, (char *)menu.row[iRow].entry[iWord].szText);
}
}
// Menu created, show it on screen
- _vm->_gfx->doUpdate();
- _vm->_system->updateScreen();
+ _gfx->doUpdate();
+ _system->updateScreen();
}
-void Mickey::getMouseMenuSelRow(MSA_MENU menu, int *sel0, int *sel1, int iRow, int x, int y) {
+void MickeyEngine::getMouseMenuSelRow(MSA_MENU menu, int *sel0, int *sel1, int iRow, int x, int y) {
int iWord;
int *sel = 0;
@@ -314,7 +314,7 @@ void Mickey::getMouseMenuSelRow(MSA_MENU menu, int *sel0, int *sel1, int iRow, i
}
}
-bool Mickey::getMenuSelRow(MSA_MENU menu, int *sel0, int *sel1, int iRow) {
+bool MickeyEngine::getMenuSelRow(MSA_MENU menu, int *sel0, int *sel1, int iRow) {
Common::Event event;
int *sel = 0;
int nWords;
@@ -357,8 +357,8 @@ bool Mickey::getMenuSelRow(MSA_MENU menu, int *sel0, int *sel1, int iRow) {
drawMenu(menu, *sel0, *sel1);
- while (!_vm->shouldQuit()) {
- while (_vm->_system->getEventManager()->pollEvent(event)) {
+ while (!shouldQuit()) {
+ while (_system->getEventManager()->pollEvent(event)) {
switch (event.type) {
case Common::EVENT_RTL:
case Common::EVENT_QUIT:
@@ -376,18 +376,18 @@ bool Mickey::getMenuSelRow(MSA_MENU menu, int *sel0, int *sel1, int iRow) {
// Change cursor
if (northIndex >= 0 && (event.mouse.x >= 20 && event.mouse.x <= (IDI_MSA_PIC_WIDTH + 10) * 2) &&
(event.mouse.y >= 0 && event.mouse.y <= 10)) {
- _vm->_gfx->setCursorPalette(true);
+ _gfx->setCursorPalette(true);
} else if (southIndex >= 0 && (event.mouse.x >= 20 && event.mouse.x <= (IDI_MSA_PIC_WIDTH + 10) * 2) &&
(event.mouse.y >= IDI_MSA_PIC_HEIGHT - 10 && event.mouse.y <= IDI_MSA_PIC_HEIGHT)) {
- _vm->_gfx->setCursorPalette(true);
+ _gfx->setCursorPalette(true);
} else if (westIndex >= 0 && (event.mouse.y >= 0 && event.mouse.y <= IDI_MSA_PIC_HEIGHT) &&
(event.mouse.x >= 20 && event.mouse.x <= 30)) {
- _vm->_gfx->setCursorPalette(true);
+ _gfx->setCursorPalette(true);
} else if (eastIndex >= 0 && (event.mouse.y >= 0 && event.mouse.y <= IDI_MSA_PIC_HEIGHT) &&
(event.mouse.x >= IDI_MSA_PIC_WIDTH * 2 && event.mouse.x <= (IDI_MSA_PIC_WIDTH + 10) * 2)) {
- _vm->_gfx->setCursorPalette(true);
+ _gfx->setCursorPalette(true);
} else {
- _vm->_gfx->setCursorPalette(false);
+ _gfx->setCursorPalette(false);
}
}
break;
@@ -400,7 +400,7 @@ bool Mickey::getMenuSelRow(MSA_MENU menu, int *sel0, int *sel1, int iRow) {
drawMenu(menu, *sel0, *sel1);
- _vm->_gfx->setCursorPalette(false);
+ _gfx->setCursorPalette(false);
_clickToMove = true;
} else if (southIndex >= 0 && (event.mouse.x >= 20 && event.mouse.x <= (IDI_MSA_PIC_WIDTH + 10) * 2) &&
(event.mouse.y >= IDI_MSA_PIC_HEIGHT - 10 && event.mouse.y <= IDI_MSA_PIC_HEIGHT)) {
@@ -409,7 +409,7 @@ bool Mickey::getMenuSelRow(MSA_MENU menu, int *sel0, int *sel1, int iRow) {
drawMenu(menu, *sel0, *sel1);
- _vm->_gfx->setCursorPalette(false);
+ _gfx->setCursorPalette(false);
_clickToMove = true;
} else if (westIndex >= 0 && (event.mouse.y >= 0 && event.mouse.y <= IDI_MSA_PIC_HEIGHT) &&
(event.mouse.x >= 20 && event.mouse.x <= 30)) {
@@ -418,7 +418,7 @@ bool Mickey::getMenuSelRow(MSA_MENU menu, int *sel0, int *sel1, int iRow) {
drawMenu(menu, *sel0, *sel1);
- _vm->_gfx->setCursorPalette(false);
+ _gfx->setCursorPalette(false);
_clickToMove = true;
} else if (eastIndex >= 0 && (event.mouse.y >= 0 && event.mouse.y <= IDI_MSA_PIC_HEIGHT) &&
(event.mouse.x >= IDI_MSA_PIC_WIDTH * 2 && event.mouse.x <= (IDI_MSA_PIC_WIDTH + 10) * 2)) {
@@ -427,10 +427,10 @@ bool Mickey::getMenuSelRow(MSA_MENU menu, int *sel0, int *sel1, int iRow) {
drawMenu(menu, *sel0, *sel1);
- _vm->_gfx->setCursorPalette(false);
+ _gfx->setCursorPalette(false);
_clickToMove = true;
} else {
- _vm->_gfx->setCursorPalette(false);
+ _gfx->setCursorPalette(false);
}
return true;
case Common::EVENT_RBUTTONUP:
@@ -458,20 +458,20 @@ bool Mickey::getMenuSelRow(MSA_MENU menu, int *sel0, int *sel1, int iRow) {
}
break;
case Common::EVENT_KEYDOWN:
- if (event.kbd.keycode == Common::KEYCODE_d && (event.kbd.flags & Common::KBD_CTRL) && _vm->_console) {
- _vm->_console->attach();
- _vm->_console->onFrame();
+ if (event.kbd.keycode == Common::KEYCODE_d && (event.kbd.flags & Common::KBD_CTRL) && _console) {
+ _console->attach();
+ _console->onFrame();
continue;
}
switch (event.kbd.keycode) {
case Common::KEYCODE_2:
// Hidden message
- if (_game.iRoom == IDI_MSA_PIC_MERCURY_CAVE_0) {
+ if (_gameStateMickey.iRoom == IDI_MSA_PIC_MERCURY_CAVE_0) {
for (int i = 0; i < 5; i++) {
printExeMsg(IDO_MSA_HIDDEN_MSG[i]);
}
- _vm->clearTextArea();
+ clearTextArea();
waitAnyKey();
}
break;
@@ -489,7 +489,7 @@ bool Mickey::getMenuSelRow(MSA_MENU menu, int *sel0, int *sel1, int iRow) {
return false;
case Common::KEYCODE_s:
- _vm->flipflag(fSoundOn);
+ flipflag(fSoundOn);
break;
case Common::KEYCODE_c:
inventory();
@@ -552,7 +552,7 @@ bool Mickey::getMenuSelRow(MSA_MENU menu, int *sel0, int *sel1, int iRow) {
return false;
}
-void Mickey::getMenuSel(char *buffer, int *sel0, int *sel1) {
+void MickeyEngine::getMenuSel(char *buffer, int *sel0, int *sel1) {
MSA_MENU menu;
memcpy(&menu, buffer, sizeof(MSA_MENU));
@@ -563,8 +563,8 @@ void Mickey::getMenuSel(char *buffer, int *sel0, int *sel1) {
// Show the mouse cursor for the menu
CursorMan.showMouse(true);
- while (!_vm->shouldQuit()) {
- while (!_vm->shouldQuit()) {
+ while (!shouldQuit()) {
+ while (!shouldQuit()) {
if (getMenuSelRow(menu, sel0, sel1, 0)) {
if (_clickToMove)
break;
@@ -586,7 +586,7 @@ void Mickey::getMenuSel(char *buffer, int *sel0, int *sel1) {
CursorMan.showMouse(false);
}
-void Mickey::centerMenu(MSA_MENU *menu) {
+void MickeyEngine::centerMenu(MSA_MENU *menu) {
int iWord;
int iRow;
int w, x;
@@ -606,19 +606,19 @@ void Mickey::centerMenu(MSA_MENU *menu) {
}
}
-void Mickey::patchMenu(MSA_MENU *menu) {
+void MickeyEngine::patchMenu(MSA_MENU *menu) {
uint8 buffer[512];
uint8 menubuf[sizeof(MSA_MENU)];
int nPatches;
int pBuf = 0;
// change planet name in ship airlock menu
- if (_game.iRoom == IDI_MSA_PIC_SHIP_AIRLOCK) {
- strcpy((char *)menu->row[1].entry[2].szText, IDS_MSA_NAME_PLANET[_game.iPlanet]);
+ if (_gameStateMickey.iRoom == IDI_MSA_PIC_SHIP_AIRLOCK) {
+ strcpy((char *)menu->row[1].entry[2].szText, IDS_MSA_NAME_PLANET[_gameStateMickey.iPlanet]);
}
// exit if fix unnecessary
- if (!_game.iRmMenu[_game.iRoom]) {
+ if (!_gameStateMickey.iRmMenu[_gameStateMickey.iRoom]) {
centerMenu(menu);
return;
}
@@ -629,7 +629,7 @@ void Mickey::patchMenu(MSA_MENU *menu) {
// read patches
readOfsData(
IDOFS_MSA_MENU_PATCHES,
- _game.nRmMenu[_game.iRoom] + _game.iRmMenu[_game.iRoom] - 1,
+ _gameStateMickey.nRmMenu[_gameStateMickey.iRoom] + _gameStateMickey.iRmMenu[_gameStateMickey.iRoom] - 1,
buffer, sizeof(buffer)
);
@@ -652,24 +652,24 @@ void Mickey::patchMenu(MSA_MENU *menu) {
centerMenu(menu);
}
-void Mickey::printDatMessage(int iStr) {
+void MickeyEngine::printDatMessage(int iStr) {
printDatString(iStr);
waitAnyKey(true);
}
// Sound
-void Mickey::playNote(MSA_SND_NOTE note) {
+void MickeyEngine::playNote(MSA_SND_NOTE note) {
if (!note.counter) {
// Pause
- _vm->_system->delayMillis((uint) (note.length / IDI_SND_TIMER_RESOLUTION));
+ _system->delayMillis((uint) (note.length / IDI_SND_TIMER_RESOLUTION));
} else {
- _vm->playNote(IDI_SND_OSCILLATOR_FREQUENCY / note.counter, (int32) (note.length / IDI_SND_TIMER_RESOLUTION));
+ PreAgiEngine::playNote(IDI_SND_OSCILLATOR_FREQUENCY / note.counter, (int32) (note.length / IDI_SND_TIMER_RESOLUTION));
}
}
-void Mickey::playSound(ENUM_MSA_SOUND iSound) {
- if (!_vm->getflag(fSoundOn))
+void MickeyEngine::playSound(ENUM_MSA_SOUND iSound) {
+ if (!getflag(fSoundOn))
return;
Common::Event event;
@@ -680,7 +680,7 @@ void Mickey::playSound(ENUM_MSA_SOUND iSound) {
switch (iSound) {
case IDI_MSA_SND_XL30:
for (int iNote = 0; iNote < 6; iNote++) {
- note.counter = _vm->rnd(59600) + 59;
+ note.counter = rnd(59600) + 59;
note.length = 4;
playNote(note);
}
@@ -698,7 +698,7 @@ void Mickey::playSound(ENUM_MSA_SOUND iSound) {
pBuf += 3;
if (iSound == IDI_MSA_SND_THEME) {
- while (_vm->_system->getEventManager()->pollEvent(event)) {
+ while (_system->getEventManager()->pollEvent(event)) {
switch (event.type) {
case Common::EVENT_RTL:
case Common::EVENT_QUIT:
@@ -722,7 +722,7 @@ void Mickey::playSound(ENUM_MSA_SOUND iSound) {
// Graphics
-void Mickey::drawObj(ENUM_MSA_OBJECT iObj, int x0, int y0) {
+void MickeyEngine::drawObj(ENUM_MSA_OBJECT iObj, int x0, int y0) {
char szFile[255] = {0};
sprintf(szFile, IDS_MSA_PATH_OBJ, IDS_MSA_NAME_OBJ[iObj]);
@@ -736,15 +736,15 @@ void Mickey::drawObj(ENUM_MSA_OBJECT iObj, int x0, int y0) {
file.close();
if (iObj == IDI_MSA_OBJECT_CRYSTAL)
- _vm->_picture->setPictureFlags(kPicFStep);
+ _picture->setPictureFlags(kPicFStep);
- _vm->_picture->setOffset(x0, y0);
- _vm->_picture->decodePicture(buffer, size, false, IDI_MSA_PIC_WIDTH, IDI_MSA_PIC_HEIGHT);
- _vm->_picture->setOffset(0, 0);
- _vm->_picture->showPic(10, 0, IDI_MSA_PIC_WIDTH, IDI_MSA_PIC_HEIGHT);
+ _picture->setOffset(x0, y0);
+ _picture->decodePicture(buffer, size, false, IDI_MSA_PIC_WIDTH, IDI_MSA_PIC_HEIGHT);
+ _picture->setOffset(0, 0);
+ _picture->showPic(10, 0, IDI_MSA_PIC_WIDTH, IDI_MSA_PIC_HEIGHT);
}
-void Mickey::drawPic(int iPic) {
+void MickeyEngine::drawPic(int iPic) {
char szFile[255] = {0};
sprintf(szFile, IDS_MSA_PATH_PIC, iPic);
@@ -758,16 +758,16 @@ void Mickey::drawPic(int iPic) {
file.close();
// Note that decodePicture clears the screen
- _vm->_picture->decodePicture(buffer, size, true, IDI_MSA_PIC_WIDTH, IDI_MSA_PIC_HEIGHT);
- _vm->_picture->showPic(10, 0, IDI_MSA_PIC_WIDTH, IDI_MSA_PIC_HEIGHT);
+ _picture->decodePicture(buffer, size, true, IDI_MSA_PIC_WIDTH, IDI_MSA_PIC_HEIGHT);
+ _picture->showPic(10, 0, IDI_MSA_PIC_WIDTH, IDI_MSA_PIC_HEIGHT);
}
-void Mickey::drawRoomAnimation() {
+void MickeyEngine::drawRoomAnimation() {
uint8 objLight[] = {
0xF0, 1, 0xF9, 2, 43, 45, 0xFF
};
- switch (_game.iRoom) {
+ switch (_gameStateMickey.iRoom) {
case IDI_MSA_PIC_EARTH_SHIP:
case IDI_MSA_PIC_VENUS_SHIP:
case IDI_MSA_PIC_NEPTUNE_SHIP:
@@ -790,26 +790,26 @@ void Mickey::drawRoomAnimation() {
uint8 iColor = 0;
- _vm->_picture->setPattern(2, 0);
+ _picture->setPattern(2, 0);
for (int i = 0; i < 12; i++) {
- iColor = _game.nFrame + i;
+ iColor = _gameStateMickey.nFrame + i;
if (iColor > 15)
iColor -= 15;
objLight[1] = iColor;
objLight[4] += 7;
- _vm->_picture->setPictureData(objLight);
- _vm->_picture->setPictureFlags(kPicFCircle);
- _vm->_picture->drawPicture();
+ _picture->setPictureData(objLight);
+ _picture->setPictureFlags(kPicFCircle);
+ _picture->drawPicture();
}
- _vm->_picture->showPic(10, 0, IDI_MSA_PIC_WIDTH, IDI_MSA_PIC_HEIGHT);
+ _picture->showPic(10, 0, IDI_MSA_PIC_WIDTH, IDI_MSA_PIC_HEIGHT);
- _game.nFrame--;
- if (_game.nFrame < 0)
- _game.nFrame = 15;
+ _gameStateMickey.nFrame--;
+ if (_gameStateMickey.nFrame < 0)
+ _gameStateMickey.nFrame = 15;
playSound(IDI_MSA_SND_PRESS_BLUE);
}
@@ -818,12 +818,12 @@ void Mickey::drawRoomAnimation() {
case IDI_MSA_PIC_SHIP_CONTROLS:
// draw XL30 screen
- if (_game.fAnimXL30) {
- if (_game.nFrame > 5)
- _game.nFrame = 0;
+ if (_gameStateMickey.fAnimXL30) {
+ if (_gameStateMickey.nFrame > 5)
+ _gameStateMickey.nFrame = 0;
- drawObj((ENUM_MSA_OBJECT)(IDI_MSA_OBJECT_XL31 + _game.nFrame), 0, 4);
- _game.nFrame++;
+ drawObj((ENUM_MSA_OBJECT)(IDI_MSA_OBJECT_XL31 + _gameStateMickey.nFrame), 0, 4);
+ _gameStateMickey.nFrame++;
};
break;
@@ -831,17 +831,17 @@ void Mickey::drawRoomAnimation() {
default:
// draw crystal
- if (_game.iRoom == IDI_MSA_XTAL_ROOM_XY[_game.iPlanet][0]) {
- if (!_game.fHasXtal) {
- switch (_game.iPlanet) {
+ if (_gameStateMickey.iRoom == IDI_MSA_XTAL_ROOM_XY[_gameStateMickey.iPlanet][0]) {
+ if (!_gameStateMickey.fHasXtal) {
+ switch (_gameStateMickey.iPlanet) {
case IDI_MSA_PLANET_VENUS:
- if (_game.iRmMenu[_game.iRoom] != 2)
+ if (_gameStateMickey.iRmMenu[_gameStateMickey.iRoom] != 2)
break;
default:
drawObj(
IDI_MSA_OBJECT_CRYSTAL,
- IDI_MSA_XTAL_ROOM_XY[_game.iPlanet][1],
- IDI_MSA_XTAL_ROOM_XY[_game.iPlanet][2]
+ IDI_MSA_XTAL_ROOM_XY[_gameStateMickey.iPlanet][1],
+ IDI_MSA_XTAL_ROOM_XY[_gameStateMickey.iPlanet][2]
);
break;
}
@@ -852,36 +852,36 @@ void Mickey::drawRoomAnimation() {
}
}
-void Mickey::drawRoom() {
+void MickeyEngine::drawRoom() {
uint8 buffer[256];
int pBuf = 0;
int nObjs;
// Draw room picture
- if (_game.iRoom == IDI_MSA_PIC_TITLE) {
+ if (_gameStateMickey.iRoom == IDI_MSA_PIC_TITLE) {
drawPic(IDI_MSA_PIC_TITLE);
} else {
- drawPic(_game.iRmPic[_game.iRoom]);
+ drawPic(_gameStateMickey.iRmPic[_gameStateMickey.iRoom]);
- if (_game.iRoom == IDI_MSA_PIC_SHIP_CONTROLS) {
+ if (_gameStateMickey.iRoom == IDI_MSA_PIC_SHIP_CONTROLS) {
// Draw ship control room window
- if (_game.fFlying) {
+ if (_gameStateMickey.fFlying) {
drawObj(IDI_MSA_OBJECT_W_SPACE, 0, 0);
} else {
- drawObj((ENUM_MSA_OBJECT)(IDI_MSA_OBJECT_W_EARTH + _game.iPlanet), 0, 1);
+ drawObj((ENUM_MSA_OBJECT)(IDI_MSA_OBJECT_W_EARTH + _gameStateMickey.iPlanet), 0, 1);
}
}
}
// Draw room objects
- if (_game.iRoom >= IDI_MSA_MAX_PIC_ROOM) {
+ if (_gameStateMickey.iRoom >= IDI_MSA_MAX_PIC_ROOM) {
drawRoomAnimation();
return;
}
- if (_game.iRmObj[_game.iRoom] != IDI_MSA_OBJECT_NONE) {
+ if (_gameStateMickey.iRmObj[_gameStateMickey.iRoom] != IDI_MSA_OBJECT_NONE) {
readOfsData(IDO_MSA_ROOM_OBJECT_XY_OFFSETS,
- _game.iRmObj[_game.iRoom], buffer, sizeof(buffer));
+ _gameStateMickey.iRmObj[_gameStateMickey.iRoom], buffer, sizeof(buffer));
nObjs = buffer[pBuf++];
@@ -914,7 +914,7 @@ const uint8 colorBCG[16][2] = {
{ 0xFF, 0xFF } // F (white, white)
};
-void Mickey::drawLogo() {
+void MickeyEngine::drawLogo() {
// TODO: clean this up and make it work properly, the logo is drawn way off to the right
#if 0
char szFile[256] = {0};
@@ -937,7 +937,7 @@ void Mickey::drawLogo() {
// draw logo bitmap
memcpy(bitmap, buffer, sizeof(bitmap));
- _vm->_picture->setDimensions(w, h);
+ _picture->setDimensions(w, h);
// Show BCG picture
for (int y = 0; y < h; y++) {
@@ -947,40 +947,40 @@ void Mickey::drawLogo() {
color3 = colorBCG[ bitmap[y][x] & 0x0f][0]; // foreground
color4 = colorBCG[ bitmap[y][x] & 0x0f][1]; // foreground
- _vm->_picture->putPixel(x * 4 - xoffset, y, color);
- _vm->_picture->putPixel(x * 4 + 1 - xoffset, y, color2);
- _vm->_picture->putPixel(x * 4 + 2 - xoffset, y, color3);
- _vm->_picture->putPixel(x * 4 + 3 - xoffset, y, color4);
- _vm->_picture->putPixel(x * 4 - xoffset, y + 1, color);
- _vm->_picture->putPixel(x * 4 + 1 - xoffset, y + 1, color2);
- _vm->_picture->putPixel(x * 4 + 2 - xoffset, y + 1, color3);
- _vm->_picture->putPixel(x * 4 + 3 - xoffset, y + 1, color4);
+ _picture->putPixel(x * 4 - xoffset, y, color);
+ _picture->putPixel(x * 4 + 1 - xoffset, y, color2);
+ _picture->putPixel(x * 4 + 2 - xoffset, y, color3);
+ _picture->putPixel(x * 4 + 3 - xoffset, y, color4);
+ _picture->putPixel(x * 4 - xoffset, y + 1, color);
+ _picture->putPixel(x * 4 + 1 - xoffset, y + 1, color2);
+ _picture->putPixel(x * 4 + 2 - xoffset, y + 1, color3);
+ _picture->putPixel(x * 4 + 3 - xoffset, y + 1, color4);
}
}
- _vm->_picture->showPic(10, 10, w, h);
+ _picture->showPic(10, 10, w, h);
delete[] buffer;
#endif
}
-void Mickey::animate() {
- _vm->_system->delayMillis(IDI_MSA_ANIM_DELAY);
+void MickeyEngine::animate() {
+ _system->delayMillis(IDI_MSA_ANIM_DELAY);
drawRoomAnimation();
}
-void Mickey::printRoomDesc() {
+void MickeyEngine::printRoomDesc() {
// print room description
- printDesc(_game.iRoom);
+ printDesc(_gameStateMickey.iRoom);
waitAnyKey(true);
// print extended room description
- if (_game.oRmTxt[_game.iRoom]) {
- printExeMsg(_game.oRmTxt[_game.iRoom] + IDI_MSA_OFS_EXE);
+ if (_gameStateMickey.oRmTxt[_gameStateMickey.iRoom]) {
+ printExeMsg(_gameStateMickey.oRmTxt[_gameStateMickey.iRoom] + IDI_MSA_OFS_EXE);
}
}
-bool Mickey::loadGame() {
+bool MickeyEngine::loadGame() {
Common::InSaveFile *infile;
char szFile[256] = {0};
bool diskerror = true;
@@ -994,15 +994,15 @@ bool Mickey::loadGame() {
return false;
// load game
- sprintf(szFile, "%s.s%02d", _vm->getTargetName().c_str(), sel);
- if (!(infile = _vm->getSaveFileMan()->openForLoading(szFile))) {
+ sprintf(szFile, "%s.s%02d", getTargetName().c_str(), sel);
+ if (!(infile = getSaveFileMan()->openForLoading(szFile))) {
printLine("PLEASE CHECK THE DISK DRIVE");
- if (_vm->getSelection(kSelAnyKey) == 0)
+ if (getSelection(kSelAnyKey) == 0)
return false;
} else {
if (infile->readUint32BE() != MKTAG('M','I','C','K')) {
- warning("Mickey::loadGame wrong save game format");
+ warning("MickeyEngine::loadGame wrong save game format");
return false;
}
@@ -1015,61 +1015,61 @@ bool Mickey::loadGame() {
if (saveVersion != MSA_SAVEGAME_VERSION)
warning("Old save game version (%d, current version is %d). Will try and read anyway, but don't be surprised if bad things happen", saveVersion, MSA_SAVEGAME_VERSION);
- _game.iRoom = infile->readByte();
- _game.iPlanet = infile->readByte();
- _game.iDisk = infile->readByte();
+ _gameStateMickey.iRoom = infile->readByte();
+ _gameStateMickey.iPlanet = infile->readByte();
+ _gameStateMickey.iDisk = infile->readByte();
- _game.nAir = infile->readByte();
- _game.nButtons = infile->readByte();
- _game.nRocks = infile->readByte();
+ _gameStateMickey.nAir = infile->readByte();
+ _gameStateMickey.nButtons = infile->readByte();
+ _gameStateMickey.nRocks = infile->readByte();
- _game.nXtals = infile->readByte();
+ _gameStateMickey.nXtals = infile->readByte();
for (i = 0; i < IDI_MSA_MAX_DAT; i++)
- _game.iPlanetXtal[i] = infile->readByte();
+ _gameStateMickey.iPlanetXtal[i] = infile->readByte();
for (i = 0; i < IDI_MSA_MAX_PLANET; i++)
- _game.iClue[i] = infile->readUint16LE();
+ _gameStateMickey.iClue[i] = infile->readUint16LE();
- infile->read(_game.szAddr, IDI_MSA_MAX_BUTTON + 1);
+ infile->read(_gameStateMickey.szAddr, IDI_MSA_MAX_BUTTON + 1);
- _game.fHasXtal = infile->readByte() == 1;
- _game.fIntro = infile->readByte() == 1;
- _game.fSuit = infile->readByte() == 1;
- _game.fShipDoorOpen = infile->readByte() == 1;
- _game.fFlying = infile->readByte() == 1;
- _game.fStoryShown = infile->readByte() == 1;
- _game.fPlanetsInitialized = infile->readByte() == 1;
- _game.fTempleDoorOpen = infile->readByte() == 1;
- _game.fAnimXL30 = infile->readByte() == 1;
+ _gameStateMickey.fHasXtal = infile->readByte() == 1;
+ _gameStateMickey.fIntro = infile->readByte() == 1;
+ _gameStateMickey.fSuit = infile->readByte() == 1;
+ _gameStateMickey.fShipDoorOpen = infile->readByte() == 1;
+ _gameStateMickey.fFlying = infile->readByte() == 1;
+ _gameStateMickey.fStoryShown = infile->readByte() == 1;
+ _gameStateMickey.fPlanetsInitialized = infile->readByte() == 1;
+ _gameStateMickey.fTempleDoorOpen = infile->readByte() == 1;
+ _gameStateMickey.fAnimXL30 = infile->readByte() == 1;
for (i = 0; i < IDI_MSA_MAX_ITEM; i++)
- _game.fItem[i] = infile->readByte() == 1;
+ _gameStateMickey.fItem[i] = infile->readByte() == 1;
for (i = 0; i < IDI_MSA_MAX_ITEM; i++)
- _game.fItemUsed[i] = infile->readByte() == 1;
+ _gameStateMickey.fItemUsed[i] = infile->readByte() == 1;
for (i = 0; i < IDI_MSA_MAX_ITEM; i++)
- _game.iItem[i] = infile->readSByte();
+ _gameStateMickey.iItem[i] = infile->readSByte();
- _game.nItems = infile->readByte();
+ _gameStateMickey.nItems = infile->readByte();
for (i = 0; i < IDI_MSA_MAX_ROOM; i++)
- _game.iRmObj[i] = infile->readSByte();
+ _gameStateMickey.iRmObj[i] = infile->readSByte();
for (i = 0; i < IDI_MSA_MAX_ROOM; i++)
- _game.iRmPic[i] = infile->readByte();
+ _gameStateMickey.iRmPic[i] = infile->readByte();
for (i = 0; i < IDI_MSA_MAX_ROOM; i++)
- _game.oRmTxt[i] = infile->readUint16LE();
+ _gameStateMickey.oRmTxt[i] = infile->readUint16LE();
for (i = 0; i < IDI_MSA_MAX_ROOM; i++)
- _game.iRmMenu[i] = infile->readByte();
+ _gameStateMickey.iRmMenu[i] = infile->readByte();
for (i = 0; i < IDI_MSA_MAX_ROOM; i++)
- _game.nRmMenu[i] = infile->readByte();
+ _gameStateMickey.nRmMenu[i] = infile->readByte();
- _game.nFrame = infile->readSByte();
+ _gameStateMickey.nFrame = infile->readSByte();
diskerror = false;
delete infile;
@@ -1080,7 +1080,7 @@ bool Mickey::loadGame() {
return true;
}
-void Mickey::saveGame() {
+void MickeyEngine::saveGame() {
Common::OutSaveFile* outfile;
char szFile[256] = {0};
bool diskerror = true;
@@ -1094,7 +1094,7 @@ void Mickey::saveGame() {
else
printExeStr(IDO_MSA_SAVE_GAME[2]);
- if (_vm->getSelection(kSelAnyKey) == 0)
+ if (getSelection(kSelAnyKey) == 0)
return;
while (diskerror) {
@@ -1107,75 +1107,75 @@ void Mickey::saveGame() {
else
printExeStr(IDO_MSA_SAVE_GAME[4]);
- if (_vm->getSelection(kSelAnyKey) == 0)
+ if (getSelection(kSelAnyKey) == 0)
return;
// save game
- sprintf(szFile, "%s.s%02d", _vm->getTargetName().c_str(), sel);
- if (!(outfile = _vm->getSaveFileMan()->openForSaving(szFile))) {
+ sprintf(szFile, "%s.s%02d", getTargetName().c_str(), sel);
+ if (!(outfile = getSaveFileMan()->openForSaving(szFile))) {
printLine("PLEASE CHECK THE DISK DRIVE");
- if (_vm->getSelection(kSelAnyKey) == 0)
+ if (getSelection(kSelAnyKey) == 0)
return;
} else {
outfile->writeUint32BE(MKTAG('M','I','C','K')); // header
outfile->writeByte(MSA_SAVEGAME_VERSION);
- outfile->writeByte(_game.iRoom);
- outfile->writeByte(_game.iPlanet);
- outfile->writeByte(_game.iDisk);
+ outfile->writeByte(_gameStateMickey.iRoom);
+ outfile->writeByte(_gameStateMickey.iPlanet);
+ outfile->writeByte(_gameStateMickey.iDisk);
- outfile->writeByte(_game.nAir);
- outfile->writeByte(_game.nButtons);
- outfile->writeByte(_game.nRocks);
+ outfile->writeByte(_gameStateMickey.nAir);
+ outfile->writeByte(_gameStateMickey.nButtons);
+ outfile->writeByte(_gameStateMickey.nRocks);
- outfile->writeByte(_game.nXtals);
+ outfile->writeByte(_gameStateMickey.nXtals);
for (i = 0; i < IDI_MSA_MAX_DAT; i++)
- outfile->writeByte(_game.iPlanetXtal[i]);
+ outfile->writeByte(_gameStateMickey.iPlanetXtal[i]);
for (i = 0; i < IDI_MSA_MAX_PLANET; i++)
- outfile->writeUint16LE(_game.iClue[i]);
+ outfile->writeUint16LE(_gameStateMickey.iClue[i]);
- outfile->write(_game.szAddr, IDI_MSA_MAX_BUTTON + 1);
+ outfile->write(_gameStateMickey.szAddr, IDI_MSA_MAX_BUTTON + 1);
- outfile->writeByte(_game.fHasXtal ? 1 : 0);
- outfile->writeByte(_game.fIntro ? 1 : 0);
- outfile->writeByte(_game.fSuit ? 1 : 0);
- outfile->writeByte(_game.fShipDoorOpen ? 1 : 0);
- outfile->writeByte(_game.fFlying ? 1 : 0);
- outfile->writeByte(_game.fStoryShown ? 1 : 0);
- outfile->writeByte(_game.fPlanetsInitialized ? 1 : 0);
- outfile->writeByte(_game.fTempleDoorOpen ? 1 : 0);
- outfile->writeByte(_game.fAnimXL30 ? 1 : 0);
+ outfile->writeByte(_gameStateMickey.fHasXtal ? 1 : 0);
+ outfile->writeByte(_gameStateMickey.fIntro ? 1 : 0);
+ outfile->writeByte(_gameStateMickey.fSuit ? 1 : 0);
+ outfile->writeByte(_gameStateMickey.fShipDoorOpen ? 1 : 0);
+ outfile->writeByte(_gameStateMickey.fFlying ? 1 : 0);
+ outfile->writeByte(_gameStateMickey.fStoryShown ? 1 : 0);
+ outfile->writeByte(_gameStateMickey.fPlanetsInitialized ? 1 : 0);
+ outfile->writeByte(_gameStateMickey.fTempleDoorOpen ? 1 : 0);
+ outfile->writeByte(_gameStateMickey.fAnimXL30 ? 1 : 0);
for (i = 0; i < IDI_MSA_MAX_ITEM; i++)
- outfile->writeByte(_game.fItem[i] ? 1 : 0);
+ outfile->writeByte(_gameStateMickey.fItem[i] ? 1 : 0);
for (i = 0; i < IDI_MSA_MAX_ITEM; i++)
- outfile->writeByte(_game.fItemUsed[i] ? 1 : 0);
+ outfile->writeByte(_gameStateMickey.fItemUsed[i] ? 1 : 0);
for (i = 0; i < IDI_MSA_MAX_ITEM; i++)
- outfile->writeSByte(_game.iItem[i]);
+ outfile->writeSByte(_gameStateMickey.iItem[i]);
- outfile->writeByte(_game.nItems);
+ outfile->writeByte(_gameStateMickey.nItems);
for (i = 0; i < IDI_MSA_MAX_ROOM; i++)
- outfile->writeSByte(_game.iRmObj[i]);
+ outfile->writeSByte(_gameStateMickey.iRmObj[i]);
for (i = 0; i < IDI_MSA_MAX_ROOM; i++)
- outfile->writeByte(_game.iRmPic[i]);
+ outfile->writeByte(_gameStateMickey.iRmPic[i]);
for (i = 0; i < IDI_MSA_MAX_ROOM; i++)
- outfile->writeUint16LE(_game.oRmTxt[i]);
+ outfile->writeUint16LE(_gameStateMickey.oRmTxt[i]);
for (i = 0; i < IDI_MSA_MAX_ROOM; i++)
- outfile->writeByte(_game.iRmMenu[i]);
+ outfile->writeByte(_gameStateMickey.iRmMenu[i]);
for (i = 0; i < IDI_MSA_MAX_ROOM; i++)
- outfile->writeByte(_game.nRmMenu[i]);
+ outfile->writeByte(_gameStateMickey.nRmMenu[i]);
- outfile->writeSByte(_game.nFrame);
+ outfile->writeSByte(_gameStateMickey.nFrame);
outfile->finalize();
@@ -1190,14 +1190,14 @@ void Mickey::saveGame() {
printExeMsg(IDO_MSA_SAVE_GAME[6]);
}
-void Mickey::showPlanetInfo() {
+void MickeyEngine::showPlanetInfo() {
for (int i = 0; i < 4; i++) {
- printExeStr(IDO_MSA_PLANET_INFO[_game.iPlanet][i]);
+ printExeStr(IDO_MSA_PLANET_INFO[_gameStateMickey.iPlanet][i]);
waitAnyKey();
}
}
-void Mickey::printStory() {
+void MickeyEngine::printStory() {
char buffer[IDI_MSA_LEN_STORY] = {0};
char szLine[41] = {0};
int iRow;
@@ -1205,37 +1205,37 @@ void Mickey::printStory() {
readExe(IDO_MSA_GAME_STORY, (uint8 *)buffer, sizeof(buffer));
- _vm->clearScreen(IDA_DEFAULT);
+ clearScreen(IDA_DEFAULT);
for (iRow = 0; iRow < 25; iRow++) {
strcpy(szLine, buffer + pBuf);
- _vm->drawStr(iRow, 0, IDA_DEFAULT, szLine);
+ drawStr(iRow, 0, IDA_DEFAULT, szLine);
pBuf += strlen(szLine) + 1;
}
waitAnyKey();
- _vm->clearScreen(IDA_DEFAULT);
+ clearScreen(IDA_DEFAULT);
for (iRow = 0; iRow < 21; iRow++) {
strcpy(szLine, buffer + pBuf);
- _vm->drawStr(iRow, 0, IDA_DEFAULT, szLine);
+ drawStr(iRow, 0, IDA_DEFAULT, szLine);
pBuf += strlen(szLine) + 1;
}
waitAnyKey();
//Set back to black
- _vm->_gfx->clearScreen(0);
- _vm->_gfx->doUpdate();
+ _gfx->clearScreen(0);
+ _gfx->doUpdate();
drawRoom();
- _game.fStoryShown = true;
+ _gameStateMickey.fStoryShown = true;
}
-int Mickey::getPlanet() {
- if (!_game.nButtons)
+int MickeyEngine::getPlanet() {
+ if (!_gameStateMickey.nButtons)
return -1;
for (int iPlanet = 0; iPlanet < IDI_MSA_MAX_DAT - 1; iPlanet++) {
- if (!strcmp(IDS_MSA_ADDR_PLANET[iPlanet], _game.szAddr)) {
+ if (!strcmp(IDS_MSA_ADDR_PLANET[iPlanet], _gameStateMickey.szAddr)) {
return iPlanet;
}
}
@@ -1243,49 +1243,49 @@ int Mickey::getPlanet() {
return -1;
}
-void Mickey::pressOB(int iButton) {
+void MickeyEngine::pressOB(int iButton) {
char szButtons[12] = {0};
// check if too many buttons pressed
- if (_game.nButtons == IDI_MSA_MAX_BUTTON) {
- _game.nButtons = 0;
- memset(_game.szAddr, 0, sizeof(_game.szAddr));
+ if (_gameStateMickey.nButtons == IDI_MSA_MAX_BUTTON) {
+ _gameStateMickey.nButtons = 0;
+ memset(_gameStateMickey.szAddr, 0, sizeof(_gameStateMickey.szAddr));
printExeMsg(IDO_MSA_TOO_MANY_BUTTONS_PRESSED);
return;
}
// add button press to address
- _game.nButtons++;
- _game.szAddr[_game.nButtons - 1] = (char)iButton;
+ _gameStateMickey.nButtons++;
+ _gameStateMickey.szAddr[_gameStateMickey.nButtons - 1] = (char)iButton;
// format buttons string
for (int i = 0; i < IDI_MSA_MAX_BUTTON; i++) {
- szButtons[i * 2] = _game.szAddr[i];
- if (_game.szAddr[i + 1]) szButtons[(i * 2) + 1] = ',';
+ szButtons[i * 2] = _gameStateMickey.szAddr[i];
+ if (_gameStateMickey.szAddr[i + 1]) szButtons[(i * 2) + 1] = ',';
}
// print pressed buttons
printLine("MICKEY HAS PRESSED: ");
- _vm->drawStr(20, 22, IDA_DEFAULT, szButtons);
+ drawStr(20, 22, IDA_DEFAULT, szButtons);
waitAnyKey();
}
-void Mickey::insertDisk(int iDisk) {
- _vm->clearTextArea();
- _vm->drawStr(IDI_MSA_ROW_INSERT_DISK, IDI_MSA_COL_INSERT_DISK, IDA_DEFAULT, (const char *)IDS_MSA_INSERT_DISK[iDisk]);
+void MickeyEngine::insertDisk(int iDisk) {
+ clearTextArea();
+ drawStr(IDI_MSA_ROW_INSERT_DISK, IDI_MSA_COL_INSERT_DISK, IDA_DEFAULT, (const char *)IDS_MSA_INSERT_DISK[iDisk]);
waitAnyKey();
}
-void Mickey::gameOver() {
+void MickeyEngine::gameOver() {
// We shouldn't run the game over segment if we're quitting.
- if (_vm->shouldQuit())
+ if (shouldQuit())
return;
drawPic(IDI_MSA_PIC_EARTH_SHIP_LEAVING);
printExeMsg(IDO_MSA_GAME_OVER[3]);
playSound(IDI_MSA_SND_GAME_OVER);
- if (_game.fItemUsed[IDI_MSA_ITEM_LETTER]) {
+ if (_gameStateMickey.fItemUsed[IDI_MSA_ITEM_LETTER]) {
drawPic(IDI_MSA_PIC_EARTH_MINNIE);
printExeMsg(IDO_MSA_GAME_OVER[4]);
printExeMsg(IDO_MSA_GAME_OVER[5]);
@@ -1297,74 +1297,74 @@ void Mickey::gameOver() {
waitAnyKey();
}
-void Mickey::flipSwitch() {
- if (_game.fHasXtal || _game.nXtals) {
- if (!_game.fStoryShown)
+void MickeyEngine::flipSwitch() {
+ if (_gameStateMickey.fHasXtal || _gameStateMickey.nXtals) {
+ if (!_gameStateMickey.fStoryShown)
printStory();
// Initialize planet data
- if (!_game.fPlanetsInitialized) {
+ if (!_gameStateMickey.fPlanetsInitialized) {
int iHint = 0;
int iPlanet = 0;
- memset(_game.iPlanetXtal, 0, sizeof(_game.iPlanetXtal));
- memset(_game.iClue, 0, sizeof(_game.iClue));
+ memset(_gameStateMickey.iPlanetXtal, 0, sizeof(_gameStateMickey.iPlanetXtal));
+ memset(_gameStateMickey.iClue, 0, sizeof(_gameStateMickey.iClue));
- _game.iPlanetXtal[0] = IDI_MSA_PLANET_EARTH;
- _game.iPlanetXtal[8] = IDI_MSA_PLANET_URANUS;
+ _gameStateMickey.iPlanetXtal[0] = IDI_MSA_PLANET_EARTH;
+ _gameStateMickey.iPlanetXtal[8] = IDI_MSA_PLANET_URANUS;
for (int i = 1; i < IDI_MSA_MAX_PLANET; i++) {
if (i < 8) {
do {
// Earth (planet 0) and Uranus (planet 8) are excluded
- iPlanet = _vm->rnd(IDI_MSA_MAX_PLANET - 2);
+ iPlanet = rnd(IDI_MSA_MAX_PLANET - 2);
} while (planetIsAlreadyAssigned(iPlanet));
} else {
iPlanet = IDI_MSA_PLANET_URANUS; // Uranus is always last
}
- _game.iPlanetXtal[i] = iPlanet;
- iHint = _vm->rnd(5) - 1; // clues are 0-4
- _game.iClue[i] = IDO_MSA_NEXT_PIECE[iPlanet][iHint];
+ _gameStateMickey.iPlanetXtal[i] = iPlanet;
+ iHint = rnd(5) - 1; // clues are 0-4
+ _gameStateMickey.iClue[i] = IDO_MSA_NEXT_PIECE[iPlanet][iHint];
}
- _game.fPlanetsInitialized = true;
+ _gameStateMickey.fPlanetsInitialized = true;
}
// activate screen animation
- _game.fAnimXL30 = true;
+ _gameStateMickey.fAnimXL30 = true;
- _vm->clearTextArea();
+ clearTextArea();
playSound(IDI_MSA_SND_XL30);
printExeMsg(IDO_MSA_XL30_SPEAKING);
- if (_game.fHasXtal) {
- _game.fHasXtal = false;
+ if (_gameStateMickey.fHasXtal) {
+ _gameStateMickey.fHasXtal = false;
printExeMsg(IDO_MSA_CRYSTAL_PIECE_FOUND);
}
- if (_game.nXtals == IDI_MSA_MAX_PLANET) {
+ if (_gameStateMickey.nXtals == IDI_MSA_MAX_PLANET) {
printExeMsg(IDO_MSA_GAME_OVER[0]);
printExeMsg(IDO_MSA_GAME_OVER[1]);
printExeMsg(IDO_MSA_GAME_OVER[2]);
#if 0
// DEBUG
- strcpy(_game.szAddr, (char *)IDS_MSA_ADDR_PLANET[IDI_MSA_PLANET_EARTH]);
- _game.nButtons = strlen(_game.szAddr);
+ strcpy(_gameStateMickey.szAddr, (char *)IDS_MSA_ADDR_PLANET[IDI_MSA_PLANET_EARTH]);
+ _gameStateMickey.nButtons = strlen(_gameStateMickey.szAddr);
#endif
} else {
- printExeStr(_game.iClue[_game.nXtals]);
+ printExeStr(_gameStateMickey.iClue[_gameStateMickey.nXtals]);
#if 0
// DEBUG
- _vm->drawStr(24, 12, IDA_DEFAULT, (char *)IDS_MSA_NAME_PLANET_2[_game.iPlanetXtal[_game.nXtals]]);
- _vm->drawStr(24, 22, IDA_DEFAULT, (char *)IDS_MSA_ADDR_PLANET[_game.iPlanetXtal[_game.nXtals]]);
- strcpy(_game.szAddr, (char *)IDS_MSA_ADDR_PLANET[_game.iPlanetXtal[_game.nXtals]]);
- _game.nButtons = strlen(_game.szAddr);
- _vm->_gfx->doUpdate();
- _vm->_system->updateScreen(); // TODO: this should go in the game's main loop
+ drawStr(24, 12, IDA_DEFAULT, (char *)IDS_MSA_NAME_PLANET_2[_gameStateMickey.iPlanetXtal[_gameStateMickey.nXtals]]);
+ drawStr(24, 22, IDA_DEFAULT, (char *)IDS_MSA_ADDR_PLANET[_gameStateMickey.iPlanetXtal[_gameStateMickey.nXtals]]);
+ strcpy(_gameStateMickey.szAddr, (char *)IDS_MSA_ADDR_PLANET[_gameStateMickey.iPlanetXtal[_gameStateMickey.nXtals]]);
+ _gameStateMickey.nButtons = strlen(_gameStateMickey.szAddr);
+ _gfx->doUpdate();
+ _system->updateScreen(); // TODO: this should go in the game's main loop
#endif
waitAnyKey(true);
@@ -1374,73 +1374,73 @@ void Mickey::flipSwitch() {
}
}
-void Mickey::inventory() {
+void MickeyEngine::inventory() {
int iRow = IDI_MSA_ROW_INV_ITEMS;
char szCrystals[12] = {0};
- sprintf(szCrystals, IDS_MSA_CRYSTALS, IDS_MSA_CRYSTAL_NO[_game.nXtals]);
+ sprintf(szCrystals, IDS_MSA_CRYSTALS, IDS_MSA_CRYSTAL_NO[_gameStateMickey.nXtals]);
CursorMan.showMouse(false);
- _vm->clearScreen(IDA_DEFAULT);
- _vm->drawStr(IDI_MSA_ROW_INV_TITLE, IDI_MSA_COL_INV_TITLE, IDA_DEFAULT, IDS_MSA_INVENTORY);
- _vm->drawStr(IDI_MSA_ROW_INV_CRYSTALS, IDI_MSA_COL_INV_ITEMS, IDA_DEFAULT, szCrystals);
+ clearScreen(IDA_DEFAULT);
+ drawStr(IDI_MSA_ROW_INV_TITLE, IDI_MSA_COL_INV_TITLE, IDA_DEFAULT, IDS_MSA_INVENTORY);
+ drawStr(IDI_MSA_ROW_INV_CRYSTALS, IDI_MSA_COL_INV_ITEMS, IDA_DEFAULT, szCrystals);
for (int iItem = 0; iItem < IDI_MSA_MAX_ITEM; iItem++) {
- if (_game.fItem[_game.iItem[iItem]] && (_game.iItem[iItem] != IDI_MSA_OBJECT_NONE)) {
- _vm->drawStr(iRow++, IDI_MSA_COL_INV_ITEMS, IDA_DEFAULT, (const char *)IDS_MSA_NAME_ITEM[_game.iItem[iItem]]);
+ if (_gameStateMickey.fItem[_gameStateMickey.iItem[iItem]] && (_gameStateMickey.iItem[iItem] != IDI_MSA_OBJECT_NONE)) {
+ drawStr(iRow++, IDI_MSA_COL_INV_ITEMS, IDA_DEFAULT, (const char *)IDS_MSA_NAME_ITEM[_gameStateMickey.iItem[iItem]]);
}
}
waitAnyKey();
- _vm->clearScreen(IDA_DEFAULT);
+ clearScreen(IDA_DEFAULT);
CursorMan.showMouse(true);
}
-void Mickey::intro() {
+void MickeyEngine::intro() {
// Draw Sierra logo
//drawLogo(); // Original does not even show this, so we skip it too
//waitAnyKey(); // Not in the original, but needed so that the logo is visible
// draw title picture
- _game.iRoom = IDI_MSA_PIC_TITLE;
+ _gameStateMickey.iRoom = IDI_MSA_PIC_TITLE;
drawRoom();
// show copyright and play theme
printExeMsg(IDO_MSA_COPYRIGHT);
// Quit if necessary
- if (_vm->shouldQuit())
+ if (shouldQuit())
return;
playSound(IDI_MSA_SND_THEME);
// load game
- _game.fIntro = true;
+ _gameStateMickey.fIntro = true;
if (chooseY_N(IDO_MSA_LOAD_GAME[0], true)) {
if (loadGame()) {
- _game.iPlanet = IDI_MSA_PLANET_EARTH;
- _game.fIntro = false;
- _game.iRoom = IDI_MSA_PIC_SHIP_CORRIDOR;
+ _gameStateMickey.iPlanet = IDI_MSA_PLANET_EARTH;
+ _gameStateMickey.fIntro = false;
+ _gameStateMickey.iRoom = IDI_MSA_PIC_SHIP_CORRIDOR;
return;
}
}
// Quit if necessary
- if (_vm->shouldQuit())
+ if (shouldQuit())
return;
// play spaceship landing scene
- _game.iPlanet = IDI_MSA_PLANET_EARTH;
- _game.iRoom = IDI_MSA_PIC_EARTH_ROAD_4;
+ _gameStateMickey.iPlanet = IDI_MSA_PLANET_EARTH;
+ _gameStateMickey.iRoom = IDI_MSA_PIC_EARTH_ROAD_4;
drawRoom();
printRoomDesc();
// Quit if necessary
- if (_vm->shouldQuit())
+ if (shouldQuit())
return;
playSound(IDI_MSA_SND_SHIP_LAND);
@@ -1450,48 +1450,48 @@ void Mickey::intro() {
playSound(IDI_MSA_SND_PRESS_BLUE);
//Set screen to white
- _vm->_gfx->clearScreen(15);
- _vm->_gfx->doUpdate();
- _vm->_system->updateScreen();
+ _gfx->clearScreen(15);
+ _gfx->doUpdate();
+ _system->updateScreen();
- _vm->_system->delayMillis(IDI_MSA_ANIM_DELAY);
+ _system->delayMillis(IDI_MSA_ANIM_DELAY);
//Set back to black
- _vm->_gfx->clearScreen(0);
- _vm->_gfx->doUpdate();
- _vm->_system->updateScreen();
+ _gfx->clearScreen(0);
+ _gfx->doUpdate();
+ _system->updateScreen();
drawRoom();
- printDesc(_game.iRoom);
+ printDesc(_gameStateMickey.iRoom);
}
printExeMsg(IDO_MSA_INTRO);
}
-void Mickey::getItem(ENUM_MSA_ITEM iItem) {
- _game.fItem[iItem] = true;
- _game.iItem[_game.nItems++] = iItem;
- _game.oRmTxt[_game.iRoom] = 0;
+void MickeyEngine::getItem(ENUM_MSA_ITEM iItem) {
+ _gameStateMickey.fItem[iItem] = true;
+ _gameStateMickey.iItem[_gameStateMickey.nItems++] = iItem;
+ _gameStateMickey.oRmTxt[_gameStateMickey.iRoom] = 0;
playSound(IDI_MSA_SND_TAKE);
drawRoom();
}
-void Mickey::getXtal(int iStr) {
- _game.oRmTxt[_game.iRoom] = 0;
- _game.fHasXtal = true;
- _game.nXtals++;
+void MickeyEngine::getXtal(int iStr) {
+ _gameStateMickey.oRmTxt[_gameStateMickey.iRoom] = 0;
+ _gameStateMickey.fHasXtal = true;
+ _gameStateMickey.nXtals++;
playSound(IDI_MSA_SND_CRYSTAL);
drawRoom();
printDatMessage(iStr);
}
-bool Mickey::parse(int cmd, int arg) {
+bool MickeyEngine::parse(int cmd, int arg) {
switch (cmd) {
// BASIC
case IDI_MSA_ACTION_GOTO_ROOM:
- _game.iRoom = arg;
+ _gameStateMickey.iRoom = arg;
return true;
case IDI_MSA_ACTION_SHOW_INT_STR:
printLine(IDS_MSA_ERRORS[arg]);
@@ -1515,291 +1515,291 @@ bool Mickey::parse(int cmd, int arg) {
// EARTH
case IDI_MSA_ACTION_GET_ROPE:
- if (_game.iRmMenu[_game.iRoom] == 2) {
- _game.iRmObj[_game.iRoom] = IDI_MSA_OBJECT_NONE;
- _game.iRmMenu[_game.iRoom] = 3;
+ if (_gameStateMickey.iRmMenu[_gameStateMickey.iRoom] == 2) {
+ _gameStateMickey.iRmObj[_gameStateMickey.iRoom] = IDI_MSA_OBJECT_NONE;
+ _gameStateMickey.iRmMenu[_gameStateMickey.iRoom] = 3;
getItem(IDI_MSA_ITEM_ROPE);
printLine("MICKEY TAKES THE ROPE");
} else {
- _game.iRmMenu[_game.iRoom] = 1;
+ _gameStateMickey.iRmMenu[_gameStateMickey.iRoom] = 1;
printDatMessage(11);
}
break;
case IDI_MSA_ACTION_UNTIE_ROPE:
- _game.iRmPic[_game.iRoom] = IDI_MSA_PIC_EARTH_TIRE_SWING_1;
- _game.iRmObj[_game.iRoom] = 0;
- _game.iRmMenu[_game.iRoom] = 2;
+ _gameStateMickey.iRmPic[_gameStateMickey.iRoom] = IDI_MSA_PIC_EARTH_TIRE_SWING_1;
+ _gameStateMickey.iRmObj[_gameStateMickey.iRoom] = 0;
+ _gameStateMickey.iRmMenu[_gameStateMickey.iRoom] = 2;
drawRoom();
printDatMessage(12);
break;
case IDI_MSA_ACTION_GET_BONE:
- _game.iRmObj[_game.iRoom] = IDI_MSA_OBJECT_NONE;
- _game.iRmMenu[_game.iRoom] = 1;
+ _gameStateMickey.iRmObj[_gameStateMickey.iRoom] = IDI_MSA_OBJECT_NONE;
+ _gameStateMickey.iRmMenu[_gameStateMickey.iRoom] = 1;
getItem(IDI_MSA_ITEM_BONE);
printDatMessage(arg);
break;
case IDI_MSA_ACTION_GET_XTAL_EARTH:
- _game.iRmMenu[_game.iRoom] = 1;
+ _gameStateMickey.iRmMenu[_gameStateMickey.iRoom] = 1;
getXtal(arg);
break;
case IDI_MSA_ACTION_LOOK_DESK:
- _game.iRmMenu[_game.iRoom] = 1;
- _game.iRmObj[_game.iRoom] = 2;
+ _gameStateMickey.iRmMenu[_gameStateMickey.iRoom] = 1;
+ _gameStateMickey.iRmObj[_gameStateMickey.iRoom] = 2;
drawRoom();
printDatMessage(arg);
break;
case IDI_MSA_ACTION_WRITE_LETTER:
- _game.iRmMenu[_game.iRoom] = 3;
- _game.iRmMenu[IDI_MSA_PIC_EARTH_MAILBOX] = 1;
- _game.iRmObj[_game.iRoom] = IDI_MSA_OBJECT_NONE;
+ _gameStateMickey.iRmMenu[_gameStateMickey.iRoom] = 3;
+ _gameStateMickey.iRmMenu[IDI_MSA_PIC_EARTH_MAILBOX] = 1;
+ _gameStateMickey.iRmObj[_gameStateMickey.iRoom] = IDI_MSA_OBJECT_NONE;
getItem(IDI_MSA_ITEM_LETTER);
printDatMessage(arg);
break;
case IDI_MSA_ACTION_MAIL_LETTER:
- _game.fItemUsed[IDI_MSA_ITEM_LETTER] = true;
- _game.fItem[IDI_MSA_ITEM_LETTER] = false;
- _game.iRmMenu[_game.iRoom] = 0;
+ _gameStateMickey.fItemUsed[IDI_MSA_ITEM_LETTER] = true;
+ _gameStateMickey.fItem[IDI_MSA_ITEM_LETTER] = false;
+ _gameStateMickey.iRmMenu[_gameStateMickey.iRoom] = 0;
printDatMessage(arg);
break;
case IDI_MSA_ACTION_OPEN_MAILBOX:
- if (_game.fItemUsed[IDI_MSA_ITEM_LETTER]) {
+ if (_gameStateMickey.fItemUsed[IDI_MSA_ITEM_LETTER]) {
printDatMessage(110);
} else {
printDatMessage(arg);
}
break;
case IDI_MSA_ACTION_OPEN_CUPBOARD:
- if (_game.iRmMenu[_game.iRoom]) {
- if (_game.iRmObj[_game.iRoom] == IDI_MSA_OBJECT_NONE) {
+ if (_gameStateMickey.iRmMenu[_gameStateMickey.iRoom]) {
+ if (_gameStateMickey.iRmObj[_gameStateMickey.iRoom] == IDI_MSA_OBJECT_NONE) {
printDatMessage(78);
} else {
printDatMessage(arg);
}
} else {
- _game.iRmMenu[_game.iRoom] = 1;
- _game.iRmPic[_game.iRoom] = IDI_MSA_PIC_EARTH_KITCHEN_1;
- _game.iRmObj[_game.iRoom] = 3;
+ _gameStateMickey.iRmMenu[_gameStateMickey.iRoom] = 1;
+ _gameStateMickey.iRmPic[_gameStateMickey.iRoom] = IDI_MSA_PIC_EARTH_KITCHEN_1;
+ _gameStateMickey.iRmObj[_gameStateMickey.iRoom] = 3;
drawRoom();
printDatMessage(arg);
}
break;
case IDI_MSA_ACTION_GET_FLASHLIGHT:
if (!mickeyHasItem(IDI_MSA_ITEM_FLASHLIGHT)) {
- _game.iRmObj[_game.iRoom] = IDI_MSA_OBJECT_NONE;
+ _gameStateMickey.iRmObj[_gameStateMickey.iRoom] = IDI_MSA_OBJECT_NONE;
getItem(IDI_MSA_ITEM_FLASHLIGHT);
drawRoom();
printDatMessage(arg);
}
break;
case IDI_MSA_ACTION_OPEN_CABINET:
- if (_game.iRmMenu[_game.iRoom]) {
+ if (_gameStateMickey.iRmMenu[_gameStateMickey.iRoom]) {
printDatMessage(109);
} else {
- _game.iRmMenu[_game.iRoom] = 1;
- _game.iRmPic[_game.iRoom] = IDI_MSA_PIC_EARTH_GARAGE_1;
- _game.iRmObj[_game.iRoom] = 15;
+ _gameStateMickey.iRmMenu[_gameStateMickey.iRoom] = 1;
+ _gameStateMickey.iRmPic[_gameStateMickey.iRoom] = IDI_MSA_PIC_EARTH_GARAGE_1;
+ _gameStateMickey.iRmObj[_gameStateMickey.iRoom] = 15;
drawRoom();
printDatMessage(arg);
}
break;
case IDI_MSA_ACTION_GET_CROWBAR:
if (!mickeyHasItem(IDI_MSA_ITEM_CROWBAR)) {
- _game.iRmObj[_game.iRoom]--;
+ _gameStateMickey.iRmObj[_gameStateMickey.iRoom]--;
getItem(IDI_MSA_ITEM_CROWBAR);
printDatMessage(arg);
}
break;
case IDI_MSA_ACTION_GET_WRENCH:
if (!mickeyHasItem(IDI_MSA_ITEM_WRENCH)) {
- _game.iRmObj[_game.iRoom] -= 2;
+ _gameStateMickey.iRmObj[_gameStateMickey.iRoom] -= 2;
getItem(IDI_MSA_ITEM_WRENCH);
printDatMessage(arg);
}
break;
case IDI_MSA_ACTION_OPEN_CLOSET:
- if (_game.iRmMenu[_game.iRoom]) {
+ if (_gameStateMickey.iRmMenu[_gameStateMickey.iRoom]) {
printDatMessage(99);
} else {
- _game.iRmMenu[_game.iRoom] = 1;
- _game.iRmPic[_game.iRoom] = IDI_MSA_PIC_EARTH_BEDROOM_1;
- _game.iRmObj[_game.iRoom] = 7;
+ _gameStateMickey.iRmMenu[_gameStateMickey.iRoom] = 1;
+ _gameStateMickey.iRmPic[_gameStateMickey.iRoom] = IDI_MSA_PIC_EARTH_BEDROOM_1;
+ _gameStateMickey.iRmObj[_gameStateMickey.iRoom] = 7;
drawRoom();
printDatMessage(arg);
}
break;
case IDI_MSA_ACTION_GET_MATTRESS:
if (!mickeyHasItem(IDI_MSA_ITEM_MATTRESS)) {
- _game.iRmObj[_game.iRoom]--;
+ _gameStateMickey.iRmObj[_gameStateMickey.iRoom]--;
getItem(IDI_MSA_ITEM_MATTRESS);
printDatMessage(arg);
}
break;
case IDI_MSA_ACTION_GET_SCARF:
if (!mickeyHasItem(IDI_MSA_ITEM_SCARF)) {
- _game.iRmObj[_game.iRoom] -= 2;
+ _gameStateMickey.iRmObj[_gameStateMickey.iRoom] -= 2;
getItem(IDI_MSA_ITEM_SCARF);
printDatMessage(arg);
}
break;
case IDI_MSA_ACTION_GET_SUNGLASSES:
if (!mickeyHasItem(IDI_MSA_ITEM_SUNGLASSES)) {
- _game.iRmObj[_game.iRoom]--;
+ _gameStateMickey.iRmObj[_gameStateMickey.iRoom]--;
getItem(IDI_MSA_ITEM_SUNGLASSES);
printDatMessage(arg);
}
break;
case IDI_MSA_ACTION_GET_SCALE:
if (!mickeyHasItem(IDI_MSA_ITEM_SCALE)) {
- _game.iRmMenu[IDI_MSA_PIC_VENUS_WEIGH] = 1;
- _game.iRmMenu[IDI_MSA_PIC_NEPTUNE_WEIGH] = 1;
- _game.iRmMenu[IDI_MSA_PIC_MERCURY_WEIGH] = 1;
- _game.iRmMenu[IDI_MSA_PIC_SATURN_WEIGH] = 1;
- _game.iRmMenu[IDI_MSA_PIC_PLUTO_WEIGH] = 1;
- _game.iRmMenu[IDI_MSA_PIC_JUPITER_WEIGH] = 1;
- _game.iRmMenu[IDI_MSA_PIC_MARS_WEIGH] = 1;
- _game.iRmMenu[IDI_MSA_PIC_URANUS_WEIGH] = 1;
- _game.iRmObj[_game.iRoom] -= 2;
+ _gameStateMickey.iRmMenu[IDI_MSA_PIC_VENUS_WEIGH] = 1;
+ _gameStateMickey.iRmMenu[IDI_MSA_PIC_NEPTUNE_WEIGH] = 1;
+ _gameStateMickey.iRmMenu[IDI_MSA_PIC_MERCURY_WEIGH] = 1;
+ _gameStateMickey.iRmMenu[IDI_MSA_PIC_SATURN_WEIGH] = 1;
+ _gameStateMickey.iRmMenu[IDI_MSA_PIC_PLUTO_WEIGH] = 1;
+ _gameStateMickey.iRmMenu[IDI_MSA_PIC_JUPITER_WEIGH] = 1;
+ _gameStateMickey.iRmMenu[IDI_MSA_PIC_MARS_WEIGH] = 1;
+ _gameStateMickey.iRmMenu[IDI_MSA_PIC_URANUS_WEIGH] = 1;
+ _gameStateMickey.iRmObj[_gameStateMickey.iRoom] -= 2;
getItem(IDI_MSA_ITEM_SCALE);
printDatMessage(arg);
}
break;
case IDI_MSA_ACTION_GOTO_SPACESHIP:
- _game.iRoom = IDI_MSA_PIC_SHIP_AIRLOCK;
- if (_game.iPlanet != IDI_MSA_PLANET_EARTH)
+ _gameStateMickey.iRoom = IDI_MSA_PIC_SHIP_AIRLOCK;
+ if (_gameStateMickey.iPlanet != IDI_MSA_PLANET_EARTH)
insertDisk(0);
return true;
// VENUS
case IDI_MSA_ACTION_DOWN_CHASM:
- if (_game.fItem[IDI_MSA_ITEM_ROPE]) {
- _game.iRmMenu[_game.iRoom] = 1;
+ if (_gameStateMickey.fItem[IDI_MSA_ITEM_ROPE]) {
+ _gameStateMickey.iRmMenu[_gameStateMickey.iRoom] = 1;
}
printDatMessage(arg);
break;
case IDI_MSA_ACTION_DOWN_ROPE:
- if (_game.fItemUsed[IDI_MSA_ITEM_ROPE]) {
- _game.iRoom = IDI_MSA_PIC_VENUS_PROBE;
+ if (_gameStateMickey.fItemUsed[IDI_MSA_ITEM_ROPE]) {
+ _gameStateMickey.iRoom = IDI_MSA_PIC_VENUS_PROBE;
return true;
} else {
printDatMessage(arg);
}
break;
case IDI_MSA_ACTION_USE_ROPE:
- if (_game.fItemUsed[IDI_MSA_ITEM_ROPE]) {
+ if (_gameStateMickey.fItemUsed[IDI_MSA_ITEM_ROPE]) {
printDatMessage(22);
} else {
- _game.fItemUsed[IDI_MSA_ITEM_ROPE] = true;
- _game.fItem[IDI_MSA_ITEM_ROPE] = false;
- _game.iRmPic[_game.iRoom] = IDI_MSA_PIC_VENUS_CHASM_1;
+ _gameStateMickey.fItemUsed[IDI_MSA_ITEM_ROPE] = true;
+ _gameStateMickey.fItem[IDI_MSA_ITEM_ROPE] = false;
+ _gameStateMickey.iRmPic[_gameStateMickey.iRoom] = IDI_MSA_PIC_VENUS_CHASM_1;
drawRoom();
printDatMessage(arg);
}
break;
case IDI_MSA_ACTION_OPEN_HATCH:
- if (_game.fItemUsed[IDI_MSA_ITEM_WRENCH]) {
- if ((_game.iRmMenu[_game.iRoom] == 3) || (_game.iRmPic[_game.iRoom] == IDI_MSA_PIC_VENUS_PROBE_1))
+ if (_gameStateMickey.fItemUsed[IDI_MSA_ITEM_WRENCH]) {
+ if ((_gameStateMickey.iRmMenu[_gameStateMickey.iRoom] == 3) || (_gameStateMickey.iRmPic[_gameStateMickey.iRoom] == IDI_MSA_PIC_VENUS_PROBE_1))
printDatMessage(39);
else {
- _game.iRmMenu[_game.iRoom] = 2;
- _game.iRmPic[_game.iRoom] = IDI_MSA_PIC_VENUS_PROBE_1;
+ _gameStateMickey.iRmMenu[_gameStateMickey.iRoom] = 2;
+ _gameStateMickey.iRmPic[_gameStateMickey.iRoom] = IDI_MSA_PIC_VENUS_PROBE_1;
drawRoom();
printDatMessage(24);
}
} else {
- if (_game.fItem[IDI_MSA_ITEM_WRENCH]) {
- _game.iRmMenu[_game.iRoom] = 1;
+ if (_gameStateMickey.fItem[IDI_MSA_ITEM_WRENCH]) {
+ _gameStateMickey.iRmMenu[_gameStateMickey.iRoom] = 1;
}
printDatMessage(arg);
}
break;
case IDI_MSA_ACTION_USE_WRENCH:
- _game.fItemUsed[IDI_MSA_ITEM_WRENCH] = true;
+ _gameStateMickey.fItemUsed[IDI_MSA_ITEM_WRENCH] = true;
printDatString(arg);
- if (_game.iRmPic[_game.iRoom] == IDI_MSA_PIC_VENUS_PROBE_1) {
- _vm->clearRow(22);
+ if (_gameStateMickey.iRmPic[_gameStateMickey.iRoom] == IDI_MSA_PIC_VENUS_PROBE_1) {
+ clearRow(22);
}
waitAnyKey();
break;
case IDI_MSA_ACTION_GET_XTAL_VENUS:
- _game.iRmMenu[_game.iRoom] = 3;
+ _gameStateMickey.iRmMenu[_gameStateMickey.iRoom] = 3;
getXtal(arg);
break;
// TRITON (NEPTUNE)
case IDI_MSA_ACTION_LOOK_CASTLE:
- if (!_game.iRmMenu[_game.iRoom]) {
- _game.iRmMenu[_game.iRoom] = 1;
+ if (!_gameStateMickey.iRmMenu[_gameStateMickey.iRoom]) {
+ _gameStateMickey.iRmMenu[_gameStateMickey.iRoom] = 1;
}
printDatMessage(arg);
break;
case IDI_MSA_ACTION_ENTER_OPENING:
- if (_game.fItemUsed[IDI_MSA_ITEM_CROWBAR]) {
- _game.iRoom = IDI_MSA_PIC_NEPTUNE_CASTLE_4;
+ if (_gameStateMickey.fItemUsed[IDI_MSA_ITEM_CROWBAR]) {
+ _gameStateMickey.iRoom = IDI_MSA_PIC_NEPTUNE_CASTLE_4;
return true;
} else {
- if (_game.fItem[IDI_MSA_ITEM_CROWBAR]) {
- _game.iRmMenu[_game.iRoom] = 2;
+ if (_gameStateMickey.fItem[IDI_MSA_ITEM_CROWBAR]) {
+ _gameStateMickey.iRmMenu[_gameStateMickey.iRoom] = 2;
}
printDatMessage(arg);
}
break;
case IDI_MSA_ACTION_USE_CROWBAR:
- _game.fItemUsed[IDI_MSA_ITEM_CROWBAR] = true;
- _game.iRmMenu[_game.iRoom] = 1;
- _game.iRmPic[_game.iRoom] = IDI_MSA_PIC_NEPTUNE_ENTRANCE_1;
+ _gameStateMickey.fItemUsed[IDI_MSA_ITEM_CROWBAR] = true;
+ _gameStateMickey.iRmMenu[_gameStateMickey.iRoom] = 1;
+ _gameStateMickey.iRmPic[_gameStateMickey.iRoom] = IDI_MSA_PIC_NEPTUNE_ENTRANCE_1;
drawRoom();
printDatMessage(arg);
break;
case IDI_MSA_ACTION_GET_XTAL_NEPTUNE:
- if (_game.fHasXtal) {
+ if (_gameStateMickey.fHasXtal) {
printDatMessage(71);
} else {
- if (_game.fItem[IDI_MSA_ITEM_SCARF]) {
- _game.iRmMenu[_game.iRoom] = 1;
+ if (_gameStateMickey.fItem[IDI_MSA_ITEM_SCARF]) {
+ _gameStateMickey.iRmMenu[_gameStateMickey.iRoom] = 1;
}
printDatMessage(arg);
}
break;
case IDI_MSA_ACTION_TALK_LEADER:
- _game.iRoom = IDI_MSA_PIC_NEPTUNE_ENTRYWAY;
+ _gameStateMickey.iRoom = IDI_MSA_PIC_NEPTUNE_ENTRYWAY;
printDatMessage(arg);
return true;
case IDI_MSA_ACTION_GIVE_SCARF:
- _game.iRmObj[_game.iRoom] = 18;
+ _gameStateMickey.iRmObj[_gameStateMickey.iRoom] = 18;
getXtal(arg);
- _game.fItem[IDI_MSA_ITEM_SCARF] = false;
- _game.iRmMenu[_game.iRoom] = 0;
- _game.iRmMenu[IDI_MSA_PIC_EARTH_BEDROOM] = 2;
- _game.iRoom = IDI_MSA_PIC_NEPTUNE_ENTRYWAY;
+ _gameStateMickey.fItem[IDI_MSA_ITEM_SCARF] = false;
+ _gameStateMickey.iRmMenu[_gameStateMickey.iRoom] = 0;
+ _gameStateMickey.iRmMenu[IDI_MSA_PIC_EARTH_BEDROOM] = 2;
+ _gameStateMickey.iRoom = IDI_MSA_PIC_NEPTUNE_ENTRYWAY;
return true;
// MERCURY
case IDI_MSA_ACTION_GET_XTAL_MERCURY:
- if (_game.fHasXtal) {
- _game.iRmMenu[_game.iRoom] = 2;
+ if (_gameStateMickey.fHasXtal) {
+ _gameStateMickey.iRmMenu[_gameStateMickey.iRoom] = 2;
printDatMessage(32);
} else {
- if (_game.fItem[IDI_MSA_ITEM_SUNGLASSES]) {
- _game.iRmMenu[_game.iRoom] = 1;
+ if (_gameStateMickey.fItem[IDI_MSA_ITEM_SUNGLASSES]) {
+ _gameStateMickey.iRmMenu[_gameStateMickey.iRoom] = 1;
}
printDatMessage(arg);
}
break;
case IDI_MSA_ACTION_GIVE_SUNGLASSES:
- _game.iRmObj[_game.iRoom] = 17;
- _game.iRmMenu[_game.iRoom] = 2;
- _game.fItem[IDI_MSA_ITEM_SUNGLASSES] = false;
+ _gameStateMickey.iRmObj[_gameStateMickey.iRoom] = 17;
+ _gameStateMickey.iRmMenu[_gameStateMickey.iRoom] = 2;
+ _gameStateMickey.fItem[IDI_MSA_ITEM_SUNGLASSES] = false;
getXtal(arg);
@@ -1808,30 +1808,30 @@ bool Mickey::parse(int cmd, int arg) {
// TITAN (SATURN)
case IDI_MSA_ACTION_CROSS_LAKE:
- if (_game.fItem[IDI_MSA_ITEM_MATTRESS]) {
- _game.iRmMenu[IDI_MSA_PIC_SATURN_LAKE_0] = 1;
- _game.iRmMenu[IDI_MSA_PIC_SATURN_LAKE_1] = 1;
- _game.iRmMenu[IDI_MSA_PIC_SATURN_LAKE_2] = 1;
+ if (_gameStateMickey.fItem[IDI_MSA_ITEM_MATTRESS]) {
+ _gameStateMickey.iRmMenu[IDI_MSA_PIC_SATURN_LAKE_0] = 1;
+ _gameStateMickey.iRmMenu[IDI_MSA_PIC_SATURN_LAKE_1] = 1;
+ _gameStateMickey.iRmMenu[IDI_MSA_PIC_SATURN_LAKE_2] = 1;
}
printDatMessage(arg);
break;
case IDI_MSA_ACTION_USE_MATTRESS:
- _game.iRoom = IDI_MSA_PIC_SATURN_ISLAND;
+ _gameStateMickey.iRoom = IDI_MSA_PIC_SATURN_ISLAND;
printDatMessage(arg);
return true;
case IDI_MSA_ACTION_GET_XTAL_SATURN:
- if (_game.fHasXtal) {
+ if (_gameStateMickey.fHasXtal) {
printDatMessage(29);
} else {
getXtal(arg);
}
break;
case IDI_MSA_ACTION_LEAVE_ISLAND:
- _game.iRoom = IDI_MSA_PIC_SATURN_LAKE_1;
+ _gameStateMickey.iRoom = IDI_MSA_PIC_SATURN_LAKE_1;
printDatMessage(arg);
@@ -1840,19 +1840,19 @@ bool Mickey::parse(int cmd, int arg) {
// PLUTO
case IDI_MSA_ACTION_GET_XTAL_PLUTO:
- if (_game.fHasXtal) {
+ if (_gameStateMickey.fHasXtal) {
printDatMessage(19);
} else {
- if (_game.fItem[IDI_MSA_ITEM_BONE]) {
- _game.iRmMenu[_game.iRoom] = 1;
+ if (_gameStateMickey.fItem[IDI_MSA_ITEM_BONE]) {
+ _gameStateMickey.iRmMenu[_gameStateMickey.iRoom] = 1;
}
printDatMessage(arg);
}
break;
case IDI_MSA_ACTION_GIVE_BONE:
- _game.fItem[IDI_MSA_ITEM_BONE] = false;
- _game.iRmMenu[_game.iRoom] = 0;
- _game.iRmObj[_game.iRoom] = 16;
+ _gameStateMickey.fItem[IDI_MSA_ITEM_BONE] = false;
+ _gameStateMickey.iRmMenu[_gameStateMickey.iRoom] = 0;
+ _gameStateMickey.iRmObj[_gameStateMickey.iRoom] = 16;
getXtal(arg);
@@ -1862,29 +1862,29 @@ bool Mickey::parse(int cmd, int arg) {
case IDI_MSA_ACTION_GET_ROCK_0:
case IDI_MSA_ACTION_GET_ROCK_1:
- if (_game.fItem[IDI_MSA_ITEM_ROCK]) {
+ if (_gameStateMickey.fItem[IDI_MSA_ITEM_ROCK]) {
printDatMessage(38);
} else {
- _game.iRmMenu[_game.iRoom] = 1;
- _game.iRmObj[_game.iRoom] = IDI_MSA_OBJECT_NONE;
+ _gameStateMickey.iRmMenu[_gameStateMickey.iRoom] = 1;
+ _gameStateMickey.iRmObj[_gameStateMickey.iRoom] = IDI_MSA_OBJECT_NONE;
getItem(IDI_MSA_ITEM_ROCK);
printDatMessage(arg);
}
break;
case IDI_MSA_ACTION_GET_XTAL_JUPITER:
- if (_game.fHasXtal) {
+ if (_gameStateMickey.fHasXtal) {
printDatMessage(15);
} else {
- switch (_game.nRocks) {
+ switch (_gameStateMickey.nRocks) {
case 0:
- if (_game.fItem[IDI_MSA_ITEM_ROCK]) {
- _game.iRmMenu[_game.iRoom] = 1;
+ if (_gameStateMickey.fItem[IDI_MSA_ITEM_ROCK]) {
+ _gameStateMickey.iRmMenu[_gameStateMickey.iRoom] = 1;
}
printDatMessage(arg);
break;
case 1:
- if (_game.fItem[IDI_MSA_ITEM_ROCK]) {
- _game.iRmMenu[_game.iRoom] = 1;
+ if (_gameStateMickey.fItem[IDI_MSA_ITEM_ROCK]) {
+ _gameStateMickey.iRmMenu[_gameStateMickey.iRoom] = 1;
}
printDatMessage(34);
break;
@@ -1895,47 +1895,47 @@ bool Mickey::parse(int cmd, int arg) {
}
break;
case IDI_MSA_ACTION_THROW_ROCK:
- _game.fItem[IDI_MSA_ITEM_ROCK] = false;
- _game.nItems--;
- _game.iRmObj[_game.iRoom]++;
- _game.iRmMenu[_game.iRoom] = 0;
+ _gameStateMickey.fItem[IDI_MSA_ITEM_ROCK] = false;
+ _gameStateMickey.nItems--;
+ _gameStateMickey.iRmObj[_gameStateMickey.iRoom]++;
+ _gameStateMickey.iRmMenu[_gameStateMickey.iRoom] = 0;
drawRoom();
- if (_game.nRocks) {
+ if (_gameStateMickey.nRocks) {
printDatMessage(37);
} else {
printDatMessage(arg);
}
- _game.nRocks++;
+ _gameStateMickey.nRocks++;
break;
// MARS
case IDI_MSA_ACTION_GO_TUBE:
- if (_game.fItem[IDI_MSA_ITEM_FLASHLIGHT]) {
- _game.iRmMenu[_game.iRoom] = 1;
+ if (_gameStateMickey.fItem[IDI_MSA_ITEM_FLASHLIGHT]) {
+ _gameStateMickey.iRmMenu[_gameStateMickey.iRoom] = 1;
}
printDatMessage(arg);
break;
case IDI_MSA_ACTION_USE_FLASHLIGHT:
- _game.iRoom = IDI_MSA_PIC_MARS_TUBE_1;
+ _gameStateMickey.iRoom = IDI_MSA_PIC_MARS_TUBE_1;
printDatMessage(15);
return true;
case IDI_MSA_ACTION_PLUTO_DIG:
- if (_game.fHasXtal) {
+ if (_gameStateMickey.fHasXtal) {
printDatMessage(21);
} else {
getXtal(arg);
}
break;
case IDI_MSA_ACTION_GET_XTAL_MARS:
- if (_game.fHasXtal) {
+ if (_gameStateMickey.fHasXtal) {
printDatMessage(23);
} else {
printDatMessage(arg);
@@ -1945,29 +1945,29 @@ bool Mickey::parse(int cmd, int arg) {
// OBERON (URANUS)
case IDI_MSA_ACTION_ENTER_TEMPLE:
- _game.iRoom = IDI_MSA_PIC_URANUS_TEMPLE;
+ _gameStateMickey.iRoom = IDI_MSA_PIC_URANUS_TEMPLE;
return true;
case IDI_MSA_ACTION_USE_CRYSTAL:
- if (_game.iRmMenu[_game.iRoom]) {
+ if (_gameStateMickey.iRmMenu[_gameStateMickey.iRoom]) {
printDatMessage(25);
} else {
- _game.iRmMenu[_game.iRoom] = 1;
- _game.iRmPic[_game.iRoom] = IDI_MSA_PIC_URANUS_TEMPLE_1;
+ _gameStateMickey.iRmMenu[_gameStateMickey.iRoom] = 1;
+ _gameStateMickey.iRmPic[_gameStateMickey.iRoom] = IDI_MSA_PIC_URANUS_TEMPLE_1;
drawRoom();
- _game.iRmPic[_game.iRoom] = IDI_MSA_PIC_URANUS_TEMPLE;
+ _gameStateMickey.iRmPic[_gameStateMickey.iRoom] = IDI_MSA_PIC_URANUS_TEMPLE;
printDatMessage(arg);
}
break;
case IDI_MSA_ACTION_OPEN_DOOR:
- if (_game.fTempleDoorOpen) {
+ if (_gameStateMickey.fTempleDoorOpen) {
printDatMessage(36);
} else {
- _game.fTempleDoorOpen = 1;
- _game.iRmPic[_game.iRoom] = IDI_MSA_PIC_URANUS_TEMPLE_2;
+ _gameStateMickey.fTempleDoorOpen = 1;
+ _gameStateMickey.iRmPic[_gameStateMickey.iRoom] = IDI_MSA_PIC_URANUS_TEMPLE_2;
drawRoom();
@@ -1975,8 +1975,8 @@ bool Mickey::parse(int cmd, int arg) {
}
break;
case IDI_MSA_ACTION_ENTER_DOOR:
- if (_game.fTempleDoorOpen) {
- _game.iRoom = IDI_MSA_PIC_URANUS_STEPS;
+ if (_gameStateMickey.fTempleDoorOpen) {
+ _gameStateMickey.iRoom = IDI_MSA_PIC_URANUS_STEPS;
return true;
} else {
@@ -1984,17 +1984,17 @@ bool Mickey::parse(int cmd, int arg) {
}
break;
case IDI_MSA_ACTION_GET_XTAL_URANUS:
- if (_game.fHasXtal) {
+ if (_gameStateMickey.fHasXtal) {
printDatMessage(34);
} else {
- if (_game.fItem[IDI_MSA_ITEM_CROWBAR]) {
- _game.iRmMenu[_game.iRoom] = 1;
+ if (_gameStateMickey.fItem[IDI_MSA_ITEM_CROWBAR]) {
+ _gameStateMickey.iRmMenu[_gameStateMickey.iRoom] = 1;
}
printDatMessage(arg);
}
break;
case IDI_MSA_ACTION_USE_CROWBAR_1:
- _game.iRmMenu[_game.iRoom] = 0;
+ _gameStateMickey.iRmMenu[_gameStateMickey.iRoom] = 0;
getXtal(arg);
@@ -2003,11 +2003,11 @@ bool Mickey::parse(int cmd, int arg) {
// SPACESHIP
case IDI_MSA_ACTION_GO_NORTH:
- if (_game.fShipDoorOpen) {
- if (_game.fSuit) {
+ if (_gameStateMickey.fShipDoorOpen) {
+ if (_gameStateMickey.fSuit) {
printDatMessage(45);
} else {
- _game.iRoom = IDI_MSA_PIC_SHIP_CORRIDOR;
+ _gameStateMickey.iRoom = IDI_MSA_PIC_SHIP_CORRIDOR;
return true;
}
} else {
@@ -2015,19 +2015,19 @@ bool Mickey::parse(int cmd, int arg) {
}
break;
case IDI_MSA_ACTION_GO_PLANET:
- if (!_game.fShipDoorOpen) {
- if ((_game.nXtals == IDI_MSA_MAX_PLANET) && (_game.iPlanet == IDI_MSA_PLANET_EARTH))
+ if (!_gameStateMickey.fShipDoorOpen) {
+ if ((_gameStateMickey.nXtals == IDI_MSA_MAX_PLANET) && (_gameStateMickey.iPlanet == IDI_MSA_PLANET_EARTH))
gameOver();
- if ((_game.iPlanet == _game.iPlanetXtal[_game.nXtals]) || (_game.iPlanet == IDI_MSA_PLANET_EARTH)) {
- _game.fHasXtal = false;
- _game.iRoom = IDI_MSA_HOME_PLANET[_game.iPlanet];
+ if ((_gameStateMickey.iPlanet == _gameStateMickey.iPlanetXtal[_gameStateMickey.nXtals]) || (_gameStateMickey.iPlanet == IDI_MSA_PLANET_EARTH)) {
+ _gameStateMickey.fHasXtal = false;
+ _gameStateMickey.iRoom = IDI_MSA_HOME_PLANET[_gameStateMickey.iPlanet];
- if (_game.iPlanet != IDI_MSA_PLANET_EARTH)
+ if (_gameStateMickey.iPlanet != IDI_MSA_PLANET_EARTH)
insertDisk(1);
return true;
} else {
- _game.iRoom = IDI_MSA_SHIP_PLANET[_game.iPlanet];
+ _gameStateMickey.iRoom = IDI_MSA_SHIP_PLANET[_gameStateMickey.iPlanet];
return true;
}
@@ -2036,20 +2036,20 @@ bool Mickey::parse(int cmd, int arg) {
}
break;
case IDI_MSA_ACTION_PRESS_BUTTON:
- if (_game.fShipDoorOpen) { // inner door open
- if (_game.iPlanet && !_game.fSuit) {
+ if (_gameStateMickey.fShipDoorOpen) { // inner door open
+ if (_gameStateMickey.iPlanet && !_gameStateMickey.fSuit) {
printDatMessage(arg);
} else {
- _game.fShipDoorOpen = false;
- _game.iRmPic[_game.iRoom]--;
+ _gameStateMickey.fShipDoorOpen = false;
+ _gameStateMickey.iRmPic[_gameStateMickey.iRoom]--;
drawRoom();
printDatMessage(2);
}
} else {
- _game.fShipDoorOpen = true;
- _game.iRmPic[_game.iRoom]++;
+ _gameStateMickey.fShipDoorOpen = true;
+ _gameStateMickey.iRmPic[_gameStateMickey.iRoom]++;
drawRoom();
@@ -2057,11 +2057,11 @@ bool Mickey::parse(int cmd, int arg) {
}
break;
case IDI_MSA_ACTION_WEAR_SPACESUIT:
- if (_game.fSuit) {
- if (_game.fShipDoorOpen) {
- _game.fSuit = false;
- _game.iRmMenu[_game.iRoom] = 0;
- _game.iRmPic[_game.iRoom] -= 2;
+ if (_gameStateMickey.fSuit) {
+ if (_gameStateMickey.fShipDoorOpen) {
+ _gameStateMickey.fSuit = false;
+ _gameStateMickey.iRmMenu[_gameStateMickey.iRoom] = 0;
+ _gameStateMickey.iRmPic[_gameStateMickey.iRoom] -= 2;
drawRoom();
@@ -2070,10 +2070,10 @@ bool Mickey::parse(int cmd, int arg) {
printDatMessage(3);
}
} else {
- if (_game.iPlanet) {
- _game.fSuit = true;
- _game.iRmMenu[_game.iRoom] = 1;
- _game.iRmPic[_game.iRoom] += 2;
+ if (_gameStateMickey.iPlanet) {
+ _gameStateMickey.fSuit = true;
+ _gameStateMickey.iRmMenu[_gameStateMickey.iRoom] = 1;
+ _gameStateMickey.iRmPic[_gameStateMickey.iRoom] += 2;
drawRoom();
@@ -2085,14 +2085,14 @@ bool Mickey::parse(int cmd, int arg) {
break;
case IDI_MSA_ACTION_READ_GAUGE:
printDatString(arg);
- _vm->drawStr(21, 15, IDA_DEFAULT, (const char *)IDS_MSA_TEMP_C[_game.iPlanet]);
- _vm->drawStr(21, 23, IDA_DEFAULT, (const char *)IDS_MSA_TEMP_F[_game.iPlanet]);
+ drawStr(21, 15, IDA_DEFAULT, (const char *)IDS_MSA_TEMP_C[_gameStateMickey.iPlanet]);
+ drawStr(21, 23, IDA_DEFAULT, (const char *)IDS_MSA_TEMP_F[_gameStateMickey.iPlanet]);
waitAnyKey();
break;
case IDI_MSA_ACTION_PRESS_ORANGE:
- if (_game.fFlying) {
+ if (_gameStateMickey.fFlying) {
printDatMessage(4);
} else {
playSound(IDI_MSA_SND_PRESS_ORANGE);
@@ -2101,7 +2101,7 @@ bool Mickey::parse(int cmd, int arg) {
}
break;
case IDI_MSA_ACTION_PRESS_BLUE:
- if (_game.fFlying) {
+ if (_gameStateMickey.fFlying) {
printDatMessage(4);
} else {
playSound(IDI_MSA_SND_PRESS_BLUE);
@@ -2113,18 +2113,18 @@ bool Mickey::parse(int cmd, int arg) {
flipSwitch();
break;
case IDI_MSA_ACTION_PUSH_THROTTLE:
- if (_game.fFlying) {
- _game.fFlying = false;
- _game.nButtons = 0;
+ if (_gameStateMickey.fFlying) {
+ _gameStateMickey.fFlying = false;
+ _gameStateMickey.nButtons = 0;
- memset(_game.szAddr, 0, sizeof(_game.szAddr));
+ memset(_gameStateMickey.szAddr, 0, sizeof(_gameStateMickey.szAddr));
drawRoom();
printDatString(22);
- _vm->drawStr(IDI_MSA_ROW_PLANET, IDI_MSA_COL_PLANET, IDA_DEFAULT,
- (const char *)IDS_MSA_PLANETS[_game.iPlanet]);
+ drawStr(IDI_MSA_ROW_PLANET, IDI_MSA_COL_PLANET, IDA_DEFAULT,
+ (const char *)IDS_MSA_PLANETS[_gameStateMickey.iPlanet]);
waitAnyKey(true);
@@ -2134,39 +2134,39 @@ bool Mickey::parse(int cmd, int arg) {
}
break;
case IDI_MSA_ACTION_PULL_THROTTLE:
- if (_game.fFlying) {
+ if (_gameStateMickey.fFlying) {
printDatMessage(18);
} else {
if (getPlanet() != -1) {
- _game.fFlying = true;
- _game.iPlanet = getPlanet();
+ _gameStateMickey.fFlying = true;
+ _gameStateMickey.iPlanet = getPlanet();
drawRoom();
printDatMessage(16);
} else {
- _game.nButtons = 0;
+ _gameStateMickey.nButtons = 0;
- memset(_game.szAddr, 0, sizeof(_game.szAddr));
+ memset(_gameStateMickey.szAddr, 0, sizeof(_gameStateMickey.szAddr));
printDatMessage(17);
}
}
break;
case IDI_MSA_ACTION_LEAVE_ROOM:
- if (_game.fFlying) {
+ if (_gameStateMickey.fFlying) {
printDatMessage(24);
} else {
- _game.iRoom = arg;
+ _gameStateMickey.iRoom = arg;
return true;
}
break;
case IDI_MSA_ACTION_OPEN_CABINET_1:
- if (_game.iRmMenu[_game.iRoom]) {
+ if (_gameStateMickey.iRmMenu[_gameStateMickey.iRoom]) {
printLine("THE CABINET IS ALREADY OPEN");
} else {
- _game.iRmMenu[_game.iRoom] = 1;
- _game.iRmPic[_game.iRoom] = IDI_MSA_PIC_SHIP_KITCHEN_1;
+ _gameStateMickey.iRmMenu[_gameStateMickey.iRoom] = 1;
+ _gameStateMickey.iRmPic[_gameStateMickey.iRoom] = IDI_MSA_PIC_SHIP_KITCHEN_1;
drawRoom();
@@ -2174,7 +2174,7 @@ bool Mickey::parse(int cmd, int arg) {
}
break;
case IDI_MSA_ACTION_READ_MAP:
- _game.iRmPic[_game.iRoom] = IDI_MSA_PIC_STAR_MAP;
+ _gameStateMickey.iRmPic[_gameStateMickey.iRoom] = IDI_MSA_PIC_STAR_MAP;
drawRoom();
@@ -2182,16 +2182,16 @@ bool Mickey::parse(int cmd, int arg) {
printDatMessage(47);
printDatMessage(48);
- _game.iRmPic[_game.iRoom] = IDI_MSA_PIC_SHIP_BEDROOM;
+ _gameStateMickey.iRmPic[_gameStateMickey.iRoom] = IDI_MSA_PIC_SHIP_BEDROOM;
drawRoom();
break;
case IDI_MSA_ACTION_GO_WEST:
- _game.nButtons = 0;
+ _gameStateMickey.nButtons = 0;
- memset(_game.szAddr, 0, sizeof(_game.szAddr));
+ memset(_gameStateMickey.szAddr, 0, sizeof(_gameStateMickey.szAddr));
- _game.iRoom = arg;
+ _gameStateMickey.iRoom = arg;
return true;
}
@@ -2201,14 +2201,14 @@ bool Mickey::parse(int cmd, int arg) {
// Keyboard
-void Mickey::waitAnyKey(bool anim) {
+void MickeyEngine::waitAnyKey(bool anim) {
Common::Event event;
if (!anim)
- _vm->_gfx->doUpdate();
+ _gfx->doUpdate();
- while (!_vm->shouldQuit()) {
- while (_vm->_system->getEventManager()->pollEvent(event)) {
+ while (!shouldQuit()) {
+ while (_system->getEventManager()->pollEvent(event)) {
switch (event.type) {
case Common::EVENT_RTL:
case Common::EVENT_QUIT:
@@ -2223,134 +2223,138 @@ void Mickey::waitAnyKey(bool anim) {
if (anim) {
animate();
- _vm->_gfx->doUpdate();
+ _gfx->doUpdate();
}
- _vm->_system->updateScreen();
- _vm->_system->delayMillis(10);
+ _system->updateScreen();
+ _system->delayMillis(10);
}
}
// Console-related functions
-void Mickey::debugCurRoom() {
- _vm->_console->DebugPrintf("Current Room = %d\n", _game.iRoom);
+void MickeyEngine::debugCurRoom() {
+ _console->DebugPrintf("Current Room = %d\n", _gameStateMickey.iRoom);
- if (_game.iRmObj[_game.iRoom] != IDI_MSA_OBJECT_NONE) {
- _vm->_console->DebugPrintf("Object %d is in the room\n", _game.iRmObj[_game.iRoom]);
+ if (_gameStateMickey.iRmObj[_gameStateMickey.iRoom] != IDI_MSA_OBJECT_NONE) {
+ _console->DebugPrintf("Object %d is in the room\n", _gameStateMickey.iRmObj[_gameStateMickey.iRoom]);
}
}
-void Mickey::debugGotoRoom(int room) {
- _game.iRoom = room;
+void MickeyEngine::debugGotoRoom(int room) {
+ _gameStateMickey.iRoom = room;
drawRoom();
}
-Mickey::Mickey(PreAgiEngine *vm) : _vm(vm) {
- _vm->_console = new Mickey_Console(_vm, this);
+MickeyEngine::MickeyEngine(OSystem *syst, const AGIGameDescription *gameDesc) : PreAgiEngine(syst, gameDesc) {
+ _console = new MickeyConsole(this);
}
-Mickey::~Mickey() {
+MickeyEngine::~MickeyEngine() {
+ delete _console;
}
-void Mickey::init() {
+void MickeyEngine::init() {
uint8 buffer[512];
// clear game struct
- memset(&_game, 0, sizeof(_game));
- memset(&_game.iItem, IDI_MSA_OBJECT_NONE, sizeof(_game.iItem));
+ memset(&_gameStateMickey, 0, sizeof(_gameStateMickey));
+ memset(&_gameStateMickey.iItem, IDI_MSA_OBJECT_NONE, sizeof(_gameStateMickey.iItem));
// read room extended desc flags
//readExe(IDO_MSA_ROOM_TEXT, buffer, sizeof(buffer));
- //memcpy(_game.fRmTxt, buffer, sizeof(_game.fRmTxt));
+ //memcpy(_gameStateMickey.fRmTxt, buffer, sizeof(_gameStateMickey.fRmTxt));
// read room extended desc offsets
readExe(IDO_MSA_ROOM_TEXT_OFFSETS, buffer, sizeof(buffer));
- memcpy(_game.oRmTxt, buffer, sizeof(_game.oRmTxt));
+ memcpy(_gameStateMickey.oRmTxt, buffer, sizeof(_gameStateMickey.oRmTxt));
for (int i = 0; i < IDI_MSA_MAX_ROOM; i++)
- _game.oRmTxt[i] = buffer[i*2] + 256 * buffer[i*2+1];
+ _gameStateMickey.oRmTxt[i] = buffer[i*2] + 256 * buffer[i*2+1];
// read room object indices
//readExe(IDO_MSA_ROOM_OBJECT, buffer, sizeof(buffer));
- //memcpy(_game.iRmObj, buffer, sizeof(_game.iRmObj));
+ //memcpy(_gameStateMickey.iRmObj, buffer, sizeof(_gameStateMickey.iRmObj));
// read room picture indices
//readExe(IDO_MSA_ROOM_PICTURE, buffer, sizeof(buffer));
- //memcpy(_game.iRmPic, buffer, sizeof(_game.iRmPic));
+ //memcpy(_gameStateMickey.iRmPic, buffer, sizeof(_gameStateMickey.iRmPic));
// read room menu patch indices
readExe(IDO_MSA_ROOM_MENU_FIX, buffer, sizeof(buffer));
- memcpy(_game.nRmMenu, buffer, sizeof(_game.nRmMenu));
+ memcpy(_gameStateMickey.nRmMenu, buffer, sizeof(_gameStateMickey.nRmMenu));
// set room picture and room object indices
for (int i = 0; i < IDI_MSA_MAX_ROOM; i++) {
- _game.iRmPic[i] = i;
- _game.iRmObj[i] = -1;
+ _gameStateMickey.iRmPic[i] = i;
+ _gameStateMickey.iRmObj[i] = -1;
}
- _game.iRmPic[IDI_MSA_PIC_SHIP_AIRLOCK] = IDI_MSA_PIC_SHIP_AIRLOCK_0;
- _game.iRmObj[IDI_MSA_PIC_EARTH_BATHROOM] = 11;
- _game.iRmObj[IDI_MSA_PIC_JUPITER_LAVA] = 21;
- _game.iRmObj[IDI_MSA_PIC_JUPITER_ROCK_0] = 20;
- _game.iRmObj[IDI_MSA_PIC_JUPITER_ROCK_1] = 19;
- _game.iRmObj[IDI_MSA_PIC_EARTH_IN_DOGHOUSE] = 1;
+ _gameStateMickey.iRmPic[IDI_MSA_PIC_SHIP_AIRLOCK] = IDI_MSA_PIC_SHIP_AIRLOCK_0;
+ _gameStateMickey.iRmObj[IDI_MSA_PIC_EARTH_BATHROOM] = 11;
+ _gameStateMickey.iRmObj[IDI_MSA_PIC_JUPITER_LAVA] = 21;
+ _gameStateMickey.iRmObj[IDI_MSA_PIC_JUPITER_ROCK_0] = 20;
+ _gameStateMickey.iRmObj[IDI_MSA_PIC_JUPITER_ROCK_1] = 19;
+ _gameStateMickey.iRmObj[IDI_MSA_PIC_EARTH_IN_DOGHOUSE] = 1;
#if 0
// DEBUG
- _game.iPlanet = IDI_MSA_PLANET_EARTH;
- _game.iRoom = IDI_MSA_PIC_SHIP_CONTROLS;
- _game.fHasXtal = true;
- _game.nXtals = 9;
- _game.fItemUsed[IDI_MSA_ITEM_LETTER] = true;
+ _gameStateMickey.iPlanet = IDI_MSA_PLANET_EARTH;
+ _gameStateMickey.iRoom = IDI_MSA_PIC_SHIP_CONTROLS;
+ _gameStateMickey.fHasXtal = true;
+ _gameStateMickey.nXtals = 9;
+ _gameStateMickey.fItemUsed[IDI_MSA_ITEM_LETTER] = true;
#endif
}
-void Mickey::run() {
- bool done;
+Common::Error MickeyEngine::go() {
+ init();
// Game intro
intro();
// Game loop
- while (!_vm->shouldQuit()) {
+ while (!shouldQuit()) {
drawRoom();
- if (_game.fIntro) {
- _game.fIntro = false;
+ if (_gameStateMickey.fIntro) {
+ _gameStateMickey.fIntro = false;
} else {
printRoomDesc();
}
- if (_game.iRoom == IDI_MSA_PIC_NEPTUNE_GUARD) {
- _game.iRoom = IDI_MSA_PIC_NEPTUNE_LEADER;
+ bool done;
+ if (_gameStateMickey.iRoom == IDI_MSA_PIC_NEPTUNE_GUARD) {
+ _gameStateMickey.iRoom = IDI_MSA_PIC_NEPTUNE_LEADER;
done = true;
} else {
done = false;
}
- while (!done && !_vm->shouldQuit()) {
+ while (!done && !shouldQuit()) {
// Check air supply
- if (_game.fSuit) {
- _game.nAir -= 1;
+ if (_gameStateMickey.fSuit) {
+ _gameStateMickey.nAir -= 1;
for (int i = 0; i < 4; i++) {
- if (_game.nAir == IDI_MSA_AIR_SUPPLY[i]) {
+ if (_gameStateMickey.nAir == IDI_MSA_AIR_SUPPLY[i]) {
playSound(IDI_MSA_SND_XL30);
printExeMsg(IDO_MSA_XL30_SPEAKING);
printExeMsg(IDO_MSA_AIR_SUPPLY[i]);
if (i == 3)
- return;
+ return Common::kNoError;
}
}
} else {
- _game.nAir = 50; // max air supply
+ _gameStateMickey.nAir = 50; // max air supply
}
done = checkMenu();
}
- _game.nFrame = 0;
+ _gameStateMickey.nFrame = 0;
}
gameOver();
-}
+ return Common::kNoError;
}
+
+} // End of namespace Agi
diff --git a/engines/agi/preagi_mickey.h b/engines/agi/preagi_mickey.h
index 62981375c6..673839a592 100644
--- a/engines/agi/preagi_mickey.h
+++ b/engines/agi/preagi_mickey.h
@@ -676,23 +676,25 @@ struct MSA_GAME {
class PreAgiEngine;
-class Mickey {
+class MickeyEngine : public PreAgiEngine {
public:
- Mickey(PreAgiEngine *vm);
- ~Mickey();
+ MickeyEngine(OSystem *syst, const AGIGameDescription *gameDesc);
+ ~MickeyEngine();
void init();
- void run();
+ Common::Error go();
void debugCurRoom();
void debugGotoRoom(int);
void drawPic(int);
void drawObj(ENUM_MSA_OBJECT, int, int);
+ GUI::Debugger *getDebugger() { return _console; }
+
protected:
- PreAgiEngine *_vm;
+ MickeyConsole *_console;
- MSA_GAME _game;
+ MSA_GAME _gameStateMickey;
bool _clickToMove;
int getDat(int);
@@ -741,14 +743,14 @@ protected:
bool planetIsAlreadyAssigned(int planet) {
for (int j = 0; j < IDI_MSA_MAX_PLANET; j++) {
- if (_game.iPlanetXtal[j] == planet)
+ if (_gameStateMickey.iPlanetXtal[j] == planet)
return true;
}
return false;
}
bool mickeyHasItem(int item) {
- if (_game.fItem[item]) {
+ if (_gameStateMickey.fItem[item]) {
printDatMessage(90); // Mickey already has item
return true;
} else {
diff --git a/engines/agi/preagi_troll.cpp b/engines/agi/preagi_troll.cpp
index 445a9e34ff..c2e2bef66e 100644
--- a/engines/agi/preagi_troll.cpp
+++ b/engines/agi/preagi_troll.cpp
@@ -31,32 +31,35 @@
namespace Agi {
-Troll::Troll(PreAgiEngine* vm) : _vm(vm) {
+TrollEngine::TrollEngine(OSystem *syst, const AGIGameDescription *gameDesc) : PreAgiEngine(syst, gameDesc) {
+}
+
+TrollEngine::~TrollEngine() {
}
// User Interface
-void Troll::pressAnyKey(int col) {
- _vm->drawStr(24, col, kColorDefault, IDS_TRO_PRESSANYKEY);
- _vm->_gfx->doUpdate();
- _vm->getSelection(kSelAnyKey);
+void TrollEngine::pressAnyKey(int col) {
+ drawStr(24, col, kColorDefault, IDS_TRO_PRESSANYKEY);
+ _gfx->doUpdate();
+ getSelection(kSelAnyKey);
}
-void Troll::drawMenu(const char *szMenu, int iSel) {
- _vm->clearTextArea();
- _vm->drawStr(21, 0, kColorDefault, szMenu);
- _vm->drawStr(22 + iSel, 0, kColorDefault, " *");
- _vm->_gfx->doUpdate();
+void TrollEngine::drawMenu(const char *szMenu, int iSel) {
+ clearTextArea();
+ drawStr(21, 0, kColorDefault, szMenu);
+ drawStr(22 + iSel, 0, kColorDefault, " *");
+ _gfx->doUpdate();
}
-bool Troll::getMenuSel(const char *szMenu, int *iSel, int nSel) {
+bool TrollEngine::getMenuSel(const char *szMenu, int *iSel, int nSel) {
Common::Event event;
int y;
drawMenu(szMenu, *iSel);
- while (!_vm->shouldQuit()) {
- while (_vm->_system->getEventManager()->pollEvent(event)) {
+ while (!shouldQuit()) {
+ while (_system->getEventManager()->pollEvent(event)) {
switch (event.type) {
case Common::EVENT_RTL:
case Common::EVENT_QUIT:
@@ -117,8 +120,8 @@ bool Troll::getMenuSel(const char *szMenu, int *iSel, int nSel) {
break;
}
}
- _vm->_system->updateScreen();
- _vm->_system->delayMillis(10);
+ _system->updateScreen();
+ _system->delayMillis(10);
}
return true;
@@ -126,18 +129,18 @@ bool Troll::getMenuSel(const char *szMenu, int *iSel, int nSel) {
// Graphics
-void Troll::drawPic(int iPic, bool f3IsCont, bool clr, bool troll) {
- _vm->_picture->setDimensions(IDI_TRO_PIC_WIDTH, IDI_TRO_PIC_HEIGHT);
+void TrollEngine::drawPic(int iPic, bool f3IsCont, bool clr, bool troll) {
+ _picture->setDimensions(IDI_TRO_PIC_WIDTH, IDI_TRO_PIC_HEIGHT);
if (clr) {
- _vm->clearScreen(0x0f, false);
- _vm->_picture->clear();
+ clearScreen(0x0f, false);
+ _picture->clear();
}
- _vm->_picture->setPictureData(_gameData + IDO_TRO_FRAMEPIC);
- _vm->_picture->drawPicture();
+ _picture->setPictureData(_gameData + IDO_TRO_FRAMEPIC);
+ _picture->drawPicture();
- _vm->_picture->setPictureData(_gameData + _pictureOffsets[iPic]);
+ _picture->setPictureData(_gameData + _pictureOffsets[iPic]);
int addFlag = 0;
@@ -145,26 +148,26 @@ void Troll::drawPic(int iPic, bool f3IsCont, bool clr, bool troll) {
addFlag = kPicFTrollMode;
if (f3IsCont) {
- _vm->_picture->setPictureFlags(kPicFf3Cont | addFlag);
+ _picture->setPictureFlags(kPicFf3Cont | addFlag);
} else {
- _vm->_picture->setPictureFlags(kPicFf3Stop | addFlag);
+ _picture->setPictureFlags(kPicFf3Stop | addFlag);
}
- _vm->_picture->drawPicture();
+ _picture->drawPicture();
- _vm->_picture->showPic();
- _vm->_gfx->doUpdate();
+ _picture->showPic();
+ _gfx->doUpdate();
}
// Game Logic
-void Troll::inventory() {
+void TrollEngine::inventory() {
char tmp[40];
int n;
- _vm->clearScreen(0x07);
- _vm->drawStr(1, 12, kColorDefault, IDS_TRO_TREASURE_0);
- _vm->drawStr(2, 12, kColorDefault, IDS_TRO_TREASURE_1);
+ clearScreen(0x07);
+ drawStr(1, 12, kColorDefault, IDS_TRO_TREASURE_0);
+ drawStr(2, 12, kColorDefault, IDS_TRO_TREASURE_1);
for (int i = 0; i < IDI_TRO_MAX_TREASURE - _treasuresLeft; i++) {
@@ -172,36 +175,36 @@ void Troll::inventory() {
sprintf(tmp, " %2d ", i + 1);
- _vm->drawStr(2 + i, 10, _items[n].bg << 4 | 0x0f, tmp);
- _vm->drawStr(2 + i, 14, _items[n].bg << 4 | _items[n].fg, _items[n].name);
+ drawStr(2 + i, 10, _items[n].bg << 4 | 0x0f, tmp);
+ drawStr(2 + i, 14, _items[n].bg << 4 | _items[n].fg, _items[n].name);
}
switch (_treasuresLeft) {
case 1:
sprintf(tmp, IDS_TRO_TREASURE_5, _treasuresLeft);
- _vm->drawStr(20, 10, kColorDefault, tmp);
+ drawStr(20, 10, kColorDefault, tmp);
break;
case 0:
- _vm->drawStr(20, 1, kColorDefault, IDS_TRO_TREASURE_6);
+ drawStr(20, 1, kColorDefault, IDS_TRO_TREASURE_6);
break;
case IDI_TRO_MAX_TREASURE:
- _vm->drawStr(3, 17, kColorDefault, IDS_TRO_TREASURE_2);
+ drawStr(3, 17, kColorDefault, IDS_TRO_TREASURE_2);
default:
sprintf(tmp, IDS_TRO_TREASURE_4, _treasuresLeft);
- _vm->drawStr(20, 10, kColorDefault, tmp);
+ drawStr(20, 10, kColorDefault, tmp);
break;
}
pressAnyKey(6);
}
-void Troll::waitAnyKeyIntro() {
+void TrollEngine::waitAnyKeyIntro() {
Common::Event event;
int iMsg = 0;
- while (!_vm->shouldQuit()) {
- while (_vm->_system->getEventManager()->pollEvent(event)) {
+ while (!shouldQuit()) {
+ while (_system->getEventManager()->pollEvent(event)) {
switch (event.type) {
case Common::EVENT_RTL:
case Common::EVENT_QUIT:
@@ -217,26 +220,26 @@ void Troll::waitAnyKeyIntro() {
case 200:
iMsg = 0;
case 0:
- _vm->drawStr(22, 3, kColorDefault, IDS_TRO_INTRO_2);
- _vm->_gfx->doUpdate();
+ drawStr(22, 3, kColorDefault, IDS_TRO_INTRO_2);
+ _gfx->doUpdate();
break;
case 100:
- _vm->drawStr(22, 3, kColorDefault, IDS_TRO_INTRO_3);
- _vm->_gfx->doUpdate();
+ drawStr(22, 3, kColorDefault, IDS_TRO_INTRO_3);
+ _gfx->doUpdate();
break;
}
iMsg++;
- _vm->_system->updateScreen();
- _vm->_system->delayMillis(10);
+ _system->updateScreen();
+ _system->delayMillis(10);
}
}
-void Troll::credits() {
- _vm->clearScreen(0x07);
+void TrollEngine::credits() {
+ clearScreen(0x07);
- _vm->drawStr(1, 2, kColorDefault, IDS_TRO_CREDITS_0);
+ drawStr(1, 2, kColorDefault, IDS_TRO_CREDITS_0);
int color = 10;
char str[2];
@@ -245,49 +248,49 @@ void Troll::credits() {
for (uint i = 0; i < strlen(IDS_TRO_CREDITS_1); i++) {
str[0] = IDS_TRO_CREDITS_1[i];
- _vm->drawStr(7, 19 + i, color++, str);
+ drawStr(7, 19 + i, color++, str);
if (color > 15)
color = 9;
}
- _vm->drawStr(8, 19, kColorDefault, IDS_TRO_CREDITS_2);
+ drawStr(8, 19, kColorDefault, IDS_TRO_CREDITS_2);
- _vm->drawStr(13, 11, 9, IDS_TRO_CREDITS_3);
- _vm->drawStr(15, 8, 10, IDS_TRO_CREDITS_4);
- _vm->drawStr(17, 7, 12, IDS_TRO_CREDITS_5);
- _vm->drawStr(19, 2, 14, IDS_TRO_CREDITS_6);
+ drawStr(13, 11, 9, IDS_TRO_CREDITS_3);
+ drawStr(15, 8, 10, IDS_TRO_CREDITS_4);
+ drawStr(17, 7, 12, IDS_TRO_CREDITS_5);
+ drawStr(19, 2, 14, IDS_TRO_CREDITS_6);
- _vm->_gfx->doUpdate();
+ _gfx->doUpdate();
pressAnyKey();
}
-void Troll::tutorial() {
+void TrollEngine::tutorial() {
bool done = false;
int iSel = 0;
//char szTreasure[16] = {0};
- while (!_vm->shouldQuit()) {
- _vm->clearScreen(0xFF);
+ while (!shouldQuit()) {
+ clearScreen(0xFF);
- _vm->printStr(IDS_TRO_TUTORIAL_0);
- _vm->getSelection(kSelSpace);
+ printStr(IDS_TRO_TUTORIAL_0);
+ getSelection(kSelSpace);
- _vm->clearScreen(0x55);
- _vm->setDefaultTextColor(0x0F);
+ clearScreen(0x55);
+ setDefaultTextColor(0x0F);
done = false;
- while (!done && !_vm->shouldQuit()) {
+ while (!done && !shouldQuit()) {
getMenuSel(IDS_TRO_TUTORIAL_1, &iSel, IDI_TRO_MAX_OPTION);
switch (iSel) {
case IDI_TRO_SEL_OPTION_1:
- _vm->clearScreen(0x22, false);
- _vm->_gfx->doUpdate();
+ clearScreen(0x22, false);
+ _gfx->doUpdate();
break;
case IDI_TRO_SEL_OPTION_2:
- _vm->clearScreen(0x00, false);
- _vm->_gfx->doUpdate();
+ clearScreen(0x00, false);
+ _gfx->doUpdate();
break;
case IDI_TRO_SEL_OPTION_3:
done = true;
@@ -296,102 +299,102 @@ void Troll::tutorial() {
}
// do you need more practice ?
- _vm->clearScreen(0x4F);
- _vm->drawStr(7, 4, kColorDefault, IDS_TRO_TUTORIAL_5);
- _vm->drawStr(9, 4, kColorDefault, IDS_TRO_TUTORIAL_6);
- _vm->_gfx->doUpdate();
+ clearScreen(0x4F);
+ drawStr(7, 4, kColorDefault, IDS_TRO_TUTORIAL_5);
+ drawStr(9, 4, kColorDefault, IDS_TRO_TUTORIAL_6);
+ _gfx->doUpdate();
- if (!_vm->getSelection(kSelYesNo))
+ if (!getSelection(kSelYesNo))
break;
}
// show info texts
- _vm->clearScreen(0x5F);
- _vm->drawStr(4, 1, kColorDefault, IDS_TRO_TUTORIAL_7);
- _vm->drawStr(5, 1, kColorDefault, IDS_TRO_TUTORIAL_8);
- _vm->_gfx->doUpdate();
+ clearScreen(0x5F);
+ drawStr(4, 1, kColorDefault, IDS_TRO_TUTORIAL_7);
+ drawStr(5, 1, kColorDefault, IDS_TRO_TUTORIAL_8);
+ _gfx->doUpdate();
pressAnyKey();
- _vm->clearScreen(0x2F);
- _vm->drawStr(6, 1, kColorDefault, IDS_TRO_TUTORIAL_9);
- _vm->_gfx->doUpdate();
+ clearScreen(0x2F);
+ drawStr(6, 1, kColorDefault, IDS_TRO_TUTORIAL_9);
+ _gfx->doUpdate();
pressAnyKey();
- _vm->clearScreen(0x19);
- _vm->drawStr(7, 1, kColorDefault, IDS_TRO_TUTORIAL_10);
- _vm->drawStr(8, 1, kColorDefault, IDS_TRO_TUTORIAL_11);
- _vm->_gfx->doUpdate();
+ clearScreen(0x19);
+ drawStr(7, 1, kColorDefault, IDS_TRO_TUTORIAL_10);
+ drawStr(8, 1, kColorDefault, IDS_TRO_TUTORIAL_11);
+ _gfx->doUpdate();
pressAnyKey();
- _vm->clearScreen(0x6E);
- _vm->drawStr(9, 1, kColorDefault, IDS_TRO_TUTORIAL_12);
- _vm->drawStr(10, 1, kColorDefault, IDS_TRO_TUTORIAL_13);
- _vm->_gfx->doUpdate();
+ clearScreen(0x6E);
+ drawStr(9, 1, kColorDefault, IDS_TRO_TUTORIAL_12);
+ drawStr(10, 1, kColorDefault, IDS_TRO_TUTORIAL_13);
+ _gfx->doUpdate();
pressAnyKey();
- _vm->clearScreen(0x4C);
- _vm->drawStr(11, 1, kColorDefault, IDS_TRO_TUTORIAL_14);
- _vm->drawStr(12, 1, kColorDefault, IDS_TRO_TUTORIAL_15);
- _vm->_gfx->doUpdate();
+ clearScreen(0x4C);
+ drawStr(11, 1, kColorDefault, IDS_TRO_TUTORIAL_14);
+ drawStr(12, 1, kColorDefault, IDS_TRO_TUTORIAL_15);
+ _gfx->doUpdate();
pressAnyKey();
- _vm->clearScreen(0x5D);
- _vm->drawStr(13, 1, kColorDefault, IDS_TRO_TUTORIAL_16);
- _vm->drawStr(14, 1, kColorDefault, IDS_TRO_TUTORIAL_17);
- _vm->drawStr(15, 1, kColorDefault, IDS_TRO_TUTORIAL_18);
- _vm->_gfx->doUpdate();
+ clearScreen(0x5D);
+ drawStr(13, 1, kColorDefault, IDS_TRO_TUTORIAL_16);
+ drawStr(14, 1, kColorDefault, IDS_TRO_TUTORIAL_17);
+ drawStr(15, 1, kColorDefault, IDS_TRO_TUTORIAL_18);
+ _gfx->doUpdate();
pressAnyKey();
// show treasures
- _vm->clearScreen(0x2A);
- _vm->drawStr(2, 1, kColorDefault, IDS_TRO_TUTORIAL_19);
+ clearScreen(0x2A);
+ drawStr(2, 1, kColorDefault, IDS_TRO_TUTORIAL_19);
for (int i = 0; i < IDI_TRO_MAX_TREASURE; i++)
- _vm->drawStr(19 - i, 11, kColorDefault, _items[i].name);
+ drawStr(19 - i, 11, kColorDefault, _items[i].name);
- _vm->_gfx->doUpdate();
+ _gfx->doUpdate();
pressAnyKey();
}
-void Troll::intro() {
+void TrollEngine::intro() {
// sierra on-line presents
- _vm->clearScreen(0x2F);
- _vm->drawStr(9, 10, kColorDefault, IDS_TRO_INTRO_0);
- _vm->drawStr(14, 15, kColorDefault, IDS_TRO_INTRO_1);
- _vm->_gfx->doUpdate();
- _vm->_system->updateScreen();
- _vm->_system->delayMillis(3200);
+ clearScreen(0x2F);
+ drawStr(9, 10, kColorDefault, IDS_TRO_INTRO_0);
+ drawStr(14, 15, kColorDefault, IDS_TRO_INTRO_1);
+ _gfx->doUpdate();
+ _system->updateScreen();
+ _system->delayMillis(3200);
CursorMan.showMouse(true);
// Draw logo
- _vm->setDefaultTextColor(0x0f);
+ setDefaultTextColor(0x0f);
drawPic(45, false, true);
- _vm->_gfx->doUpdate();
+ _gfx->doUpdate();
// wait for keypress and alternate message
waitAnyKeyIntro();
// have you played this game before?
- _vm->drawStr(22, 3, kColorDefault, IDS_TRO_INTRO_4);
- _vm->drawStr(23, 6, kColorDefault, IDS_TRO_INTRO_5);
- _vm->_gfx->doUpdate();
+ drawStr(22, 3, kColorDefault, IDS_TRO_INTRO_4);
+ drawStr(23, 6, kColorDefault, IDS_TRO_INTRO_5);
+ _gfx->doUpdate();
- if (!_vm->getSelection(kSelYesNo))
+ if (!getSelection(kSelYesNo))
tutorial();
credits();
}
-void Troll::gameOver() {
+void TrollEngine::gameOver() {
// We do a check to see if the game should quit. Without this, the game show the picture, plays the
// music, and then quits. So if the game is quitting, we shouldn't run the "game over" part.
- if (_vm->shouldQuit())
+ if (shouldQuit())
return;
char szMoves[40];
- _vm->clearTextArea();
+ clearTextArea();
drawPic(42, true, true);
playTune(4, 25);
@@ -400,19 +403,19 @@ void Troll::gameOver() {
printUserMessage(33);
- _vm->clearTextArea();
+ clearTextArea();
drawPic(46, true, true);
sprintf(szMoves, IDS_TRO_GAMEOVER_0, _moves);
- _vm->drawStr(21, 1, kColorDefault, szMoves);
- _vm->drawStr(22, 1, kColorDefault, IDS_TRO_GAMEOVER_1);
- _vm->_gfx->doUpdate();
+ drawStr(21, 1, kColorDefault, szMoves);
+ drawStr(22, 1, kColorDefault, IDS_TRO_GAMEOVER_1);
+ _gfx->doUpdate();
pressAnyKey();
}
-void Troll::drawTroll() {
+void TrollEngine::drawTroll() {
for (int i = 0; i < IDI_TRO_NUM_NONTROLL; i++)
if (_currentRoom == _nonTrollRooms[i]) {
_isTrollAway = true;
@@ -422,14 +425,14 @@ void Troll::drawTroll() {
drawPic(43, false, false, true);
}
-int Troll::drawRoom(char *menu) {
+int TrollEngine::drawRoom(char *menu) {
int n = 0;
bool contFlag = false;
if (_currentRoom == 1) {
- _vm->_picture->setDimensions(IDI_TRO_PIC_WIDTH, IDI_TRO_PIC_HEIGHT);
- _vm->clearScreen(0x00, false);
- _vm->_picture->clear();
+ _picture->setDimensions(IDI_TRO_PIC_WIDTH, IDI_TRO_PIC_HEIGHT);
+ clearScreen(0x00, false);
+ _picture->clear();
} else {
if (_currentRoom != 42) {
@@ -439,7 +442,7 @@ int Troll::drawRoom(char *menu) {
}
drawPic(_currentRoom, contFlag, true);
- _vm->_gfx->doUpdate();
+ _gfx->doUpdate();
if (_currentRoom == 42) {
drawPic(44, false, false); // don't clear
@@ -450,7 +453,7 @@ int Troll::drawRoom(char *menu) {
}
}
- _vm->_gfx->doUpdate();
+ _gfx->doUpdate();
char tmp[10];
strncat(menu, (char*)_gameData + _locMessagesIdx[_currentRoom], 39);
@@ -469,7 +472,7 @@ int Troll::drawRoom(char *menu) {
return n;
}
-void Troll::playTune(int tune, int len) {
+void TrollEngine::playTune(int tune, int len) {
if (!_soundOn)
return;
@@ -482,34 +485,34 @@ void Troll::playTune(int tune, int len) {
duration = READ_LE_UINT16(_gameData + ptr);
ptr += 2;
- _vm->playNote(freq, duration);
+ playNote(freq, duration);
}
}
-void Troll::pickupTreasure(int treasureId) {
+void TrollEngine::pickupTreasure(int treasureId) {
char tmp[40];
_inventory[IDI_TRO_MAX_TREASURE - _treasuresLeft] = treasureId;
if (_currentRoom != 24) {
- _vm->clearTextArea();
+ clearTextArea();
drawPic(_currentRoom, false, true);
- _vm->_gfx->doUpdate();
+ _gfx->doUpdate();
}
printUserMessage(treasureId + 16);
- _vm->clearTextArea();
+ clearTextArea();
_treasuresLeft--;
switch (_treasuresLeft) {
case 1:
- _vm->drawStr(22, 1, kColorDefault, IDS_TRO_TREASURE_7);
+ drawStr(22, 1, kColorDefault, IDS_TRO_TREASURE_7);
break;
case 0:
- _vm->drawStr(22, 1, kColorDefault, IDS_TRO_TREASURE_8);
- _vm->drawStr(23, 4, kColorDefault, IDS_TRO_TREASURE_9);
+ drawStr(22, 1, kColorDefault, IDS_TRO_TREASURE_8);
+ drawStr(23, 4, kColorDefault, IDS_TRO_TREASURE_9);
_roomStates[6] = 1;
@@ -517,20 +520,20 @@ void Troll::pickupTreasure(int treasureId) {
break;
default:
sprintf(tmp, IDS_TRO_TREASURE_3, _treasuresLeft);
- _vm->drawStr(22, 1, kColorDefault, tmp);
+ drawStr(22, 1, kColorDefault, tmp);
break;
}
pressAnyKey();
}
-void Troll::printUserMessage(int msgId) {
+void TrollEngine::printUserMessage(int msgId) {
int i;
- _vm->clearTextArea();
+ clearTextArea();
for (i = 0; i < _userMessages[msgId - 1].num; i++) {
- _vm->drawStr(21 + i, 1, kColorDefault, _userMessages[msgId - 1].msg[i]);
+ drawStr(21 + i, 1, kColorDefault, _userMessages[msgId - 1].msg[i]);
}
if (msgId == 34) {
@@ -540,7 +543,7 @@ void Troll::printUserMessage(int msgId) {
pressAnyKey();
}
-void Troll::gameLoop() {
+void TrollEngine::gameLoop() {
bool done = false;
char menu[160+5];
int currentOption, numberOfOptions;
@@ -559,7 +562,7 @@ void Troll::gameLoop() {
memset(_inventory, 0, sizeof(_inventory));
- while (!done && !_vm->shouldQuit()) {
+ while (!done && !shouldQuit()) {
*menu = 0;
currentOption = 0;
@@ -589,7 +592,7 @@ void Troll::gameLoop() {
if (_currentRoom < 6 || _treasuresLeft == 0) {
_isTrollAway = true;
} else { // make odd 1:3
- _isTrollAway = (_vm->rnd(3) != 2);
+ _isTrollAway = (rnd(3) != 2);
}
break;
case OT_GET:
@@ -634,7 +637,7 @@ void Troll::gameLoop() {
}
-void Troll::fillOffsets() {
+void TrollEngine::fillOffsets() {
int i;
for (i = 0; i < IDI_TRO_PICNUM; i++)
@@ -721,8 +724,8 @@ void Troll::fillOffsets() {
// Init
-void Troll::init() {
- _vm->_picture->setPictureVersion(AGIPIC_V15);
+void TrollEngine::init() {
+ _picture->setPictureVersion(AGIPIC_V15);
//SetScreenPar(320, 200, (char*)ibm_fontdata);
const int gaps[] = { 0x3A40, 0x4600, 0x4800, 0x5800, 0x5a00, 0x6a00,
@@ -762,12 +765,16 @@ void Troll::init() {
fillOffsets();
}
-void Troll::run() {
- while (!_vm->shouldQuit()) {
+Common::Error TrollEngine::go() {
+ init();
+
+ while (!shouldQuit()) {
intro();
gameLoop();
gameOver();
}
+
+ return Common::kNoError;
}
} // End of namespace Agi
diff --git a/engines/agi/preagi_troll.h b/engines/agi/preagi_troll.h
index d9a995072b..c14a7872c2 100644
--- a/engines/agi/preagi_troll.h
+++ b/engines/agi/preagi_troll.h
@@ -157,16 +157,14 @@ struct Item {
char name[16];
};
-class Troll {
+class TrollEngine : public PreAgiEngine {
public:
- Troll(PreAgiEngine *vm);
+ TrollEngine(OSystem *syst, const AGIGameDescription *gameDesc);
+ ~TrollEngine();
- void init();
- void run();
+ Common::Error go();
private:
- PreAgiEngine *_vm;
-
int _roomPicture;
int _treasuresLeft;
int _currentRoom;
@@ -180,6 +178,7 @@ private:
byte *_gameData;
+ void init();
void intro();
void drawPic(int iPic, bool f3IsCont, bool clear, bool troll = false);
void drawTroll();
@@ -205,9 +204,7 @@ private:
void fillOffsets();
-private:
// These are come from game data
-
int _pictureOffsets[IDI_TRO_PICNUM];
int _roomPicStartIdx[IDI_TRO_NUM_NUMROOMS];
int _roomPicDeltas[IDI_TRO_NUM_NUMROOMS];
diff --git a/engines/agi/preagi_winnie.cpp b/engines/agi/preagi_winnie.cpp
index af26fe62d0..fee8fde2b3 100644
--- a/engines/agi/preagi_winnie.cpp
+++ b/engines/agi/preagi_winnie.cpp
@@ -31,9 +31,11 @@
#include "common/savefile.h"
#include "common/textconsole.h"
+#include "audio/mididrv.h"
+
namespace Agi {
-void Winnie::parseRoomHeader(WTP_ROOM_HDR *roomHdr, byte *buffer, int len) {
+void WinnieEngine::parseRoomHeader(WTP_ROOM_HDR *roomHdr, byte *buffer, int len) {
int i;
Common::MemoryReadStreamEndian readS(buffer, len, _isBigEndian);
@@ -68,7 +70,7 @@ void Winnie::parseRoomHeader(WTP_ROOM_HDR *roomHdr, byte *buffer, int len) {
roomHdr->opt[i].ofsOpt[j] = readS.readUint16();
}
-void Winnie::parseObjHeader(WTP_OBJ_HDR *objHdr, byte *buffer, int len) {
+void WinnieEngine::parseObjHeader(WTP_OBJ_HDR *objHdr, byte *buffer, int len) {
int i;
Common::MemoryReadStreamEndian readS(buffer, len, _isBigEndian);
@@ -85,16 +87,16 @@ void Winnie::parseObjHeader(WTP_OBJ_HDR *objHdr, byte *buffer, int len) {
objHdr->ofsPic = readS.readUint16();
}
-uint32 Winnie::readRoom(int iRoom, uint8 *buffer, WTP_ROOM_HDR &roomHdr) {
+uint32 WinnieEngine::readRoom(int iRoom, uint8 *buffer, WTP_ROOM_HDR &roomHdr) {
Common::String fileName;
- if (_vm->getPlatform() == Common::kPlatformPC)
+ if (getPlatform() == Common::kPlatformPC)
fileName = Common::String::format(IDS_WTP_ROOM_DOS, iRoom);
- else if (_vm->getPlatform() == Common::kPlatformAmiga)
+ else if (getPlatform() == Common::kPlatformAmiga)
fileName = Common::String::format(IDS_WTP_ROOM_AMIGA, iRoom);
- else if (_vm->getPlatform() == Common::kPlatformC64)
+ else if (getPlatform() == Common::kPlatformC64)
fileName = Common::String::format(IDS_WTP_ROOM_C64, iRoom);
- else if (_vm->getPlatform() == Common::kPlatformApple2GS)
+ else if (getPlatform() == Common::kPlatformApple2GS)
fileName = Common::String::format(IDS_WTP_ROOM_APPLE, iRoom);
Common::File file;
@@ -104,7 +106,7 @@ uint32 Winnie::readRoom(int iRoom, uint8 *buffer, WTP_ROOM_HDR &roomHdr) {
}
uint32 filelen = file.size();
- if (_vm->getPlatform() == Common::kPlatformC64) { // Skip the loading address
+ if (getPlatform() == Common::kPlatformC64) { // Skip the loading address
filelen -= 2;
file.seek(2, SEEK_CUR);
}
@@ -118,16 +120,16 @@ uint32 Winnie::readRoom(int iRoom, uint8 *buffer, WTP_ROOM_HDR &roomHdr) {
return filelen;
}
-uint32 Winnie::readObj(int iObj, uint8 *buffer) {
+uint32 WinnieEngine::readObj(int iObj, uint8 *buffer) {
Common::String fileName;
- if (_vm->getPlatform() == Common::kPlatformPC)
+ if (getPlatform() == Common::kPlatformPC)
fileName = Common::String::format(IDS_WTP_OBJ_DOS, iObj);
- else if (_vm->getPlatform() == Common::kPlatformAmiga)
+ else if (getPlatform() == Common::kPlatformAmiga)
fileName = Common::String::format(IDS_WTP_OBJ_AMIGA, iObj);
- else if (_vm->getPlatform() == Common::kPlatformC64)
+ else if (getPlatform() == Common::kPlatformC64)
fileName = Common::String::format(IDS_WTP_OBJ_C64, iObj);
- else if (_vm->getPlatform() == Common::kPlatformApple2GS)
+ else if (getPlatform() == Common::kPlatformApple2GS)
fileName = Common::String::format(IDS_WTP_OBJ_APPLE, iObj);
Common::File file;
@@ -137,7 +139,7 @@ uint32 Winnie::readObj(int iObj, uint8 *buffer) {
}
uint32 filelen = file.size();
- if (_vm->getPlatform() == Common::kPlatformC64) { // Skip the loading address
+ if (getPlatform() == Common::kPlatformC64) { // Skip the loading address
filelen -= 2;
file.seek(2, SEEK_CUR);
}
@@ -148,7 +150,7 @@ uint32 Winnie::readObj(int iObj, uint8 *buffer) {
return filelen;
}
-void Winnie::randomize() {
+void WinnieEngine::randomize() {
int iObj = 0;
int iRoom = 0;
bool done;
@@ -157,52 +159,52 @@ void Winnie::randomize() {
done = false;
while (!done) {
- iObj = _vm->rnd(IDI_WTP_MAX_OBJ - 1);
+ iObj = rnd(IDI_WTP_MAX_OBJ - 1);
done = true;
for (int j = 0; j < IDI_WTP_MAX_OBJ_MISSING; j++) {
- if (_game.iUsedObj[j] == iObj) {
+ if (_gameStateWinnie.iUsedObj[j] == iObj) {
done = false;
break;
}
}
}
- _game.iUsedObj[i] = iObj;
+ _gameStateWinnie.iUsedObj[i] = iObj;
done = false;
while (!done) {
- iRoom = _vm->rnd(IDI_WTP_MAX_ROOM_NORMAL);
+ iRoom = rnd(IDI_WTP_MAX_ROOM_NORMAL);
done = true;
for (int j = 0; j < IDI_WTP_MAX_ROOM_OBJ; j++) {
- if (_game.iObjRoom[j] == iRoom) {
+ if (_gameStateWinnie.iObjRoom[j] == iRoom) {
done = false;
break;
}
}
}
- _game.iObjRoom[iObj] = iRoom;
+ _gameStateWinnie.iObjRoom[iObj] = iRoom;
}
}
-void Winnie::intro() {
+void WinnieEngine::intro() {
drawPic(IDS_WTP_FILE_LOGO);
- _vm->printStr(IDS_WTP_INTRO_0);
- _vm->_gfx->doUpdate();
- _vm->_system->updateScreen();
- _vm->_system->delayMillis(0x640);
+ printStr(IDS_WTP_INTRO_0);
+ _gfx->doUpdate();
+ _system->updateScreen();
+ _system->delayMillis(0x640);
- if (_vm->getPlatform() == Common::kPlatformAmiga)
- _vm->_gfx->clearScreen(0);
+ if (getPlatform() == Common::kPlatformAmiga)
+ _gfx->clearScreen(0);
drawPic(IDS_WTP_FILE_TITLE);
- _vm->printStr(IDS_WTP_INTRO_1);
- _vm->_gfx->doUpdate();
- _vm->_system->updateScreen();
- _vm->_system->delayMillis(0x640);
+ printStr(IDS_WTP_INTRO_1);
+ _gfx->doUpdate();
+ _system->updateScreen();
+ _system->delayMillis(0x640);
if (!playSound(IDI_WTP_SND_POOH_0))
return;
@@ -214,27 +216,27 @@ void Winnie::intro() {
return;
}
-int Winnie::getObjInRoom(int iRoom) {
+int WinnieEngine::getObjInRoom(int iRoom) {
for (int iObj = 1; iObj < IDI_WTP_MAX_ROOM_OBJ; iObj++)
- if (_game.iObjRoom[iObj] == iRoom)
+ if (_gameStateWinnie.iObjRoom[iObj] == iRoom)
return iObj;
return 0;
}
-void Winnie::setTakeDrop(int fCanSel[]) {
+void WinnieEngine::setTakeDrop(int fCanSel[]) {
fCanSel[IDI_WTP_SEL_TAKE] = getObjInRoom(_room);
- fCanSel[IDI_WTP_SEL_DROP] = _game.iObjHave;
+ fCanSel[IDI_WTP_SEL_DROP] = _gameStateWinnie.iObjHave;
}
-void Winnie::setFlag(int iFlag) {
- _game.fGame[iFlag] = 1;
+void WinnieEngine::setFlag(int iFlag) {
+ _gameStateWinnie.fGame[iFlag] = 1;
}
-void Winnie::clearFlag(int iFlag) {
- _game.fGame[iFlag] = 0;
+void WinnieEngine::clearFlag(int iFlag) {
+ _gameStateWinnie.fGame[iFlag] = 0;
}
-int Winnie::parser(int pc, int index, uint8 *buffer) {
+int WinnieEngine::parser(int pc, int index, uint8 *buffer) {
WTP_ROOM_HDR hdr;
int startpc = pc;
int8 opcode;
@@ -249,7 +251,7 @@ int Winnie::parser(int pc, int index, uint8 *buffer) {
// extract header from buffer
parseRoomHeader(&hdr, buffer, sizeof(WTP_ROOM_HDR));
- while (!_vm->shouldQuit()) {
+ while (!shouldQuit()) {
pc = startpc;
// check if block is to be run
@@ -259,7 +261,7 @@ int Winnie::parser(int pc, int index, uint8 *buffer) {
return IDI_WTP_PAR_OK;
fBlock = *(buffer + pc++);
- if (_game.fGame[iBlock] != fBlock)
+ if (_gameStateWinnie.fGame[iBlock] != fBlock)
return IDI_WTP_PAR_OK;
// extract text from block
@@ -292,12 +294,12 @@ int Winnie::parser(int pc, int index, uint8 *buffer) {
// extract menu string
strcpy(szMenu, (char *)(buffer + pc));
- _vm->XOR80(szMenu);
+ XOR80(szMenu);
break;
default:
// print description
printStrWinnie((char *)(buffer + pc));
- if (_vm->getSelection(kSelBackspace) == 1)
+ if (getSelection(kSelBackspace) == 1)
return IDI_WTP_PAR_OK;
else
return IDI_WTP_PAR_BACK;
@@ -314,7 +316,7 @@ int Winnie::parser(int pc, int index, uint8 *buffer) {
// get menu selection
getMenuSel(szMenu, &iSel, fCanSel);
- if (++_game.nMoves == IDI_WTP_MAX_MOVES_UNTIL_WIND)
+ if (++_gameStateWinnie.nMoves == IDI_WTP_MAX_MOVES_UNTIL_WIND)
_doWind = true;
if (_winnieEvent && (_room <= IDI_WTP_MAX_ROOM_TELEPORT)) {
@@ -356,8 +358,8 @@ int Winnie::parser(int pc, int index, uint8 *buffer) {
iDir = iSel - IDI_WTP_SEL_NORTH;
if (hdr.roomNew[iDir] == IDI_WTP_ROOM_NONE) {
- _vm->printStr(IDS_WTP_CANT_GO);
- _vm->getSelection(kSelAnyKey);
+ printStr(IDS_WTP_CANT_GO);
+ getSelection(kSelAnyKey);
} else {
_room = hdr.roomNew[iDir];
return IDI_WTP_PAR_GOTO;
@@ -391,7 +393,7 @@ int Winnie::parser(int pc, int index, uint8 *buffer) {
case IDO_WTP_PRINT_MSG:
opcode = *(buffer + pc++);
printRoomStr(_room, opcode);
- _vm->getSelection(kSelAnyKey);
+ getSelection(kSelAnyKey);
break;
case IDO_WTP_PRINT_STR:
opcode = *(buffer + pc++);
@@ -416,7 +418,7 @@ int Winnie::parser(int pc, int index, uint8 *buffer) {
case IDO_WTP_WALK_MIST:
_mist--;
if (!_mist) {
- _room = _vm->rnd(IDI_WTP_MAX_ROOM_TELEPORT) + 1;
+ _room = rnd(IDI_WTP_MAX_ROOM_TELEPORT) + 1;
return IDI_WTP_PAR_GOTO;
}
break;
@@ -437,13 +439,13 @@ int Winnie::parser(int pc, int index, uint8 *buffer) {
showOwlHelp();
break;
case IDO_WTP_GOTO_RND:
- _room = _vm->rnd(IDI_WTP_MAX_ROOM_TELEPORT) + 1;
+ _room = rnd(IDI_WTP_MAX_ROOM_TELEPORT) + 1;
return IDI_WTP_PAR_GOTO;
default:
opcode = 0;
break;
}
- } while (opcode && !_vm->shouldQuit());
+ } while (opcode && !shouldQuit());
if (iNewRoom) {
_room = iNewRoom;
@@ -452,38 +454,38 @@ int Winnie::parser(int pc, int index, uint8 *buffer) {
if (iBlock == 1)
return IDI_WTP_PAR_OK;
- _vm->_gfx->doUpdate();
- _vm->_system->updateScreen();
+ _gfx->doUpdate();
+ _system->updateScreen();
}
return IDI_WTP_PAR_OK;
}
-void Winnie::keyHelp() {
+void WinnieEngine::keyHelp() {
playSound(IDI_WTP_SND_KEYHELP);
- _vm->printStr(IDS_WTP_HELP_0);
- _vm->getSelection(kSelAnyKey);
- _vm->printStr(IDS_WTP_HELP_1);
- _vm->getSelection(kSelAnyKey);
+ printStr(IDS_WTP_HELP_0);
+ getSelection(kSelAnyKey);
+ printStr(IDS_WTP_HELP_1);
+ getSelection(kSelAnyKey);
}
-void Winnie::inventory() {
- if (_game.iObjHave)
- printObjStr(_game.iObjHave, IDI_WTP_OBJ_TAKE);
+void WinnieEngine::inventory() {
+ if (_gameStateWinnie.iObjHave)
+ printObjStr(_gameStateWinnie.iObjHave, IDI_WTP_OBJ_TAKE);
else {
- _vm->clearTextArea();
- _vm->drawStr(IDI_WTP_ROW_MENU, IDI_WTP_COL_MENU, IDA_DEFAULT, IDS_WTP_INVENTORY_0);
+ clearTextArea();
+ drawStr(IDI_WTP_ROW_MENU, IDI_WTP_COL_MENU, IDA_DEFAULT, IDS_WTP_INVENTORY_0);
}
- Common::String missing = Common::String::format(IDS_WTP_INVENTORY_1, _game.nObjMiss);
+ Common::String missing = Common::String::format(IDS_WTP_INVENTORY_1, _gameStateWinnie.nObjMiss);
- _vm->drawStr(IDI_WTP_ROW_OPTION_4, IDI_WTP_COL_MENU, IDA_DEFAULT, missing.c_str());
- _vm->_gfx->doUpdate();
- _vm->_system->updateScreen(); //TODO: Move to game's main loop
- _vm->getSelection(kSelAnyKey);
+ drawStr(IDI_WTP_ROW_OPTION_4, IDI_WTP_COL_MENU, IDA_DEFAULT, missing.c_str());
+ _gfx->doUpdate();
+ _system->updateScreen(); //TODO: Move to game's main loop
+ getSelection(kSelAnyKey);
}
-void Winnie::printObjStr(int iObj, int iStr) {
+void WinnieEngine::printObjStr(int iObj, int iStr) {
WTP_OBJ_HDR hdr;
uint8 *buffer = (uint8 *)malloc(2048);
@@ -494,7 +496,7 @@ void Winnie::printObjStr(int iObj, int iStr) {
free(buffer);
}
-bool Winnie::isRightObj(int iRoom, int iObj, int *iCode) {
+bool WinnieEngine::isRightObj(int iRoom, int iObj, int *iCode) {
WTP_ROOM_HDR roomhdr;
WTP_OBJ_HDR objhdr;
uint8 *roomdata = (uint8 *)malloc(4096);
@@ -517,212 +519,212 @@ bool Winnie::isRightObj(int iRoom, int iObj, int *iCode) {
return false;
}
-void Winnie::takeObj(int iRoom) {
- if (_game.iObjHave) {
+void WinnieEngine::takeObj(int iRoom) {
+ if (_gameStateWinnie.iObjHave) {
// player is already carrying an object, can't take
- _vm->printStr(IDS_WTP_CANT_TAKE);
- _vm->getSelection(kSelAnyKey);
+ printStr(IDS_WTP_CANT_TAKE);
+ getSelection(kSelAnyKey);
} else {
// take object
int iObj = getObjInRoom(iRoom);
- _game.iObjHave = iObj;
- _game.iObjRoom[iObj] = 0;
+ _gameStateWinnie.iObjHave = iObj;
+ _gameStateWinnie.iObjRoom[iObj] = 0;
- _vm->printStr(IDS_WTP_OK);
+ printStr(IDS_WTP_OK);
playSound(IDI_WTP_SND_TAKE);
drawRoomPic();
// print object "take" string
- printObjStr(_game.iObjHave, IDI_WTP_OBJ_TAKE);
- _vm->getSelection(kSelAnyKey);
+ printObjStr(_gameStateWinnie.iObjHave, IDI_WTP_OBJ_TAKE);
+ getSelection(kSelAnyKey);
// HACK WARNING
if (iObj == 18) {
- _game.fGame[0x0d] = 1;
+ _gameStateWinnie.fGame[0x0d] = 1;
}
}
}
-void Winnie::dropObj(int iRoom) {
+void WinnieEngine::dropObj(int iRoom) {
int iCode;
if (getObjInRoom(iRoom)) {
// there already is an object in the room, can't drop
- _vm->printStr(IDS_WTP_CANT_DROP);
- _vm->getSelection(kSelAnyKey);
+ printStr(IDS_WTP_CANT_DROP);
+ getSelection(kSelAnyKey);
} else {
// HACK WARNING
- if (_game.iObjHave == 18) {
- _game.fGame[0x0d] = 0;
+ if (_gameStateWinnie.iObjHave == 18) {
+ _gameStateWinnie.fGame[0x0d] = 0;
}
- if (isRightObj(iRoom, _game.iObjHave, &iCode)) {
+ if (isRightObj(iRoom, _gameStateWinnie.iObjHave, &iCode)) {
// object has been dropped in the right place
- _vm->printStr(IDS_WTP_OK);
- _vm->getSelection(kSelAnyKey);
+ printStr(IDS_WTP_OK);
+ getSelection(kSelAnyKey);
playSound(IDI_WTP_SND_DROP_OK);
- printObjStr(_game.iObjHave, IDI_WTP_OBJ_DROP);
- _vm->getSelection(kSelAnyKey);
+ printObjStr(_gameStateWinnie.iObjHave, IDI_WTP_OBJ_DROP);
+ getSelection(kSelAnyKey);
// increase amount of objects returned, decrease amount of objects missing
- _game.nObjMiss--;
- _game.nObjRet++;
+ _gameStateWinnie.nObjMiss--;
+ _gameStateWinnie.nObjRet++;
// xor the dropped object with 0x80 to signify it has been dropped in the right place
for (int i = 0; i < IDI_WTP_MAX_OBJ_MISSING; i++) {
- if (_game.iUsedObj[i] == _game.iObjHave) {
- _game.iUsedObj[i] ^= 0x80;
+ if (_gameStateWinnie.iUsedObj[i] == _gameStateWinnie.iObjHave) {
+ _gameStateWinnie.iUsedObj[i] ^= 0x80;
break;
}
}
// set flag according to dropped object's id
- _game.fGame[iCode] = 1;
+ _gameStateWinnie.fGame[iCode] = 1;
// player is carrying nothing
- _game.iObjHave = 0;
+ _gameStateWinnie.iObjHave = 0;
- if (!_game.nObjMiss) {
+ if (!_gameStateWinnie.nObjMiss) {
// all objects returned, tell player to find party
playSound(IDI_WTP_SND_FANFARE);
- _vm->printStr(IDS_WTP_GAME_OVER_0);
- _vm->getSelection(kSelAnyKey);
- _vm->printStr(IDS_WTP_GAME_OVER_1);
- _vm->getSelection(kSelAnyKey);
+ printStr(IDS_WTP_GAME_OVER_0);
+ getSelection(kSelAnyKey);
+ printStr(IDS_WTP_GAME_OVER_1);
+ getSelection(kSelAnyKey);
}
} else {
// drop object in the given room
- _game.iObjRoom[_game.iObjHave] = iRoom;
+ _gameStateWinnie.iObjRoom[_gameStateWinnie.iObjHave] = iRoom;
// object has been dropped in the wrong place
- _vm->printStr(IDS_WTP_WRONG_PLACE);
- _vm->getSelection(kSelAnyKey);
+ printStr(IDS_WTP_WRONG_PLACE);
+ getSelection(kSelAnyKey);
playSound(IDI_WTP_SND_DROP);
drawRoomPic();
- _vm->printStr(IDS_WTP_WRONG_PLACE);
- _vm->getSelection(kSelAnyKey);
+ printStr(IDS_WTP_WRONG_PLACE);
+ getSelection(kSelAnyKey);
// print object description
- printObjStr(_game.iObjHave, IDI_WTP_OBJ_DESC);
- _vm->getSelection(kSelAnyKey);
+ printObjStr(_gameStateWinnie.iObjHave, IDI_WTP_OBJ_DESC);
+ getSelection(kSelAnyKey);
- _game.iObjHave = 0;
+ _gameStateWinnie.iObjHave = 0;
}
}
}
-void Winnie::dropObjRnd() {
- if (!_game.iObjHave)
+void WinnieEngine::dropObjRnd() {
+ if (!_gameStateWinnie.iObjHave)
return;
int iRoom = 0;
bool done = false;
while (!done) {
- iRoom = _vm->rnd(IDI_WTP_MAX_ROOM_NORMAL);
+ iRoom = rnd(IDI_WTP_MAX_ROOM_NORMAL);
done = true;
if (iRoom == _room)
done = false;
for (int j = 0; j < IDI_WTP_MAX_ROOM_OBJ; j++) {
- if (_game.iObjRoom[j] == iRoom) {
+ if (_gameStateWinnie.iObjRoom[j] == iRoom) {
done = false;
}
}
}
- _game.iObjRoom[_game.iObjHave] = iRoom;
- _game.iObjHave = 0;
+ _gameStateWinnie.iObjRoom[_gameStateWinnie.iObjHave] = iRoom;
+ _gameStateWinnie.iObjHave = 0;
}
-void Winnie::wind() {
+void WinnieEngine::wind() {
int iRoom = 0;
bool done;
_doWind = 0;
- _game.nMoves = 0;
- if (!_game.nObjMiss)
+ _gameStateWinnie.nMoves = 0;
+ if (!_gameStateWinnie.nObjMiss)
return;
- _vm->printStr(IDS_WTP_WIND_0);
+ printStr(IDS_WTP_WIND_0);
playSound(IDI_WTP_SND_WIND_0);
- _vm->getSelection(kSelAnyKey);
+ getSelection(kSelAnyKey);
- _vm->printStr(IDS_WTP_WIND_1);
+ printStr(IDS_WTP_WIND_1);
playSound(IDI_WTP_SND_WIND_0);
- _vm->getSelection(kSelAnyKey);
+ getSelection(kSelAnyKey);
dropObjRnd();
// randomize positions of objects at large
for (int i = 0; i < IDI_WTP_MAX_OBJ_MISSING; i++) {
- if (!(_game.iUsedObj[i] & IDI_XOR_KEY)) {
+ if (!(_gameStateWinnie.iUsedObj[i] & IDI_XOR_KEY)) {
done = false;
while (!done) {
- iRoom = _vm->rnd(IDI_WTP_MAX_ROOM_NORMAL);
+ iRoom = rnd(IDI_WTP_MAX_ROOM_NORMAL);
done = true;
for (int j = 0; j < IDI_WTP_MAX_ROOM_OBJ; j++) {
- if (_game.iObjRoom[j] == iRoom) {
+ if (_gameStateWinnie.iObjRoom[j] == iRoom) {
done = false;
}
}
}
- _game.iObjRoom[_game.iUsedObj[i]] = iRoom;
+ _gameStateWinnie.iObjRoom[_gameStateWinnie.iUsedObj[i]] = iRoom;
}
}
}
-void Winnie::mist() {
+void WinnieEngine::mist() {
// mist length in turns is (2-5)
- _mist = _vm->rnd(4) + 2;
+ _mist = rnd(4) + 2;
_room = IDI_WTP_ROOM_MIST;
drawRoomPic();
- _vm->printStr(IDS_WTP_MIST);
+ printStr(IDS_WTP_MIST);
}
-void Winnie::tigger() {
+void WinnieEngine::tigger() {
_room = IDI_WTP_ROOM_TIGGER;
drawRoomPic();
- _vm->printStr(IDS_WTP_TIGGER);
+ printStr(IDS_WTP_TIGGER);
dropObjRnd();
}
-void Winnie::showOwlHelp() {
- if (_game.iObjHave) {
- _vm->printStr(IDS_WTP_OWL_0);
- _vm->getSelection(kSelAnyKey);
- printObjStr(_game.iObjHave, IDI_WTP_OBJ_HELP);
- _vm->getSelection(kSelAnyKey);
+void WinnieEngine::showOwlHelp() {
+ if (_gameStateWinnie.iObjHave) {
+ printStr(IDS_WTP_OWL_0);
+ getSelection(kSelAnyKey);
+ printObjStr(_gameStateWinnie.iObjHave, IDI_WTP_OBJ_HELP);
+ getSelection(kSelAnyKey);
}
if (getObjInRoom(_room)) {
- _vm->printStr(IDS_WTP_OWL_0);
- _vm->getSelection(kSelAnyKey);
+ printStr(IDS_WTP_OWL_0);
+ getSelection(kSelAnyKey);
printObjStr(getObjInRoom(_room), IDI_WTP_OBJ_HELP);
- _vm->getSelection(kSelAnyKey);
+ getSelection(kSelAnyKey);
}
}
-void Winnie::drawMenu(char *szMenu, int iSel, int fCanSel[]) {
+void WinnieEngine::drawMenu(char *szMenu, int iSel, int fCanSel[]) {
int iRow = 0, iCol = 0;
- _vm->clearTextArea();
- _vm->drawStr(IDI_WTP_ROW_MENU, IDI_WTP_COL_MENU, IDA_DEFAULT, szMenu);
+ clearTextArea();
+ drawStr(IDI_WTP_ROW_MENU, IDI_WTP_COL_MENU, IDA_DEFAULT, szMenu);
if (fCanSel[IDI_WTP_SEL_NORTH])
- _vm->drawStr(IDI_WTP_ROW_OPTION_4, IDI_WTP_COL_NSEW, IDA_DEFAULT, IDS_WTP_NSEW);
+ drawStr(IDI_WTP_ROW_OPTION_4, IDI_WTP_COL_NSEW, IDA_DEFAULT, IDS_WTP_NSEW);
if (fCanSel[IDI_WTP_SEL_TAKE])
- _vm->drawStr(IDI_WTP_ROW_OPTION_4, IDI_WTP_COL_TAKE, IDA_DEFAULT, IDS_WTP_TAKE);
+ drawStr(IDI_WTP_ROW_OPTION_4, IDI_WTP_COL_TAKE, IDA_DEFAULT, IDS_WTP_TAKE);
if (fCanSel[IDI_WTP_SEL_DROP])
- _vm->drawStr(IDI_WTP_ROW_OPTION_4, IDI_WTP_COL_DROP, IDA_DEFAULT, IDS_WTP_DROP);
+ drawStr(IDI_WTP_ROW_OPTION_4, IDI_WTP_COL_DROP, IDA_DEFAULT, IDS_WTP_DROP);
switch (iSel) {
case IDI_WTP_SEL_OPT_1:
@@ -756,26 +758,26 @@ void Winnie::drawMenu(char *szMenu, int iSel, int fCanSel[]) {
iCol = IDI_WTP_COL_DROP;
break;
}
- _vm->drawStr(iRow, iCol - 1, IDA_DEFAULT, ">");
- _vm->_gfx->doUpdate();
- _vm->_system->updateScreen(); //TODO: Move to game's main loop
+ drawStr(iRow, iCol - 1, IDA_DEFAULT, ">");
+ _gfx->doUpdate();
+ _system->updateScreen(); //TODO: Move to game's main loop
}
-void Winnie::incMenuSel(int *iSel, int fCanSel[]) {
+void WinnieEngine::incMenuSel(int *iSel, int fCanSel[]) {
do {
*iSel += 1;
if (*iSel > IDI_WTP_SEL_DROP) *iSel = IDI_WTP_SEL_OPT_1;
} while (!fCanSel[*iSel]);
}
-void Winnie::decMenuSel(int *iSel, int fCanSel[]) {
+void WinnieEngine::decMenuSel(int *iSel, int fCanSel[]) {
do {
*iSel -= 1;
if (*iSel < IDI_WTP_SEL_OPT_1) *iSel = IDI_WTP_SEL_DROP;
} while (!fCanSel[*iSel]);
}
-void Winnie::getMenuMouseSel(int *iSel, int fCanSel[], int x, int y) {
+void WinnieEngine::getMenuMouseSel(int *iSel, int fCanSel[], int x, int y) {
switch (y) {
case IDI_WTP_ROW_OPTION_1:
case IDI_WTP_ROW_OPTION_2:
@@ -793,7 +795,7 @@ void Winnie::getMenuMouseSel(int *iSel, int fCanSel[], int x, int y) {
}
}
-void Winnie::makeSel(int *iSel, int fCanSel[]) {
+void WinnieEngine::makeSel(int *iSel, int fCanSel[]) {
if (fCanSel[*iSel])
return;
@@ -801,7 +803,7 @@ void Winnie::makeSel(int *iSel, int fCanSel[]) {
clrMenuSel(iSel, fCanSel);
}
-void Winnie::getMenuSel(char *szMenu, int *iSel, int fCanSel[]) {
+void WinnieEngine::getMenuSel(char *szMenu, int *iSel, int fCanSel[]) {
Common::Event event;
int x, y;
@@ -811,8 +813,8 @@ void Winnie::getMenuSel(char *szMenu, int *iSel, int fCanSel[]) {
// Show the mouse cursor for the menu
CursorMan.showMouse(true);
- while (!_vm->shouldQuit()) {
- while (_vm->_system->getEventManager()->pollEvent(event)) {
+ while (!shouldQuit()) {
+ while (_system->getEventManager()->pollEvent(event)) {
switch (event.type) {
case Common::EVENT_RTL:
case Common::EVENT_QUIT:
@@ -824,15 +826,15 @@ void Winnie::getMenuSel(char *szMenu, int *iSel, int fCanSel[]) {
// Change cursor
if (fCanSel[IDI_WTP_SEL_NORTH] && hotspotNorth.contains(event.mouse.x, event.mouse.y)) {
- _vm->_gfx->setCursorPalette(true);
+ _gfx->setCursorPalette(true);
} else if (fCanSel[IDI_WTP_SEL_SOUTH] && hotspotSouth.contains(event.mouse.x, event.mouse.y)) {
- _vm->_gfx->setCursorPalette(true);
+ _gfx->setCursorPalette(true);
} else if (fCanSel[IDI_WTP_SEL_WEST] && hotspotWest.contains(event.mouse.x, event.mouse.y)) {
- _vm->_gfx->setCursorPalette(true);
+ _gfx->setCursorPalette(true);
} else if (fCanSel[IDI_WTP_SEL_EAST] && hotspotEast.contains(event.mouse.x, event.mouse.y)) {
- _vm->_gfx->setCursorPalette(true);
+ _gfx->setCursorPalette(true);
} else {
- _vm->_gfx->setCursorPalette(false);
+ _gfx->setCursorPalette(false);
}
break;
@@ -841,25 +843,25 @@ void Winnie::getMenuSel(char *szMenu, int *iSel, int fCanSel[]) {
if (fCanSel[IDI_WTP_SEL_NORTH] && hotspotNorth.contains(event.mouse.x, event.mouse.y)) {
*iSel = IDI_WTP_SEL_NORTH;
makeSel(iSel, fCanSel);
- _vm->_gfx->setCursorPalette(false);
+ _gfx->setCursorPalette(false);
return;
} else if (fCanSel[IDI_WTP_SEL_SOUTH] && hotspotSouth.contains(event.mouse.x, event.mouse.y)) {
*iSel = IDI_WTP_SEL_SOUTH;
makeSel(iSel, fCanSel);
- _vm->_gfx->setCursorPalette(false);
+ _gfx->setCursorPalette(false);
return;
} else if (fCanSel[IDI_WTP_SEL_WEST] && hotspotWest.contains(event.mouse.x, event.mouse.y)) {
*iSel = IDI_WTP_SEL_WEST;
makeSel(iSel, fCanSel);
- _vm->_gfx->setCursorPalette(false);
+ _gfx->setCursorPalette(false);
return;
} else if (fCanSel[IDI_WTP_SEL_EAST] && hotspotEast.contains(event.mouse.x, event.mouse.y)) {
*iSel = IDI_WTP_SEL_EAST;
makeSel(iSel, fCanSel);
- _vm->_gfx->setCursorPalette(false);
+ _gfx->setCursorPalette(false);
return;
} else {
- _vm->_gfx->setCursorPalette(false);
+ _gfx->setCursorPalette(false);
}
switch (*iSel) {
@@ -896,9 +898,9 @@ void Winnie::getMenuSel(char *szMenu, int *iSel, int fCanSel[]) {
incMenuSel(iSel, fCanSel);
break;
case Common::EVENT_KEYDOWN:
- if (event.kbd.keycode == Common::KEYCODE_d && (event.kbd.flags & Common::KBD_CTRL) && _vm->_console) {
- _vm->_console->attach();
- _vm->_console->onFrame();
+ if (event.kbd.keycode == Common::KEYCODE_d && (event.kbd.flags & Common::KBD_CTRL) && _console) {
+ _console->attach();
+ _console->onFrame();
continue;
}
@@ -944,7 +946,7 @@ void Winnie::getMenuSel(char *szMenu, int *iSel, int fCanSel[]) {
break;
case Common::KEYCODE_s:
if (event.kbd.flags & Common::KBD_CTRL) {
- _vm->flipflag(fSoundOn);
+ flipflag(fSoundOn);
} else {
*iSel = IDI_WTP_SEL_SOUTH;
makeSel(iSel, fCanSel);
@@ -1005,24 +1007,24 @@ void Winnie::getMenuSel(char *szMenu, int *iSel, int fCanSel[]) {
}
}
-void Winnie::gameLoop() {
+void WinnieEngine::gameLoop() {
WTP_ROOM_HDR hdr;
uint8 *roomdata = (uint8 *)malloc(4096);
int iBlock;
phase0:
- if (!_game.nObjMiss && (_room == IDI_WTP_ROOM_PICNIC))
+ if (!_gameStateWinnie.nObjMiss && (_room == IDI_WTP_ROOM_PICNIC))
_room = IDI_WTP_ROOM_PARTY;
readRoom(_room, roomdata, hdr);
drawRoomPic();
- _vm->_gfx->doUpdate();
- _vm->_system->updateScreen();
+ _gfx->doUpdate();
+ _system->updateScreen();
phase1:
if (getObjInRoom(_room)) {
printObjStr(getObjInRoom(_room), IDI_WTP_OBJ_DESC);
- _vm->getSelection(kSelAnyKey);
+ getSelection(kSelAnyKey);
}
phase2:
@@ -1031,7 +1033,7 @@ phase2:
goto phase1;
}
- while (!_vm->shouldQuit()) {
+ while (!shouldQuit()) {
for (iBlock = 0; iBlock < IDI_WTP_MAX_BLOCK; iBlock++) {
switch (parser(hdr.ofsBlock[iBlock] - _roomOffset, iBlock, roomdata)) {
case IDI_WTP_PAR_GOTO:
@@ -1047,10 +1049,10 @@ phase2:
free(roomdata);
}
-void Winnie::drawPic(const char *szName) {
+void WinnieEngine::drawPic(const char *szName) {
Common::String fileName = szName;
- if (_vm->getPlatform() != Common::kPlatformAmiga)
+ if (getPlatform() != Common::kPlatformAmiga)
fileName += ".pic";
Common::File file;
@@ -1065,13 +1067,13 @@ void Winnie::drawPic(const char *szName) {
file.read(buffer, size);
file.close();
- _vm->_picture->decodePicture(buffer, size, 1, IDI_WTP_PIC_WIDTH, IDI_WTP_PIC_HEIGHT);
- _vm->_picture->showPic(IDI_WTP_PIC_X0, IDI_WTP_PIC_Y0, IDI_WTP_PIC_WIDTH, IDI_WTP_PIC_HEIGHT);
+ _picture->decodePicture(buffer, size, 1, IDI_WTP_PIC_WIDTH, IDI_WTP_PIC_HEIGHT);
+ _picture->showPic(IDI_WTP_PIC_X0, IDI_WTP_PIC_Y0, IDI_WTP_PIC_WIDTH, IDI_WTP_PIC_HEIGHT);
free(buffer);
}
-void Winnie::drawObjPic(int iObj, int x0, int y0) {
+void WinnieEngine::drawObjPic(int iObj, int x0, int y0) {
if (!iObj)
return;
@@ -1080,28 +1082,28 @@ void Winnie::drawObjPic(int iObj, int x0, int y0) {
uint32 objSize = readObj(iObj, buffer);
parseObjHeader(&objhdr, buffer, sizeof(WTP_OBJ_HDR));
- _vm->_picture->setOffset(x0, y0);
- _vm->_picture->decodePicture(buffer + objhdr.ofsPic - _objOffset, objSize, 0, IDI_WTP_PIC_WIDTH, IDI_WTP_PIC_HEIGHT);
- _vm->_picture->setOffset(0, 0);
- _vm->_picture->showPic(10, 0, IDI_WTP_PIC_WIDTH, IDI_WTP_PIC_HEIGHT);
+ _picture->setOffset(x0, y0);
+ _picture->decodePicture(buffer + objhdr.ofsPic - _objOffset, objSize, 0, IDI_WTP_PIC_WIDTH, IDI_WTP_PIC_HEIGHT);
+ _picture->setOffset(0, 0);
+ _picture->showPic(10, 0, IDI_WTP_PIC_WIDTH, IDI_WTP_PIC_HEIGHT);
free(buffer);
}
-void Winnie::drawRoomPic() {
+void WinnieEngine::drawRoomPic() {
WTP_ROOM_HDR roomhdr;
uint8 *buffer = (uint8 *)malloc(4096);
int iObj = getObjInRoom(_room);
// clear gfx screen
- _vm->_gfx->clearScreen(0);
+ _gfx->clearScreen(0);
// read room picture
readRoom(_room, buffer, roomhdr);
// draw room picture
- _vm->_picture->decodePicture(buffer + roomhdr.ofsPic - _roomOffset, 4096, 1, IDI_WTP_PIC_WIDTH, IDI_WTP_PIC_HEIGHT);
- _vm->_picture->showPic(IDI_WTP_PIC_X0, IDI_WTP_PIC_Y0, IDI_WTP_PIC_WIDTH, IDI_WTP_PIC_HEIGHT);
+ _picture->decodePicture(buffer + roomhdr.ofsPic - _roomOffset, 4096, 1, IDI_WTP_PIC_WIDTH, IDI_WTP_PIC_HEIGHT);
+ _picture->showPic(IDI_WTP_PIC_X0, IDI_WTP_PIC_Y0, IDI_WTP_PIC_WIDTH, IDI_WTP_PIC_HEIGHT);
// draw object picture
drawObjPic(iObj, IDI_WTP_PIC_X0 + roomhdr.objX, IDI_WTP_PIC_Y0 + roomhdr.objY);
@@ -1109,21 +1111,68 @@ void Winnie::drawRoomPic() {
free(buffer);
}
-bool Winnie::playSound(ENUM_WTP_SOUND iSound) {
- //TODO
- warning ("STUB: playSound(%d)", iSound);
- return 1;
+bool WinnieEngine::playSound(ENUM_WTP_SOUND iSound) {
+ // TODO: Only DOS sound is supported, currently
+ if (getPlatform() != Common::kPlatformPC) {
+ warning("STUB: playSound(%d)", iSound);
+ return false;
+ }
+
+ Common::String fileName = Common::String::format(IDS_WTP_SND_DOS, iSound);
+
+ Common::File file;
+ if (!file.open(fileName))
+ return false;
+
+ uint32 size = file.size();
+ byte *data = new byte[size];
+ file.read(data, size);
+ file.close();
+
+ _game.sounds[0] = AgiSound::createFromRawResource(data, size, 0, *_sound, _soundemu);
+ _sound->startSound(0, 0);
+
+ bool cursorShowing = CursorMan.showMouse(false);
+ _system->updateScreen();
+
+ // Loop until the sound is done
+ bool skippedSound = false;
+ while (!shouldQuit() && _game.sounds[0]->isPlaying()) {
+ Common::Event event;
+ while (_system->getEventManager()->pollEvent(event)) {
+ switch (event.type) {
+ case Common::EVENT_KEYDOWN:
+ _sound->stopSound();
+ skippedSound = true;
+ break;
+ default:
+ break;
+ }
+ }
+
+ _system->delayMillis(10);
+ }
+
+ if (cursorShowing) {
+ CursorMan.showMouse(true);
+ _system->updateScreen();
+ }
+
+ delete _game.sounds[0];
+ _game.sounds[0] = 0;
+
+ return !shouldQuit() && !skippedSound;
}
-void Winnie::clrMenuSel(int *iSel, int fCanSel[]) {
+void WinnieEngine::clrMenuSel(int *iSel, int fCanSel[]) {
*iSel = IDI_WTP_SEL_OPT_1;
while (!fCanSel[*iSel]) {
*iSel += 1;
}
- _vm->_gfx->setCursorPalette(false);
+ _gfx->setCursorPalette(false);
}
-void Winnie::printRoomStr(int iRoom, int iStr) {
+void WinnieEngine::printRoomStr(int iRoom, int iStr) {
WTP_ROOM_HDR hdr;
uint8 *buffer = (uint8 *)malloc(4096);
@@ -1133,23 +1182,23 @@ void Winnie::printRoomStr(int iRoom, int iStr) {
free(buffer);
}
-void Winnie::gameOver() {
+void WinnieEngine::gameOver() {
// sing the Pooh song forever
- while (!_vm->shouldQuit()) {
- _vm->printStr(IDS_WTP_SONG_0);
+ while (!shouldQuit()) {
+ printStr(IDS_WTP_SONG_0);
playSound(IDI_WTP_SND_POOH_0);
- _vm->printStr(IDS_WTP_SONG_1);
+ printStr(IDS_WTP_SONG_1);
playSound(IDI_WTP_SND_POOH_1);
- _vm->printStr(IDS_WTP_SONG_2);
+ printStr(IDS_WTP_SONG_2);
playSound(IDI_WTP_SND_POOH_2);
- _vm->getSelection(kSelAnyKey);
+ getSelection(kSelAnyKey);
}
}
-void Winnie::saveGame() {
+void WinnieEngine::saveGame() {
int i = 0;
- Common::OutSaveFile *outfile = _vm->getSaveFileMan()->openForSaving(IDS_WTP_FILE_SAVEGAME);
+ Common::OutSaveFile *outfile = getSaveFileMan()->openForSaving(IDS_WTP_FILE_SAVEGAME);
if (!outfile)
return;
@@ -1157,20 +1206,20 @@ void Winnie::saveGame() {
outfile->writeUint32BE(MKTAG('W','I','N','N')); // header
outfile->writeByte(WTP_SAVEGAME_VERSION);
- outfile->writeByte(_game.fSound);
- outfile->writeByte(_game.nMoves);
- outfile->writeByte(_game.nObjMiss);
- outfile->writeByte(_game.nObjRet);
- outfile->writeByte(_game.iObjHave);
+ outfile->writeByte(_gameStateWinnie.fSound);
+ outfile->writeByte(_gameStateWinnie.nMoves);
+ outfile->writeByte(_gameStateWinnie.nObjMiss);
+ outfile->writeByte(_gameStateWinnie.nObjRet);
+ outfile->writeByte(_gameStateWinnie.iObjHave);
for (i = 0; i < IDI_WTP_MAX_FLAG; i++)
- outfile->writeByte(_game.fGame[i]);
+ outfile->writeByte(_gameStateWinnie.fGame[i]);
for (i = 0; i < IDI_WTP_MAX_OBJ_MISSING; i++)
- outfile->writeByte(_game.iUsedObj[i]);
+ outfile->writeByte(_gameStateWinnie.iUsedObj[i]);
for (i = 0; i < IDI_WTP_MAX_ROOM_OBJ; i++)
- outfile->writeByte(_game.iObjRoom[i]);
+ outfile->writeByte(_gameStateWinnie.iObjRoom[i]);
outfile->finalize();
@@ -1180,11 +1229,11 @@ void Winnie::saveGame() {
delete outfile;
}
-void Winnie::loadGame() {
+void WinnieEngine::loadGame() {
int saveVersion = 0;
int i = 0;
- Common::InSaveFile *infile = _vm->getSaveFileMan()->openForLoading(IDS_WTP_FILE_SAVEGAME);
+ Common::InSaveFile *infile = getSaveFileMan()->openForLoading(IDS_WTP_FILE_SAVEGAME);
if (!infile)
return;
@@ -1194,11 +1243,11 @@ void Winnie::loadGame() {
if (saveVersion != WTP_SAVEGAME_VERSION)
warning("Old save game version (%d, current version is %d). Will try and read anyway, but don't be surprised if bad things happen", saveVersion, WTP_SAVEGAME_VERSION);
- _game.fSound = infile->readByte();
- _game.nMoves = infile->readByte();
- _game.nObjMiss = infile->readByte();
- _game.nObjRet = infile->readByte();
- _game.iObjHave = infile->readByte();
+ _gameStateWinnie.fSound = infile->readByte();
+ _gameStateWinnie.nMoves = infile->readByte();
+ _gameStateWinnie.nObjMiss = infile->readByte();
+ _gameStateWinnie.nObjRet = infile->readByte();
+ _gameStateWinnie.iObjHave = infile->readByte();
} else {
// This is probably a save from the original interpreter, throw a warning and attempt
// to read it as LE
@@ -1211,31 +1260,31 @@ void Winnie::loadGame() {
infile->readUint16LE(); // skip unused field
infile->readByte(); // first 8 bits of fSound
- _game.fSound = infile->readByte();
+ _gameStateWinnie.fSound = infile->readByte();
infile->readByte(); // first 8 bits of nMoves
- _game.nMoves = infile->readByte();
+ _gameStateWinnie.nMoves = infile->readByte();
infile->readByte(); // first 8 bits of nObjMiss
- _game.nObjMiss = infile->readByte();
+ _gameStateWinnie.nObjMiss = infile->readByte();
infile->readByte(); // first 8 bits of nObjRet
- _game.nObjRet = infile->readByte();
+ _gameStateWinnie.nObjRet = infile->readByte();
infile->readUint16LE(); // skip unused field
infile->readUint16LE(); // skip unused field
infile->readUint16LE(); // skip unused field
infile->readByte(); // first 8 bits of iObjHave
- _game.iObjHave = infile->readByte();
+ _gameStateWinnie.iObjHave = infile->readByte();
infile->readUint16LE(); // skip unused field
infile->readUint16LE(); // skip unused field
infile->readUint16LE(); // skip unused field
}
for (i = 0; i < IDI_WTP_MAX_FLAG; i++)
- _game.fGame[i] = infile->readByte();
+ _gameStateWinnie.fGame[i] = infile->readByte();
for (i = 0; i < IDI_WTP_MAX_OBJ_MISSING; i++)
- _game.iUsedObj[i] = infile->readByte();
+ _gameStateWinnie.iUsedObj[i] = infile->readByte();
for (i = 0; i < IDI_WTP_MAX_ROOM_OBJ; i++)
- _game.iObjRoom[i] = infile->readByte();
+ _gameStateWinnie.iObjRoom[i] = infile->readByte();
// Note that saved games from the original interpreter have 2 more 16-bit fields here
// which are ignored
@@ -1243,37 +1292,59 @@ void Winnie::loadGame() {
delete infile;
}
-void Winnie::printStrWinnie(char *szMsg) {
- if (_vm->getPlatform() != Common::kPlatformAmiga)
- _vm->printStrXOR(szMsg);
+void WinnieEngine::printStrWinnie(char *szMsg) {
+ if (getPlatform() != Common::kPlatformAmiga)
+ printStrXOR(szMsg);
else
- _vm->printStr(szMsg);
+ printStr(szMsg);
}
// Console-related functions
-void Winnie::debugCurRoom() {
- _vm->_console->DebugPrintf("Current Room = %d\n", _room);
+void WinnieEngine::debugCurRoom() {
+ _console->DebugPrintf("Current Room = %d\n", _room);
+}
+
+WinnieEngine::WinnieEngine(OSystem *syst, const AGIGameDescription *gameDesc) : PreAgiEngine(syst, gameDesc) {
+ _console = new WinnieConsole(this);
}
-Winnie::Winnie(PreAgiEngine* vm) : _vm(vm) {
- _vm->_console = new Winnie_Console(_vm, this);
+WinnieEngine::~WinnieEngine() {
+ delete _console;
}
-void Winnie::init() {
- memset(&_game, 0, sizeof(_game));
- _game.fSound = 1;
- _game.nObjMiss = IDI_WTP_MAX_OBJ_MISSING;
- _game.nObjRet = 0;
- _game.fGame[0] = 1;
- _game.fGame[1] = 1;
+void WinnieEngine::init() {
+ // Initialize sound
+
+ switch (MidiDriver::getMusicType(MidiDriver::detectDevice(MDT_PCSPK|MDT_PCJR))) {
+ case MT_PCSPK:
+ _soundemu = SOUND_EMU_PC;
+ break;
+ case MT_PCJR:
+ _soundemu = SOUND_EMU_PCJR;
+ break;
+ default:
+ _soundemu = SOUND_EMU_NONE;
+ break;
+ }
+
+ _sound = new SoundMgr(this, _mixer);
+ _sound->initSound();
+ setflag(fSoundOn, true); // enable sound
+
+ memset(&_gameStateWinnie, 0, sizeof(_gameStateWinnie));
+ _gameStateWinnie.fSound = 1;
+ _gameStateWinnie.nObjMiss = IDI_WTP_MAX_OBJ_MISSING;
+ _gameStateWinnie.nObjRet = 0;
+ _gameStateWinnie.fGame[0] = 1;
+ _gameStateWinnie.fGame[1] = 1;
_room = IDI_WTP_ROOM_HOME;
_mist = -1;
_doWind = false;
_winnieEvent = false;
- if (_vm->getPlatform() != Common::kPlatformAmiga) {
+ if (getPlatform() != Common::kPlatformAmiga) {
_isBigEndian = false;
_roomOffset = IDI_WTP_OFS_ROOM;
_objOffset = IDI_WTP_OFS_OBJ;
@@ -1283,8 +1354,8 @@ void Winnie::init() {
_objOffset = 0;
}
- if (_vm->getPlatform() == Common::kPlatformC64 || _vm->getPlatform() == Common::kPlatformApple2GS)
- _vm->_picture->setPictureVersion(AGIPIC_C64);
+ if (getPlatform() == Common::kPlatformC64 || getPlatform() == Common::kPlatformApple2GS)
+ _picture->setPictureVersion(AGIPIC_C64);
hotspotNorth = Common::Rect(20, 0, (IDI_WTP_PIC_WIDTH + 10) * 2, 10);
hotspotSouth = Common::Rect(20, IDI_WTP_PIC_HEIGHT - 10, (IDI_WTP_PIC_WIDTH + 10) * 2, IDI_WTP_PIC_HEIGHT);
@@ -1292,11 +1363,17 @@ void Winnie::init() {
hotspotWest = Common::Rect(20, 0, 30, IDI_WTP_PIC_HEIGHT);
}
-void Winnie::run() {
+Common::Error WinnieEngine::go() {
+ init();
randomize();
- if (_vm->getPlatform() != Common::kPlatformC64 && _vm->getPlatform() != Common::kPlatformApple2GS)
+
+ // The intro is not supported on these platforms yet
+ if (getPlatform() != Common::kPlatformC64 && getPlatform() != Common::kPlatformApple2GS)
intro();
+
gameLoop();
-}
+ return Common::kNoError;
}
+
+} // End of namespace AGI
diff --git a/engines/agi/preagi_winnie.h b/engines/agi/preagi_winnie.h
index 07a1a13e2e..96ae65997e 100644
--- a/engines/agi/preagi_winnie.h
+++ b/engines/agi/preagi_winnie.h
@@ -281,19 +281,22 @@ struct WTP_SAVE_GAME {
class PreAgiEngine;
-class Winnie {
+class WinnieEngine : public PreAgiEngine {
public:
- Winnie(PreAgiEngine *vm);
+ WinnieEngine(OSystem *syst, const AGIGameDescription *gameDesc);
+ ~WinnieEngine();
void init();
- void run();
+ Common::Error go();
void debugCurRoom();
+ GUI::Debugger *getDebugger() { return _console; }
+
private:
- PreAgiEngine *_vm;
+ WinnieConsole *_console;
- WTP_SAVE_GAME _game;
+ WTP_SAVE_GAME _gameStateWinnie;
int _room;
int _mist;
bool _doWind;
diff --git a/engines/agi/saveload.cpp b/engines/agi/saveload.cpp
index f0d976bbbb..28dd0a53dd 100644
--- a/engines/agi/saveload.cpp
+++ b/engines/agi/saveload.cpp
@@ -474,8 +474,8 @@ int AgiEngine::loadGame(const char *fileName, bool checkId) {
v->cycleTimeCount = in->readByte();
v->direction = in->readByte();
- v->motion = in->readByte();
- v->cycle = in->readByte();
+ v->motion = (MotionType)in->readByte();
+ v->cycle = (CycleType)in->readByte();
v->priority = in->readByte();
v->flags = in->readUint16BE();
diff --git a/engines/agi/sound.cpp b/engines/agi/sound.cpp
index f2d7af32da..ca3d799ecc 100644
--- a/engines/agi/sound.cpp
+++ b/engines/agi/sound.cpp
@@ -41,6 +41,10 @@ AgiSound *AgiSound::createFromRawResource(uint8 *data, uint32 len, int resnum, S
return NULL;
uint16 type = READ_LE_UINT16(data);
+ // For V1 sound resources
+ if (type != AGI_SOUND_SAMPLE && (type & 0xFF) == 0x01)
+ return new PCjrSound(data, len, resnum, manager);
+
switch (type) { // Create a sound object based on the type
case AGI_SOUND_SAMPLE:
return new IIgsSample(data, len, resnum, manager);
@@ -62,6 +66,11 @@ PCjrSound::PCjrSound(uint8 *data, uint32 len, int resnum, SoundMgr &manager) : A
_data = data; // Save the resource pointer
_len = len; // Save the resource's length
_type = READ_LE_UINT16(data); // Read sound resource's type
+
+ // Detect V1 sound resources
+ if ((_type & 0xFF) == 0x01)
+ _type = AGI_SOUND_4CHN;
+
_isValid = (_type == AGI_SOUND_4CHN) && (_data != NULL) && (_len >= 2);
if (!_isValid) // Check for errors
@@ -127,7 +136,12 @@ void SoundMgr::startSound(int resnum, int flag) {
// Reset the flag
_endflag = flag;
- _vm->setflag(_endflag, false);
+
+ if (_vm->getVersion() < 0x2000) {
+ _vm->_game.vars[_endflag] = 0;
+ } else {
+ _vm->setflag(_endflag, false);
+ }
}
void SoundMgr::stopSound() {
@@ -142,8 +156,13 @@ void SoundMgr::stopSound() {
// This is probably not needed most of the time, but there also should
// not be any harm doing it, so do it anyway.
- if (_endflag != -1)
- _vm->setflag(_endflag, true);
+ if (_endflag != -1) {
+ if (_vm->getVersion() < 0x2000) {
+ _vm->_game.vars[_endflag] = 1;
+ } else {
+ _vm->setflag(_endflag, true);
+ }
+ }
_endflag = -1;
}
@@ -168,7 +187,7 @@ void SoundMgr::soundIsFinished() {
_endflag = -1;
}
-SoundMgr::SoundMgr(AgiEngine *agi, Audio::Mixer *pMixer) {
+SoundMgr::SoundMgr(AgiBase *agi, Audio::Mixer *pMixer) {
_vm = agi;
_endflag = -1;
_playingSound = -1;
diff --git a/engines/agi/sound.h b/engines/agi/sound.h
index 0ee19878c4..6fd8dd516e 100644
--- a/engines/agi/sound.h
+++ b/engines/agi/sound.h
@@ -71,7 +71,7 @@ class SoundMgr;
class SoundGen {
public:
- SoundGen(AgiEngine *vm, Audio::Mixer *pMixer) : _vm(vm), _mixer(pMixer) {
+ SoundGen(AgiBase *vm, Audio::Mixer *pMixer) : _vm(vm), _mixer(pMixer) {
_sampleRate = pMixer->getOutputRate();
}
@@ -80,7 +80,7 @@ public:
virtual void play(int resnum) = 0;
virtual void stop(void) = 0;
- AgiEngine *_vm;
+ AgiBase *_vm;
Audio::Mixer *_mixer;
Audio::SoundHandle _soundHandle;
@@ -122,6 +122,8 @@ public:
~PCjrSound() { free(_data); }
virtual uint16 type() { return _type; }
const uint8 *getVoicePointer(uint voiceNum);
+ uint8 *getData() { return _data; }
+ uint32 getLength() { return _len; }
protected:
uint8 *_data; ///< Raw sound resource data
uint32 _len; ///< Length of the raw sound resource
@@ -131,7 +133,7 @@ protected:
class SoundMgr {
public:
- SoundMgr(AgiEngine *agi, Audio::Mixer *pMixer);
+ SoundMgr(AgiBase *agi, Audio::Mixer *pMixer);
~SoundMgr();
void setVolume(uint8 volume);
@@ -147,7 +149,7 @@ public:
private:
int _endflag;
- AgiEngine *_vm;
+ AgiBase *_vm;
SoundGen *_soundGen;
diff --git a/engines/agi/sound_2gs.cpp b/engines/agi/sound_2gs.cpp
index 38e256aa4b..c5cfa125d6 100644
--- a/engines/agi/sound_2gs.cpp
+++ b/engines/agi/sound_2gs.cpp
@@ -33,7 +33,7 @@
namespace Agi {
-SoundGen2GS::SoundGen2GS(AgiEngine *vm, Audio::Mixer *pMixer) : SoundGen(vm, pMixer) {
+SoundGen2GS::SoundGen2GS(AgiBase *vm, Audio::Mixer *pMixer) : SoundGen(vm, pMixer) {
// Allocate memory for the wavetable
_wavetable = new int8[SIERRASTANDARD_SIZE];
diff --git a/engines/agi/sound_2gs.h b/engines/agi/sound_2gs.h
index 9123e18415..89ffc3fe11 100644
--- a/engines/agi/sound_2gs.h
+++ b/engines/agi/sound_2gs.h
@@ -215,7 +215,7 @@ private:
class SoundGen2GS : public SoundGen, public Audio::AudioStream {
public:
- SoundGen2GS(AgiEngine *vm, Audio::Mixer *pMixer);
+ SoundGen2GS(AgiBase *vm, Audio::Mixer *pMixer);
~SoundGen2GS();
void play(int resnum);
diff --git a/engines/agi/sound_coco3.cpp b/engines/agi/sound_coco3.cpp
index 281f2cb2d4..64818e4e34 100644
--- a/engines/agi/sound_coco3.cpp
+++ b/engines/agi/sound_coco3.cpp
@@ -34,7 +34,7 @@ static int cocoFrequencies[] = {
2093, 2217, 2349, 2489, 2637, 2793, 2959, 3135, 3322, 3520, 3729, 3951
};
-SoundGenCoCo3::SoundGenCoCo3(AgiEngine *vm, Audio::Mixer *pMixer) : SoundGen(vm, pMixer) {
+SoundGenCoCo3::SoundGenCoCo3(AgiBase *vm, Audio::Mixer *pMixer) : SoundGen(vm, pMixer) {
}
SoundGenCoCo3::~SoundGenCoCo3() {
diff --git a/engines/agi/sound_coco3.h b/engines/agi/sound_coco3.h
index 7058b770f5..d24acf5cc5 100644
--- a/engines/agi/sound_coco3.h
+++ b/engines/agi/sound_coco3.h
@@ -42,7 +42,7 @@ struct CoCoNote {
class SoundGenCoCo3 : public SoundGen, public Audio::AudioStream {
public:
- SoundGenCoCo3(AgiEngine *vm, Audio::Mixer *pMixer);
+ SoundGenCoCo3(AgiBase *vm, Audio::Mixer *pMixer);
~SoundGenCoCo3();
void play(int resnum);
diff --git a/engines/agi/sound_midi.cpp b/engines/agi/sound_midi.cpp
index 0cbaa4af86..47d354093b 100644
--- a/engines/agi/sound_midi.cpp
+++ b/engines/agi/sound_midi.cpp
@@ -69,7 +69,7 @@ MIDISound::MIDISound(uint8 *data, uint32 len, int resnum, SoundMgr &manager) : A
warning("Error creating MIDI sound from resource %d (Type %d, length %d)", resnum, _type, len);
}
-SoundGenMIDI::SoundGenMIDI(AgiEngine *vm, Audio::Mixer *pMixer) : SoundGen(vm, pMixer), _isGM(false) {
+SoundGenMIDI::SoundGenMIDI(AgiBase *vm, Audio::Mixer *pMixer) : SoundGen(vm, pMixer), _isGM(false) {
MidiPlayer::createDriver(MDT_MIDI | MDT_ADLIB);
int ret = _driver->open();
diff --git a/engines/agi/sound_midi.h b/engines/agi/sound_midi.h
index 92a4002498..36bd66ee76 100644
--- a/engines/agi/sound_midi.h
+++ b/engines/agi/sound_midi.h
@@ -45,7 +45,7 @@ protected:
class SoundGenMIDI : public SoundGen, public Audio::MidiPlayer {
public:
- SoundGenMIDI(AgiEngine *vm, Audio::Mixer *pMixer);
+ SoundGenMIDI(AgiBase *vm, Audio::Mixer *pMixer);
void play(int resnum);
// We must overload stop() here to implement the pure virtual
diff --git a/engines/agi/sound_pcjr.cpp b/engines/agi/sound_pcjr.cpp
index fdebf16b1a..d21baa450f 100644
--- a/engines/agi/sound_pcjr.cpp
+++ b/engines/agi/sound_pcjr.cpp
@@ -102,7 +102,7 @@ const int8 dissolveDataV3[] = {
};
-SoundGenPCJr::SoundGenPCJr(AgiEngine *vm, Audio::Mixer *pMixer) : SoundGen(vm, pMixer) {
+SoundGenPCJr::SoundGenPCJr(AgiBase *vm, Audio::Mixer *pMixer) : SoundGen(vm, pMixer) {
_chanAllocated = 10240; // preallocate something which will most likely fit
_chanData = (int16 *)malloc(_chanAllocated << 1);
@@ -126,6 +126,9 @@ SoundGenPCJr::SoundGenPCJr(AgiEngine *vm, Audio::Mixer *pMixer) : SoundGen(vm, p
memset(_tchannel, 0, sizeof(_tchannel));
_mixer->playStream(Audio::Mixer::kMusicSoundType, &_soundHandle, this, -1, Audio::Mixer::kMaxChannelVolume, 0, DisposeAfterUse::NO, true);
+
+ _v1data = NULL;
+ _v1size = 0;
}
SoundGenPCJr::~SoundGenPCJr() {
@@ -153,6 +156,9 @@ void SoundGenPCJr::play(int resnum) {
_tchannel[i].genType = kGenTone;
_tchannel[i].genTypePrev = -1;
}
+
+ _v1data = pcjrSound->getData() + 1;
+ _v1size = pcjrSound->getLength() - 1;
}
void SoundGenPCJr::stop(void) {
@@ -201,7 +207,7 @@ int SoundGenPCJr::volumeCalc(SndGenChan *chan) {
chan->attenuationCopy = attenuation;
attenuation &= 0x0F;
- attenuation += _vm->getvar(vVolume);
+ attenuation += _mixer->getVolumeForSoundType(Audio::Mixer::kSFXSoundType) / 17;
if (attenuation > 0x0F)
attenuation = 0x0F;
}
@@ -214,16 +220,25 @@ int SoundGenPCJr::volumeCalc(SndGenChan *chan) {
return attenuation;
}
+int SoundGenPCJr::getNextNote(int ch)
+{
+ if (_vm->getVersion() > 0x2001)
+ return getNextNote_v2(ch);
+ else
+ return getNextNote_v1(ch);
+
+ return -1;
+}
+
// read the next channel data.. fill it in *tone
// if tone isn't touched.. it should be inited so it just plays silence
// return 0 if it's passing more data
// return -1 if it's passing nothing (end of data)
-int SoundGenPCJr::getNextNote(int ch, Tone *tone) {
+int SoundGenPCJr::getNextNote_v2(int ch) {
ToneChan *tpcm;
SndGenChan *chan;
const byte *data;
- assert(tone);
assert(ch < CHAN_MAX);
if (!_vm->getflag(fSoundOn))
@@ -234,7 +249,7 @@ int SoundGenPCJr::getNextNote(int ch, Tone *tone) {
if (!chan->avail)
return -1;
- while ((chan->duration == 0) && (chan->duration != 0xFFFF)) {
+ while (chan->duration <= 0) {
data = chan->data;
// read the duration of the note
@@ -242,58 +257,32 @@ int SoundGenPCJr::getNextNote(int ch, Tone *tone) {
// if it's 0 then it's not going to be played
// if it's 0xFFFF then the channel data has finished.
- if ((chan->duration != 0) && (chan->duration != 0xFFFF)) {
+ if ((chan->duration == 0) || (chan->duration == 0xFFFF)) {
tpcm->genTypePrev = -1;
tpcm->freqCountPrev = -1;
- // only tone channels dissolve
- if ((ch != 3) && (_dissolveMethod != 0)) // != noise??
- chan->dissolveCount = 0;
+ break;
+ }
- // attenuation (volume)
- chan->attenuation = data[4] & 0xF;
+ _tchannel[ch].genTypePrev = -1;
+ _tchannel[ch].freqCountPrev = -1;
- // frequency
- if (ch < (CHAN_MAX - 1)) {
- chan->freqCount = (uint16)data[2] & 0x3F;
- chan->freqCount <<= 4;
- chan->freqCount |= data[3] & 0x0F;
+ // only tone channels dissolve
+ if ((ch != 3) && (_dissolveMethod != 0)) // != noise??
+ chan->dissolveCount = 0;
+
+ // attenuation (volume)
+ writeData(data[4]);
+
+ // frequency
+ writeData(data[3]);
+ writeData(data[2]);
- chan->genType = kGenTone;
- } else {
- int noiseFreq;
-
- // check for white noise (1) or periodic (0)
- chan->genType = (data[3] & 0x04) ? kGenWhite : kGenPeriod;
-
- noiseFreq = data[3] & 0x03;
-
- switch (noiseFreq) {
- case 0:
- chan->freqCount = 32;
- break;
- case 1:
- chan->freqCount = 64;
- break;
- case 2:
- chan->freqCount = 128;
- break;
- case 3:
- chan->freqCount = _channel[2].freqCount * 2;
- break;
- }
- }
- }
// data now points to the next data seg-a-ment
chan->data += 5;
}
- if (chan->duration != 0xFFFF) {
- tone->freqCount = chan->freqCount;
- tone->atten = volumeCalc(chan); // calc volume, sent vol is different from saved vol
- tone->type = chan->genType;
- chan->duration--;
- } else {
+ if (chan->duration == 0xFFFF) {
// kill channel
chan->avail = 0;
chan->attenuation = 0x0F; // silent
@@ -302,9 +291,80 @@ int SoundGenPCJr::getNextNote(int ch, Tone *tone) {
return -1;
}
+ chan->duration--;
+
return 0;
}
+int SoundGenPCJr::getNextNote_v1(int ch) {
+ static int duration = 0;
+
+ byte *data = _v1data;
+ uint32 len = _v1size;
+
+ if (len <= 0 || data == NULL) {
+ _channel[ch].avail = 0;
+ _channel[ch].attenuation = 0x0F;
+ _channel[ch].attenuationCopy = 0x0F;
+ return -1;
+ }
+
+ // In the V1 player the default duration for a row is 3 ticks
+ if (duration > 0) {
+ duration--;
+ return 0;
+ }
+ duration = 3 * CHAN_MAX;
+
+ // Otherwise fetch a row of data for all channels
+ while (*data) {
+ writeData(*data);
+ data++;
+ len--;
+ }
+ data++;
+ len--;
+
+ _v1data = data;
+ _v1size = len;
+
+ return 0;
+}
+
+void SoundGenPCJr::writeData(uint8 val) {
+ static int reg = 0;
+
+ debugC(5, kDebugLevelSound, "writeData(%.2X)", val);
+
+ if ((val & 0x90) == 0x90) {
+ reg = (val >> 5) & 0x3;
+ _channel[reg].attenuation = val & 0xF;
+ } else if ((val & 0xF0) == 0xE0) {
+ _channel[3].genType = (val & 0x4) ? kGenWhite : kGenPeriod;
+ int noiseFreq = val & 0x03;
+ switch (noiseFreq) {
+ case 0:
+ _channel[3].freqCount = 32;
+ break;
+ case 1:
+ _channel[3].freqCount = 64;
+ break;
+ case 2:
+ _channel[3].freqCount = 128;
+ break;
+ case 3:
+ _channel[3].freqCount = _channel[2].freqCount * 2;
+ break;
+ }
+ } else if (val & 0x80) {
+ reg = (val >> 5) & 0x3;
+ _channel[reg].freqCount = val & 0xF;
+ _channel[reg].genType = kGenTone;
+ } else {
+ _channel[reg].freqCount |= (val & 0x3F) << 4;
+ }
+}
+
// Formulas for noise generator
// bit0 = output
@@ -340,7 +400,6 @@ const int16 volTable[16] = {
// fill buff
int SoundGenPCJr::chanGen(int chan, int16 *stream, int len) {
ToneChan *tpcm;
- Tone toneNew;
int fillSize;
int retVal;
@@ -351,13 +410,10 @@ int SoundGenPCJr::chanGen(int chan, int16 *stream, int len) {
while (len > 0) {
if (tpcm->noteCount <= 0) {
// get new tone data
- toneNew.freqCount = 0;
- toneNew.atten = 0xF;
- toneNew.type = kGenTone;
- if ((tpcm->avail) && (getNextNote(chan, &toneNew) == 0)) {
- tpcm->atten = toneNew.atten;
- tpcm->freqCount = toneNew.freqCount;
- tpcm->genType = toneNew.type;
+ if ((tpcm->avail) && (getNextNote(chan) == 0)) {
+ tpcm->atten = _channel[chan].attenuation;
+ tpcm->freqCount = _channel[chan].freqCount;
+ tpcm->genType = _channel[chan].genType;
// setup counters 'n stuff
// SAMPLE_RATE samples per sec.. tone changes 60 times per sec
diff --git a/engines/agi/sound_pcjr.h b/engines/agi/sound_pcjr.h
index 4317e86516..1b4d1e9efb 100644
--- a/engines/agi/sound_pcjr.h
+++ b/engines/agi/sound_pcjr.h
@@ -71,15 +71,9 @@ struct ToneChan {
int feedback; /* noise feedback mask */
};
-struct Tone {
- int freqCount;
- int atten;
- GenType type;
-};
-
class SoundGenPCJr : public SoundGen, public Audio::AudioStream {
public:
- SoundGenPCJr(AgiEngine *vm, Audio::Mixer *pMixer);
+ SoundGenPCJr(AgiBase *vm, Audio::Mixer *pMixer);
~SoundGenPCJr();
void play(int resnum);
@@ -102,9 +96,13 @@ public:
}
private:
- int getNextNote(int ch, Tone *tone);
+ int getNextNote(int ch);
+ int getNextNote_v2(int ch);
+ int getNextNote_v1(int ch);
int volumeCalc(SndGenChan *chan);
+ void writeData(uint8 val);
+
int chanGen(int chan, int16 *stream, int len);
int fillNoise(ToneChan *t, int16 *buf, int len);
@@ -117,6 +115,9 @@ private:
int _chanAllocated;
int _dissolveMethod;
+
+ uint8 *_v1data;
+ uint32 _v1size;
};
} // End of namespace Agi
diff --git a/engines/agi/sound_sarien.cpp b/engines/agi/sound_sarien.cpp
index 9ea8569b81..a2baf89d12 100644
--- a/engines/agi/sound_sarien.cpp
+++ b/engines/agi/sound_sarien.cpp
@@ -65,7 +65,7 @@ static const int16 waveformMac[WAVEFORM_SIZE] = {
-175, -172, -165, -159, -137, -114, -67, -19
};
-SoundGenSarien::SoundGenSarien(AgiEngine *vm, Audio::Mixer *pMixer) : SoundGen(vm, pMixer), _chn() {
+SoundGenSarien::SoundGenSarien(AgiBase *vm, Audio::Mixer *pMixer) : SoundGen(vm, pMixer), _chn() {
_sndBuffer = (int16 *)calloc(2, BUFFER_SIZE);
memset(_sndBuffer, 0, BUFFER_SIZE << 1);
diff --git a/engines/agi/sound_sarien.h b/engines/agi/sound_sarien.h
index 22bfff3395..04f274ca7d 100644
--- a/engines/agi/sound_sarien.h
+++ b/engines/agi/sound_sarien.h
@@ -68,7 +68,7 @@ struct ChannelInfo {
class SoundGenSarien : public SoundGen, public Audio::AudioStream {
public:
- SoundGenSarien(AgiEngine *vm, Audio::Mixer *pMixer);
+ SoundGenSarien(AgiBase *vm, Audio::Mixer *pMixer);
~SoundGenSarien();
void play(int resnum);
diff --git a/engines/agi/sprite.cpp b/engines/agi/sprite.cpp
index ea0b07f4da..cec0895073 100644
--- a/engines/agi/sprite.cpp
+++ b/engines/agi/sprite.cpp
@@ -257,7 +257,7 @@ bool SpritesMgr::testUpdating(VtEntry *v, AgiEngine *agi) {
if (~agi->_game.dirView[v->currentView].flags & RES_LOADED)
return false;
- return (v->flags & (ANIMATED | UPDATE | DRAWN)) == (ANIMATED | UPDATE | DRAWN);
+ return (v->flags & (fAnimated | fUpdate | fDrawn)) == (fAnimated | fUpdate | fDrawn);
}
/**
@@ -268,7 +268,7 @@ bool SpritesMgr::testNotUpdating(VtEntry *v, AgiEngine *vm) {
if (~vm->_game.dirView[v->currentView].flags & RES_LOADED)
return false;
- return (v->flags & (ANIMATED | UPDATE | DRAWN)) == (ANIMATED | DRAWN);
+ return (v->flags & (fAnimated | fUpdate | fDrawn)) == (fAnimated | fDrawn);
}
/**
@@ -332,7 +332,7 @@ void SpritesMgr::buildList(SpriteList &l, bool (*test)(VtEntry *, AgiEngine *))
for (v = _vm->_game.viewTable; v < &_vm->_game.viewTable[MAX_VIEWTABLE]; v++) {
if ((*test)(v, _vm)) {
entry[i] = v;
- yVal[i] = v->flags & FIXED_PRIORITY ? prioToY(v->priority) : v->yPos;
+ yVal[i] = v->flags & fFixedPriority ? prioToY(v->priority) : v->yPos;
i++;
}
}
@@ -407,13 +407,13 @@ void SpritesMgr::commitSprites(SpriteList &l, bool immediate) {
continue;
if (s->v->xPos == s->v->xPos2 && s->v->yPos == s->v->yPos2) {
- s->v->flags |= DIDNT_MOVE;
+ s->v->flags |= fDidntMove;
continue;
}
s->v->xPos2 = s->v->xPos;
s->v->yPos2 = s->v->yPos;
- s->v->flags &= ~DIDNT_MOVE;
+ s->v->flags &= ~fDidntMove;
}
}
@@ -604,7 +604,9 @@ void SpritesMgr::addToPic(int view, int loop, int cel, int x, int y, int pri, in
// If margin is 0, 1, 2, or 3, the base of the cel is
// surrounded with a rectangle of the corresponding priority.
// If margin >= 4, this extra margin is not shown.
- if (mar < 4) {
+ //
+ // -1 indicates ignore and is set for V1
+ if (mar < 4 && mar != -1) {
// add rectangle around object, don't clobber control
// info in priority data. The box extends to the end of
// its priority band!
diff --git a/engines/agi/view.cpp b/engines/agi/view.cpp
index 0d420caa81..3f3686561e 100644
--- a/engines/agi/view.cpp
+++ b/engines/agi/view.cpp
@@ -47,7 +47,7 @@ void AgiEngine::lSetCel(VtEntry *v, int n) {
// in the KQ4 introduction
// It seems there's either a bug with KQ4's logic script 120 (the intro script)
// or flag 64 is not set correctly, which causes the erroneous behavior from the actors
- if (getGameID() == GID_KQ4 && !(v->flags & UPDATE) && (v->currentView == 172))
+ if (getGameID() == GID_KQ4 && !(v->flags & fUpdate) && (v->currentView == 172))
return;
currentVc = &currentVl->cel[n];
@@ -78,8 +78,8 @@ void AgiEngine::lSetLoop(VtEntry *v, int n) {
void AgiEngine::updateView(VtEntry *v) {
int cel, lastCel;
- if (v->flags & DONTUPDATE) {
- v->flags &= ~DONTUPDATE;
+ if (v->flags & fDontupdate) {
+ v->flags &= ~fDontupdate;
return;
}
@@ -87,32 +87,32 @@ void AgiEngine::updateView(VtEntry *v) {
lastCel = v->numCels - 1;
switch (v->cycle) {
- case CYCLE_NORMAL:
+ case kCycleNormal:
if (++cel > lastCel)
cel = 0;
break;
- case CYCLE_END_OF_LOOP:
+ case kCycleEndOfLoop:
if (cel < lastCel) {
debugC(5, kDebugLevelResources, "cel %d (last = %d)", cel + 1, lastCel);
if (++cel != lastCel)
break;
}
setflag(v->parm1, true);
- v->flags &= ~CYCLING;
+ v->flags &= ~fCycling;
v->direction = 0;
- v->cycle = CYCLE_NORMAL;
+ v->cycle = kCycleNormal;
break;
- case CYCLE_REV_LOOP:
+ case kCycleRevLoop:
if (cel) {
if (--cel)
break;
}
setflag(v->parm1, true);
- v->flags &= ~CYCLING;
+ v->flags &= ~fCycling;
v->direction = 0;
- v->cycle = CYCLE_NORMAL;
+ v->cycle = kCycleNormal;
break;
- case CYCLE_REVERSE:
+ case kCycleReverse:
if (cel == 0) {
cel = lastCel;
} else {
@@ -259,17 +259,22 @@ void AgiEngine::setCel(VtEntry *v, int n) {
*/
void AgiEngine::clipViewCoordinates(VtEntry *v) {
if (v->xPos + v->xSize > _WIDTH) {
- v->flags |= UPDATE_POS;
+ v->flags |= fUpdatePos;
v->xPos = _WIDTH - v->xSize;
}
if (v->yPos - v->ySize + 1 < 0) {
- v->flags |= UPDATE_POS;
+ v->flags |= fUpdatePos;
v->yPos = v->ySize - 1;
}
- if (v->yPos <= _game.horizon && (~v->flags & IGNORE_HORIZON)) {
- v->flags |= UPDATE_POS;
+ if (v->yPos <= _game.horizon && (~v->flags & fIgnoreHorizon)) {
+ v->flags |= fUpdatePos;
v->yPos = _game.horizon + 1;
}
+
+ if (getVersion() < 0x2000) {
+ v->flags |= fDontupdate;
+ }
+
}
/**
@@ -294,6 +299,12 @@ void AgiEngine::setView(VtEntry *v, int n) {
v->currentView = n;
v->numLoops = v->viewData->numLoops;
v->viewReplaced = true;
+
+ if (getVersion() < 0x2000) {
+ v->stepSize = v->viewData->rdata[0];
+ v->cycleTime = v->viewData->rdata[1];
+ v->cycleTimeCount = 0;
+ }
setLoop(v, v->currentLoop >= v->numLoops ? 0 : v->currentLoop);
}
@@ -302,10 +313,10 @@ void AgiEngine::setView(VtEntry *v, int n) {
* @param v pointer to view table entry
*/
void AgiEngine::startUpdate(VtEntry *v) {
- if (~v->flags & UPDATE) {
+ if (~v->flags & fUpdate) {
_sprites->eraseBoth();
- v->flags |= UPDATE;
+ v->flags |= fUpdate;
_sprites->blitBoth();
_sprites->commitBoth();
}
@@ -316,10 +327,10 @@ void AgiEngine::startUpdate(VtEntry *v) {
* @param v pointer to view table entry
*/
void AgiEngine::stopUpdate(VtEntry *v) {
- if (v->flags & UPDATE) {
+ if (v->flags & fUpdate) {
_sprites->eraseBoth();
- v->flags &= ~UPDATE;
+ v->flags &= ~fUpdate;
_sprites->blitBoth();
_sprites->commitBoth();
}
@@ -346,14 +357,14 @@ void AgiEngine::updateViewtable() {
i = 0;
for (v = _game.viewTable; v < &_game.viewTable[MAX_VIEWTABLE]; v++) {
- if ((v->flags & (ANIMATED | UPDATE | DRAWN)) != (ANIMATED | UPDATE | DRAWN)) {
+ if ((v->flags & (fAnimated | fUpdate | fDrawn)) != (fAnimated | fUpdate | fDrawn)) {
continue;
}
i++;
loop = 4;
- if (~v->flags & FIX_LOOP) {
+ if (~v->flags & fFixLoop) {
switch (v->numLoops) {
case 2:
case 3:
@@ -378,7 +389,7 @@ void AgiEngine::updateViewtable() {
}
}
- if (~v->flags & CYCLING)
+ if (~v->flags & fCycling)
continue;
if (v->cycleTimeCount == 0)
@@ -395,7 +406,7 @@ void AgiEngine::updateViewtable() {
updatePosition();
_sprites->blitUpdSprites();
_sprites->commitUpdSprites();
- _game.viewTable[0].flags &= ~(ON_WATER | ON_LAND);
+ _game.viewTable[0].flags &= ~(fOnWater | fOnLand);
}
}
diff --git a/engines/agi/view.h b/engines/agi/view.h
index 0ef443f8e5..5cf59d7df5 100644
--- a/engines/agi/view.h
+++ b/engines/agi/view.h
@@ -50,6 +50,39 @@ struct AgiView {
uint8 *rdata;
};
+enum MotionType {
+ kMotionNormal = 0,
+ kMotionWander = 1,
+ kMotionFollowEgo = 2,
+ kMotionMoveObj = 3
+};
+
+enum CycleType {
+ kCycleNormal = 0,
+ kCycleEndOfLoop = 1,
+ kCycleRevLoop = 2,
+ kCycleReverse = 3
+ };
+
+enum ViewFlags {
+ fDrawn = (1 << 0),
+ fIgnoreBlocks = (1 << 1),
+ fFixedPriority = (1 << 2),
+ fIgnoreHorizon = (1 << 3),
+ fUpdate = (1 << 4),
+ fCycling = (1 << 5),
+ fAnimated = (1 << 6),
+ fMotion = (1 << 7),
+ fOnWater = (1 << 8),
+ fIgnoreObjects = (1 << 9),
+ fUpdatePos = (1 << 10),
+ fOnLand = (1 << 11),
+ fDontupdate = (1 << 12),
+ fFixLoop = (1 << 13),
+ fDidntMove = (1 << 14),
+ fAdjEgoXY = (1 << 15)
+};
+
/**
* AGI view table entry
*/
@@ -78,39 +111,10 @@ struct VtEntry {
uint8 cycleTime;
uint8 cycleTimeCount;
uint8 direction;
-
-#define MOTION_NORMAL 0
-#define MOTION_WANDER 1
-#define MOTION_FOLLOW_EGO 2
-#define MOTION_MOVE_OBJ 3
- uint8 motion;
-
-#define CYCLE_NORMAL 0
-#define CYCLE_END_OF_LOOP 1
-#define CYCLE_REV_LOOP 2
-#define CYCLE_REVERSE 3
- uint8 cycle;
-
+ MotionType motion;
+ CycleType cycle;
uint8 priority;
-
-#define DRAWN 0x0001
-#define IGNORE_BLOCKS 0x0002
-#define FIXED_PRIORITY 0x0004
-#define IGNORE_HORIZON 0x0008
-#define UPDATE 0x0010
-#define CYCLING 0x0020
-#define ANIMATED 0x0040
-#define MOTION 0x0080
-#define ON_WATER 0x0100
-#define IGNORE_OBJECTS 0x0200
-#define UPDATE_POS 0x0400
-#define ON_LAND 0x0800
-#define DONTUPDATE 0x1000
-#define FIX_LOOP 0x2000
-#define DIDNT_MOVE 0x4000
-#define ADJ_EGO_XY 0x8000
uint16 flags;
-
uint8 parm1;
uint8 parm2;
uint8 parm3;
diff --git a/engines/agi/words.cpp b/engines/agi/words.cpp
index 4b96fdf711..ec6928f8ed 100644
--- a/engines/agi/words.cpp
+++ b/engines/agi/words.cpp
@@ -20,19 +20,12 @@
*
*/
-//
-// New find_word algorithm by Thomas Akesson <tapilot@home.se>
-//
-
#include "agi/agi.h"
#include "common/textconsole.h"
namespace Agi {
-static uint8 *words; // words in the game
-static uint32 wordsFlen; // length of word memory
-
//
// Local implementation to avoid problems with strndup() used by
// gcc 3.2 Cygwin (see #635984)
@@ -43,12 +36,38 @@ static char *myStrndup(const char *src, int n) {
return tmp;
}
+int AgiEngine::loadWords_v1(Common::File &f) {
+ char str[64];
+ int k;
+
+ debug(0, "Loading dictionary");
+
+ // Loop through alphabet, as words in the dictionary file are sorted by
+ // first character
+ f.seek(f.pos() + 26 * 2, SEEK_SET);
+ do {
+ // Read next word
+ for (k = 0; k < (int)sizeof(str) - 1; k++) {
+ str[k] = f.readByte();
+ if (str[k] == 0 || (uint8)str[k] == 0xFF)
+ break;
+ }
+
+ // And store it in our internal dictionary
+ if (k > 0) {
+ AgiWord *w = new AgiWord;
+ w->word = myStrndup(str, k + 1);
+ w->id = f.readUint16LE();
+ _game.words[str[0] - 'a'].push_back(w);
+ debug(3, "'%s' (%d)", w->word, w->id);
+ }
+ } while((uint8)str[0] != 0xFF);
+
+ return errOK;
+}
+
int AgiEngine::loadWords(const char *fname) {
Common::File fp;
- uint32 flen;
- uint8 *mem = NULL;
-
- words = NULL;
if (!fp.open(fname)) {
warning("loadWords: can't open %s", fname);
@@ -56,85 +75,70 @@ int AgiEngine::loadWords(const char *fname) {
}
debug(0, "Loading dictionary: %s", fname);
- fp.seek(0, SEEK_END);
- flen = fp.pos();
- wordsFlen = flen;
- fp.seek(0, SEEK_SET);
-
- if ((mem = (uint8 *)calloc(1, flen + 32)) == NULL) {
- fp.close();
- return errNotEnoughMemory;
+ // Loop through alphabet, as words in the dictionary file are sorted by
+ // first character
+ for (int i = 0; i < 26; i++) {
+ fp.seek(i * 2, SEEK_SET);
+ int offset = fp.readUint16BE();
+ if (offset == 0)
+ continue;
+ fp.seek(offset, SEEK_SET);
+ int k = fp.readByte();
+ while (!fp.eos() && !fp.err()) {
+ // Read next word
+ char c, str[64];
+ do {
+ c = fp.readByte();
+ str[k++] = (c ^ 0x7F) & 0x7F;
+ } while (!(c & 0x80) && k < (int)sizeof(str) - 1);
+ str[k] = 0;
+
+ // And store it in our internal dictionary
+ AgiWord *w = new AgiWord;
+ w->word = myStrndup(str, k);
+ w->id = fp.readUint16BE();
+ _game.words[i].push_back(w);
+
+ // Are there more words with an already known prefix?
+ if (!(k = fp.readByte()))
+ break;
+ }
}
- fp.read(mem, flen);
- fp.close();
-
- words = mem;
-
return errOK;
}
void AgiEngine::unloadWords() {
- free(words);
- words = NULL;
+ for (int i = 0; i < 26; i++)
+ _game.words[i].clear();
}
/**
* Find a word in the dictionary
* Uses an algorithm hopefully like the one Sierra used. Returns the ID
* of the word and the length in flen. Returns -1 if not found.
- *
- * Thomas Akesson, November 2001
*/
int AgiEngine::findWord(const char *word, int *flen) {
- int mchr = 0; // matched chars
- int len, fchr, id = -1;
- const uint8 *p = words;
- const uint8 *q = words + wordsFlen;
- *flen = 0;
+ int c;
debugC(2, kDebugLevelScripts, "find_word(%s)", word);
if (word[0] >= 'a' && word[0] <= 'z')
- fchr = word[0] - 'a';
+ c = word[0] - 'a';
else
return -1;
- len = strlen(word);
-
- // Get the offset to the first word beginning with the
- // right character
- p += READ_BE_UINT16(p + 2 * fchr);
-
- while (p[0] >= mchr) {
- if (p[0] == mchr) {
- p++;
- // Loop through all matching characters
- while ((p[0] ^ word[mchr]) == 0x7F && mchr < len) {
- mchr++;
- p++;
- }
- // Check if this is the last character of the word
- // and if it matches
- if ((p[0] ^ word[mchr]) == 0xFF && mchr < len) {
- mchr++;
- if (word[mchr] == 0 || word[mchr] == 0x20) {
- id = READ_BE_UINT16(p + 1);
- *flen = mchr;
- }
- }
+ *flen = 0;
+ Common::Array<AgiWord*> &a = _game.words[c];
+ for (int i = 0; i < (int)a.size(); i++) {
+ int wlen = strlen(a[i]->word);
+ if (!strncmp(a[i]->word, word, wlen) && (word[wlen] == 0 || word[wlen] == 0x20)) {
+ *flen = wlen;
+ return a[i]->id;
}
- if (p >= q)
- return -1;
-
- // Step to the next word
- while (p[0] < 0x80)
- p++;
-
- p += 3;
}
- return id;
+ return -1;
}
void AgiEngine::dictionaryWords(char *msg) {
diff --git a/engines/agos/detection_tables.h b/engines/agos/detection_tables.h
index a43d581173..d9f321d98e 100644
--- a/engines/agos/detection_tables.h
+++ b/engines/agos/detection_tables.h
@@ -1040,7 +1040,7 @@ static const AGOSGameDescription gameDescriptions[] = {
},
Common::EN_ANY,
Common::kPlatformAcorn,
- ADGF_NO_FLAGS,
+ ADGF_CD,
GUIO_NOSUBTITLES
},
@@ -1208,7 +1208,7 @@ static const AGOSGameDescription gameDescriptions[] = {
},
Common::EN_ANY,
Common::kPlatformAmiga,
- ADGF_NO_FLAGS,
+ ADGF_CD,
GUIO_NOSUBTITLES | GUIO_NOMIDI
},
@@ -1232,7 +1232,7 @@ static const AGOSGameDescription gameDescriptions[] = {
},
Common::EN_ANY,
Common::kPlatformAmiga,
- ADGF_NO_FLAGS,
+ ADGF_CD,
GUIO_NOSUBTITLES | GUIO_NOMIDI
},
@@ -1546,7 +1546,7 @@ static const AGOSGameDescription gameDescriptions[] = {
},
Common::EN_ANY,
Common::kPlatformPC,
- ADGF_NO_FLAGS,
+ ADGF_CD,
GUIO_NOSUBTITLES
},
@@ -1571,7 +1571,7 @@ static const AGOSGameDescription gameDescriptions[] = {
},
Common::EN_ANY,
Common::kPlatformPC,
- ADGF_NO_FLAGS,
+ ADGF_CD,
GUIO_NOSUBTITLES
},
@@ -1596,7 +1596,7 @@ static const AGOSGameDescription gameDescriptions[] = {
},
Common::RU_RUS,
Common::kPlatformPC,
- ADGF_NO_FLAGS,
+ ADGF_CD,
GUIO_NONE
},
@@ -1621,7 +1621,7 @@ static const AGOSGameDescription gameDescriptions[] = {
},
Common::FR_FRA,
Common::kPlatformPC,
- ADGF_NO_FLAGS,
+ ADGF_CD,
GUIO_NONE
},
@@ -1671,7 +1671,7 @@ static const AGOSGameDescription gameDescriptions[] = {
},
Common::HE_ISR,
Common::kPlatformPC,
- ADGF_NO_FLAGS,
+ ADGF_CD,
GUIO_NONE
},
@@ -1696,7 +1696,7 @@ static const AGOSGameDescription gameDescriptions[] = {
},
Common::IT_ITA,
Common::kPlatformPC,
- ADGF_NO_FLAGS,
+ ADGF_CD,
GUIO_NONE
},
@@ -1722,7 +1722,7 @@ static const AGOSGameDescription gameDescriptions[] = {
// FIXME: DOS version which uses WAV format
Common::IT_ITA,
Common::kPlatformWindows,
- ADGF_NO_FLAGS,
+ ADGF_CD,
GUIO_NONE
},
@@ -1747,7 +1747,7 @@ static const AGOSGameDescription gameDescriptions[] = {
},
Common::ES_ESP,
Common::kPlatformPC,
- ADGF_NO_FLAGS,
+ ADGF_CD,
GUIO_NONE
},
@@ -1772,7 +1772,7 @@ static const AGOSGameDescription gameDescriptions[] = {
},
Common::EN_ANY,
Common::kPlatformWindows,
- ADGF_NO_FLAGS,
+ ADGF_CD,
GUIO_NOSUBTITLES
},
@@ -1797,7 +1797,7 @@ static const AGOSGameDescription gameDescriptions[] = {
},
Common::DE_DEU,
Common::kPlatformWindows,
- ADGF_NO_FLAGS,
+ ADGF_CD,
GUIO_NOSUBTITLES
},
@@ -2022,7 +2022,7 @@ static const AGOSGameDescription gameDescriptions[] = {
},
Common::EN_ANY,
Common::kPlatformPC,
- ADGF_NO_FLAGS,
+ ADGF_CD,
GUIO_NONE
},
@@ -2047,7 +2047,7 @@ static const AGOSGameDescription gameDescriptions[] = {
},
Common::EN_ANY,
Common::kPlatformPC,
- ADGF_NO_FLAGS,
+ ADGF_CD,
GUIO_NONE
},
@@ -2072,7 +2072,7 @@ static const AGOSGameDescription gameDescriptions[] = {
},
Common::FR_FRA,
Common::kPlatformPC,
- ADGF_NO_FLAGS,
+ ADGF_CD,
GUIO_NONE
},
@@ -2097,7 +2097,7 @@ static const AGOSGameDescription gameDescriptions[] = {
},
Common::DE_DEU,
Common::kPlatformPC,
- ADGF_NO_FLAGS,
+ ADGF_CD,
GUIO_NONE
},
@@ -2122,7 +2122,7 @@ static const AGOSGameDescription gameDescriptions[] = {
},
Common::DE_DEU,
Common::kPlatformPC,
- ADGF_NO_FLAGS,
+ ADGF_CD,
GUIO_NONE
},
@@ -2147,7 +2147,7 @@ static const AGOSGameDescription gameDescriptions[] = {
},
Common::HE_ISR,
Common::kPlatformPC,
- ADGF_NO_FLAGS,
+ ADGF_CD,
GUIO_NONE
},
@@ -2173,7 +2173,7 @@ static const AGOSGameDescription gameDescriptions[] = {
// FIXME: DOS version which uses WAV format
Common::IT_ITA,
Common::kPlatformWindows,
- ADGF_NO_FLAGS,
+ ADGF_CD,
GUIO_NONE
},
@@ -2198,7 +2198,7 @@ static const AGOSGameDescription gameDescriptions[] = {
},
Common::ES_ESP,
Common::kPlatformPC,
- ADGF_NO_FLAGS,
+ ADGF_CD,
GUIO_NONE
},
@@ -2223,7 +2223,7 @@ static const AGOSGameDescription gameDescriptions[] = {
},
Common::CZ_CZE,
Common::kPlatformWindows,
- ADGF_NO_FLAGS,
+ ADGF_CD,
GUIO_NONE
},
@@ -2248,7 +2248,7 @@ static const AGOSGameDescription gameDescriptions[] = {
},
Common::EN_ANY,
Common::kPlatformWindows,
- ADGF_NO_FLAGS,
+ ADGF_CD,
GUIO_NONE
},
@@ -2273,7 +2273,7 @@ static const AGOSGameDescription gameDescriptions[] = {
},
Common::FR_FRA,
Common::kPlatformWindows,
- ADGF_NO_FLAGS,
+ ADGF_CD,
GUIO_NONE
},
@@ -2298,7 +2298,7 @@ static const AGOSGameDescription gameDescriptions[] = {
},
Common::DE_DEU,
Common::kPlatformWindows,
- ADGF_NO_FLAGS,
+ ADGF_CD,
GUIO_NONE
},
@@ -2323,7 +2323,7 @@ static const AGOSGameDescription gameDescriptions[] = {
},
Common::PL_POL,
Common::kPlatformWindows,
- ADGF_NO_FLAGS,
+ ADGF_CD,
GUIO_NONE
},
diff --git a/engines/composer/composer.cpp b/engines/composer/composer.cpp
index cf773dc2dc..d9bb0cdc54 100644
--- a/engines/composer/composer.cpp
+++ b/engines/composer/composer.cpp
@@ -125,9 +125,9 @@ Common::Error ComposerEngine::run() {
}
if (lastDrawTime + frameTime <= thisTime) {
- // catch up if we're more than 5 frames behind
- if (lastDrawTime + (frameTime * 5) <= thisTime)
- lastDrawTime = thisTime - (frameTime * 5);
+ // catch up if we're more than 2 frames behind
+ if (lastDrawTime + (frameTime * 2) <= thisTime)
+ lastDrawTime = thisTime;
else
lastDrawTime += frameTime;
@@ -253,16 +253,15 @@ void ComposerEngine::setCursor(uint16 id, const Common::Point &offset) {
}
void ComposerEngine::setCursorVisible(bool visible) {
- if (!_mouseSpriteId)
- return;
-
if (visible && !_mouseVisible) {
_mouseVisible = true;
- addSprite(_mouseSpriteId, 0, 0, _lastMousePos - _mouseOffset);
+ if (_mouseSpriteId)
+ addSprite(_mouseSpriteId, 0, 0, _lastMousePos - _mouseOffset);
onMouseMove(_lastMousePos);
} else if (!visible && _mouseVisible) {
_mouseVisible = false;
- removeSprite(_mouseSpriteId, 0);
+ if (_mouseSpriteId)
+ removeSprite(_mouseSpriteId, 0);
}
}
@@ -276,6 +275,11 @@ Common::String ComposerEngine::getStringFromConfig(const Common::String &section
Common::String ComposerEngine::getFilename(const Common::String &section, uint id) {
Common::String key = Common::String::format("%d", id);
Common::String filename = getStringFromConfig(section, key);
+
+ return mangleFilename(filename);
+}
+
+Common::String ComposerEngine::mangleFilename(Common::String filename) {
while (filename.size() && (filename[0] == '~' || filename[0] == ':' || filename[0] == '\\'))
filename = filename.c_str() + 1;
@@ -318,11 +322,11 @@ void ComposerEngine::loadLibrary(uint id) {
for (uint i = 0; i < buttonResources.size(); i++) {
uint16 buttonId = buttonResources[i];
Common::SeekableReadStream *stream = library._archive->getResource(ID_BUTN, buttonId);
- Button button(stream, buttonId);
+ Button button(stream, buttonId, getGameType());
bool inserted = false;
for (Common::List<Button>::iterator b = newLib._buttons.begin(); b != newLib._buttons.end(); b++) {
- if (button._zorder <= b->_zorder)
+ if (button._zorder < b->_zorder)
continue;
newLib._buttons.insert(b, button);
inserted = true;
@@ -405,22 +409,32 @@ Common::SeekableReadStream *ComposerEngine::getResource(uint32 tag, uint16 id) {
error("No loaded library contains '%s' %04x", tag2str(tag), id);
}
-Button::Button(Common::SeekableReadStream *stream, uint16 id) {
+Button::Button(Common::SeekableReadStream *stream, uint16 id, uint gameType) {
_id = id;
_type = stream->readUint16LE();
_active = (_type & 0x8000) ? true : false;
_type &= 0xfff;
- debug(9, "button: type %d, active %d", _type, _active);
-
- _zorder = stream->readUint16LE();
- _scriptId = stream->readUint16LE();
- _scriptIdRollOn = stream->readUint16LE();
- _scriptIdRollOff = stream->readUint16LE();
-
- stream->skip(4);
-
- uint16 size = stream->readUint16LE();
+ debug(9, "button %d: type %d, active %d", id, _type, _active);
+
+ uint16 flags = 0;
+ uint16 size = 4;
+ if (gameType == GType_ComposerV1) {
+ flags = stream->readUint16LE();
+ _zorder = 0;
+ _scriptId = stream->readUint16LE();
+ _scriptIdRollOn = 0;
+ _scriptIdRollOff = 0;
+ } else {
+ _zorder = stream->readUint16LE();
+ _scriptId = stream->readUint16LE();
+ _scriptIdRollOn = stream->readUint16LE();
+ _scriptIdRollOff = stream->readUint16LE();
+
+ stream->skip(4);
+
+ size = stream->readUint16LE();
+ }
switch (_type) {
case kButtonRect:
@@ -431,17 +445,23 @@ Button::Button(Common::SeekableReadStream *stream, uint16 id) {
_rect.top = stream->readSint16LE();
_rect.right = stream->readSint16LE();
_rect.bottom = stream->readSint16LE();
- debug(9, "button: (%d, %d, %d, %d)", _rect.left, _rect.top, _rect.right, _rect.bottom);
break;
case kButtonSprites:
+ if (gameType == GType_ComposerV1)
+ error("encountered kButtonSprites in V1 data");
for (uint i = 0; i < size; i++) {
- _spriteIds.push_back(stream->readSint16LE());
+ _spriteIds.push_back(stream->readUint16LE());
}
break;
default:
error("unknown button type %d", _type);
}
+ if (flags & 0x40) {
+ _scriptIdRollOn = stream->readUint16LE();
+ _scriptIdRollOff = stream->readUint16LE();
+ }
+
delete stream;
}
diff --git a/engines/composer/composer.h b/engines/composer/composer.h
index 99ed56ead7..c0d456daaa 100644
--- a/engines/composer/composer.h
+++ b/engines/composer/composer.h
@@ -68,7 +68,7 @@ enum {
class Button {
public:
Button() { }
- Button(Common::SeekableReadStream *stream, uint16 id);
+ Button(Common::SeekableReadStream *stream, uint16 id, uint gameType);
bool contains(const Common::Point &pos) const;
@@ -172,6 +172,7 @@ private:
Common::String getStringFromConfig(const Common::String &section, const Common::String &key);
Common::String getFilename(const Common::String &section, uint id);
+ Common::String mangleFilename(Common::String filename);
void loadLibrary(uint id);
void unloadLibrary(uint id);
diff --git a/engines/composer/detection.cpp b/engines/composer/detection.cpp
index c4e98fadd7..8c97b6c4db 100644
--- a/engines/composer/detection.cpp
+++ b/engines/composer/detection.cpp
@@ -120,6 +120,19 @@ static const ComposerGameDescription gameDescriptions[] = {
GType_ComposerV2
},
+ { // Provided by Strangerke, "CD-Rom 100% Malin" Pack
+ {
+ "darby",
+ 0,
+ AD_ENTRY1("book.ini", "285308372f7dddff2ca5a25c9192cf5c"),
+ Common::FR_FRA,
+ Common::kPlatformWindows,
+ ADGF_NO_FLAGS,
+ Common::GUIO_NONE
+ },
+ GType_ComposerV2
+ },
+
{
{
"gregory",
@@ -133,6 +146,19 @@ static const ComposerGameDescription gameDescriptions[] = {
GType_ComposerV2
},
+ { // Provided by Strangerke, "CD-Rom 100% Malin" Pack
+ {
+ "gregory",
+ 0,
+ AD_ENTRY1("book.ini", "e54fc5c00de5f94e908a969e445af5d0"),
+ Common::EN_ANY,
+ Common::kPlatformWindows,
+ ADGF_NO_FLAGS,
+ Common::GUIO_NONE
+ },
+ GType_ComposerV2
+ },
+
{
{
"princess",
diff --git a/engines/composer/graphics.cpp b/engines/composer/graphics.cpp
index 5c9fc6e1f7..0768a86e7a 100644
--- a/engines/composer/graphics.cpp
+++ b/engines/composer/graphics.cpp
@@ -598,10 +598,16 @@ enum {
};
void ComposerEngine::decompressBitmap(uint16 type, Common::SeekableReadStream *stream, byte *buffer, uint32 size, uint width, uint height) {
+ uint outSize = width * height;
+
switch (type) {
case kBitmapUncompressed:
- assert(stream->size() - (uint)stream->pos() == size);
- assert(size == width * height);
+ if (stream->size() - (uint)stream->pos() != size)
+ error("kBitmapUncompressed stream had %d bytes left, supposed to be %d",
+ stream->size() - (uint)stream->pos(), size);
+ if (size != outSize)
+ error("kBitmapUncompressed size %d doesn't match required size %d",
+ size, outSize);
stream->read(buffer, size);
break;
case kBitmapSpp32:
@@ -615,12 +621,22 @@ void ComposerEngine::decompressBitmap(uint16 type, Common::SeekableReadStream *s
// run of a single color
uint count = (uint)stream->readByte() + 3;
size--;
+ if (outSize < count)
+ error("kBitmapSpp32 only needed %d bytes, but got run of %d",
+ outSize, count);
+ outSize -= count;
memset(buffer, lookup[lowBits], count);
buffer += count;
} else {
// two pixels
+ if (!outSize)
+ error("kBitmapSpp32 had too many pixels");
*buffer++ = lookup[highBits];
- *buffer++ = lookup[lowBits];
+ outSize--;
+ if (outSize) {
+ *buffer++ = lookup[lowBits];
+ outSize--;
+ }
}
}
break;
diff --git a/engines/dreamweb/dreamgen.cpp b/engines/dreamweb/dreamgen.cpp
index 59d69758b6..9a5a27dff0 100644
--- a/engines/dreamweb/dreamgen.cpp
+++ b/engines/dreamweb/dreamgen.cpp
@@ -1694,116 +1694,6 @@ notendtelly:
showgamereel();
}
-void DreamGenContext::madman() {
- STACK_CHECK;
- data.word(kWatchingtime) = 2;
- checkspeed();
- if (!flags.z())
- goto nomadspeed;
- ax = es.word(bx+3);
- _cmp(ax, 364);
- if (!flags.c())
- goto ryansded;
- _cmp(ax, 10);
- if (!flags.z())
- goto notfirstmad;
- push(es);
- push(bx);
- push(ax);
- dx = 2247;
- loadtemptext();
- ax = pop();
- bx = pop();
- es = pop();
- data.byte(kCombatcount) = -1;
- data.byte(kSpeechcount) = 0;
-notfirstmad:
- _inc(ax);
- _cmp(ax, 294);
- if (flags.z())
- goto madmanspoken;
- _cmp(ax, 66);
- if (!flags.z())
- goto nomadspeak;
- _inc(data.byte(kCombatcount));
- push(es);
- push(bx);
- madmantext();
- bx = pop();
- es = pop();
- ax = 53;
- _cmp(data.byte(kCombatcount), 64);
- if (flags.c())
- goto nomadspeak;
- _cmp(data.byte(kCombatcount), 70);
- if (flags.z())
- goto killryan;
- _cmp(data.byte(kLastweapon), 8);
- if (!flags.z())
- goto nomadspeak;
- data.byte(kCombatcount) = 72;
- data.byte(kLastweapon) = -1;
- data.byte(kMadmanflag) = 1;
- ax = 67;
- goto nomadspeak;
-killryan:
- ax = 310;
-nomadspeak:
- es.word(bx+3) = ax;
-nomadspeed:
- showgamereel();
- al = data.byte(kMapx);
- es.byte(bx+1) = al;
- madmode();
- return;
-madmanspoken:
- _cmp(data.byte(kWongame), 1);
- if (flags.z())
- return /* (alreadywon) */;
- data.byte(kWongame) = 1;
- push(es);
- push(bx);
- getridoftemptext();
- bx = pop();
- es = pop();
- return;
-ryansded:
- data.byte(kMandead) = 2;
- showgamereel();
-}
-
-void DreamGenContext::madmantext() {
- STACK_CHECK;
- _cmp(data.byte(kSpeechcount), 63);
- if (!flags.c())
- return /* (nomadtext) */;
- _cmp(data.byte(kCh1playing), 255);
- if (!flags.z())
- return /* (nomadtext) */;
- al = data.byte(kSpeechcount);
- _inc(data.byte(kSpeechcount));
- _add(al, 47);
- bl = 72;
- bh = 80;
- cx = 90;
- dx = 1;
- ah = 82;
- setuptimedtemp();
-}
-
-void DreamGenContext::madmode() {
- STACK_CHECK;
- data.word(kWatchingtime) = 2;
- data.byte(kPointermode) = 0;
- _cmp(data.byte(kCombatcount), 65);
- if (flags.c())
- return /* (iswatchmad) */;
- _cmp(data.byte(kCombatcount), 70);
- if (!flags.c())
- return /* (iswatchmad) */;
- data.byte(kPointermode) = 2;
-}
-
void DreamGenContext::priesttext() {
STACK_CHECK;
_cmp(es.word(bx+3), 2);
@@ -2160,22 +2050,6 @@ void DreamGenContext::addtopeoplelist() {
_add(data.word(kListpos), 5);
}
-void DreamGenContext::showgamereel() {
- STACK_CHECK;
- ax = es.word(bx+3);
- _cmp(ax, 512);
- if (!flags.c())
- return /* (noshow) */;
- data.word(kReelpointer) = ax;
- push(es);
- push(bx);
- plotreel();
- bx = pop();
- es = pop();
- ax = data.word(kReelpointer);
- es.word(bx+3) = ax;
-}
-
void DreamGenContext::checkspeed() {
STACK_CHECK;
_cmp(data.byte(kLastweapon), -1);
@@ -2237,182 +2111,6 @@ void DreamGenContext::checkone() {
dx = pop();
}
-void DreamGenContext::findsource() {
- STACK_CHECK;
- ax = data.word(kCurrentframe);
- _cmp(ax, 160);
- if (!flags.c())
- goto over1000;
- ds = data.word(kReel1);
- data.word(kTakeoff) = 0;
- return;
-over1000:
- _cmp(ax, 320);
- if (!flags.c())
- goto over1001;
- ds = data.word(kReel2);
- data.word(kTakeoff) = 160;
- return;
-over1001:
- ds = data.word(kReel3);
- data.word(kTakeoff) = 320;
-}
-
-void DreamGenContext::mainman() {
- STACK_CHECK;
- _cmp(data.byte(kResetmanxy), 1);
- if (!flags.z())
- goto notinnewroom;
- data.byte(kResetmanxy) = 0;
- al = data.byte(kRyanx);
- ah = data.byte(kRyany);
- es.word(bx+10) = ax;
- es.byte(bx+29) = 0;
- goto executewalk;
-notinnewroom:
- _dec(es.byte(bx+22));
- _cmp(es.byte(bx+22), -1);
- if (flags.z())
- goto executewalk;
- return;
-executewalk:
- es.byte(bx+22) = 0;
- al = data.byte(kTurntoface);
- _cmp(al, data.byte(kFacing));
- if (flags.z())
- goto facingok;
- aboutturn();
- goto notwalk;
-facingok:
- _cmp(data.byte(kTurndirection), 0);
- if (flags.z())
- goto alreadyturned;
- _cmp(data.byte(kLinepointer), 254);
- if (!flags.z())
- goto alreadyturned;
- data.byte(kReasseschanges) = 1;
- al = data.byte(kFacing);
- _cmp(al, data.byte(kLeavedirection));
- if (!flags.z())
- goto alreadyturned;
- checkforexit();
-alreadyturned:
- data.byte(kTurndirection) = 0;
- _cmp(data.byte(kLinepointer), 254);
- if (!flags.z())
- goto walkman;
- es.byte(bx+29) = 0;
- goto notwalk;
-walkman:
- al = es.byte(bx+29);
- _inc(al);
- _cmp(al, 11);
- if (!flags.z())
- goto notanimend1;
- al = 1;
-notanimend1:
- es.byte(bx+29) = al;
- walking();
- _cmp(data.byte(kLinepointer), 254);
- if (flags.z())
- goto afterwalk;
- al = data.byte(kFacing);
- _and(al, 1);
- if (flags.z())
- goto isdouble;
- al = es.byte(bx+29);
- _cmp(al, 2);
- if (flags.z())
- goto afterwalk;
- _cmp(al, 7);
- if (flags.z())
- goto afterwalk;
-isdouble:
- walking();
-afterwalk:
- _cmp(data.byte(kLinepointer), 254);
- if (!flags.z())
- goto notwalk;
- al = data.byte(kTurntoface);
- _cmp(al, data.byte(kFacing));
- if (!flags.z())
- goto notwalk;
- data.byte(kReasseschanges) = 1;
- al = data.byte(kFacing);
- _cmp(al, data.byte(kLeavedirection));
- if (!flags.z())
- goto notwalk;
- checkforexit();
-notwalk:
- al = data.byte(kFacing);
- ah = 0;
- di = 1105;
- _add(di, ax);
- al = cs.byte(di);
- _add(al, es.byte(bx+29));
- es.byte(bx+15) = al;
- ax = es.word(bx+10);
- data.byte(kRyanx) = al;
- data.byte(kRyany) = ah;
-}
-
-void DreamGenContext::aboutturn() {
- STACK_CHECK;
- _cmp(data.byte(kTurndirection), 1);
- if (flags.z())
- goto incdir;
- _cmp(data.byte(kTurndirection), -1);
- if (flags.z())
- goto decdir;
- al = data.byte(kFacing);
- _sub(al, data.byte(kTurntoface));
- if (!flags.c())
- goto higher;
- _neg(al);
- _cmp(al, 4);
- if (!flags.c())
- goto decdir;
- goto incdir;
-higher:
- _cmp(al, 4);
- if (!flags.c())
- goto incdir;
- goto decdir;
-incdir:
- data.byte(kTurndirection) = 1;
- al = data.byte(kFacing);
- _inc(al);
- _and(al, 7);
- data.byte(kFacing) = al;
- es.byte(bx+29) = 0;
- return;
-decdir:
- data.byte(kTurndirection) = -1;
- al = data.byte(kFacing);
- _dec(al);
- _and(al, 7);
- data.byte(kFacing) = al;
- es.byte(bx+29) = 0;
-}
-
-void DreamGenContext::facerightway() {
- STACK_CHECK;
- push(es);
- push(bx);
- getroomspaths();
- al = data.byte(kManspath);
- ah = 0;
- _add(ax, ax);
- _add(ax, ax);
- _add(ax, ax);
- _add(bx, ax);
- al = es.byte(bx+7);
- data.byte(kTurntoface) = al;
- data.byte(kLeavedirection) = al;
- bx = pop();
- es = pop();
-}
-
void DreamGenContext::checkforexit() {
STACK_CHECK;
cl = data.byte(kRyanx);
@@ -2772,147 +2470,6 @@ failrain:
al = 0;
}
-void DreamGenContext::showrain() {
- STACK_CHECK;
- ds = data.word(kMainsprites);
- si = 6*58;
- ax = ds.word(si+2);
- si = ax;
- _add(si, 2080);
- bx = (0+(228*13)+32+60+(32*32)+(11*10*3)+768+768+768+(32*32)+(128*5)+(80*5)+(100*5)+(12*5)+(46*40)+(5*80)+(250*4)+(256*30));
- es = data.word(kBuffers);
- _cmp(es.byte(bx), 255);
- if (flags.z())
- return /* (nothunder) */;
-morerain:
- es = data.word(kBuffers);
- _cmp(es.byte(bx), 255);
- if (flags.z())
- goto finishrain;
- al = es.byte(bx+1);
- ah = 0;
- _add(ax, data.word(kMapady));
- _add(ax, data.word(kMapystart));
- cx = 320;
- _mul(cx);
- cl = es.byte(bx);
- ch = 0;
- _add(ax, cx);
- _add(ax, data.word(kMapadx));
- _add(ax, data.word(kMapxstart));
- di = ax;
- cl = es.byte(bx+2);
- ch = 0;
- ax = es.word(bx+3);
- dl = es.byte(bx+5);
- dh = 0;
- _sub(ax, dx);
- _and(ax, 511);
- es.word(bx+3) = ax;
- _add(bx, 6);
- push(si);
- _add(si, ax);
- es = data.word(kWorkspace);
- ah = 0;
- dx = 320-2;
-rainloop:
- _lodsb();
- _cmp(al, ah);
- if (flags.z())
- goto noplot;
- _stosb();
- _add(di, dx);
- if (--cx)
- goto rainloop;
- si = pop();
- goto morerain;
-noplot:
- _add(di, 320-1);
- if (--cx)
- goto rainloop;
- si = pop();
- goto morerain;
-finishrain:
- _cmp(data.word(kCh1blockstocopy), 0);
- if (!flags.z())
- return /* (nothunder) */;
- _cmp(data.byte(kReallocation), 2);
- if (!flags.z())
- goto notlouisthund;
- _cmp(data.byte(kBeenmugged), 1);
- if (!flags.z())
- return /* (nothunder) */;
-notlouisthund:
- _cmp(data.byte(kReallocation), 55);
- if (flags.z())
- return /* (nothunder) */;
- randomnum1();
- _cmp(al, 1);
- if (!flags.c())
- return /* (nothunder) */;
- al = 7;
- _cmp(data.byte(kCh0playing), 6);
- if (flags.z())
- goto isthunder1;
- al = 4;
-isthunder1:
- playchannel1();
-}
-
-void DreamGenContext::backobject() {
- STACK_CHECK;
- ds = data.word(kSetdat);
- di = es.word(bx+20);
- al = es.byte(bx+18);
- _cmp(al, 0);
- if (flags.z())
- goto _tmp48z;
- _dec(al);
- es.byte(bx+18) = al;
- return /* (finishback) */;
-_tmp48z:
- al = ds.byte(di+7);
- es.byte(bx+18) = al;
- al = ds.byte(di+8);
- _cmp(al, 6);
- if (!flags.z())
- goto notwidedoor;
- widedoor();
- return /* (finishback) */;
-notwidedoor:
- _cmp(al, 5);
- if (!flags.z())
- goto notrandom;
- random();
- return /* (finishback) */;
-notrandom:
- _cmp(al, 4);
- if (!flags.z())
- goto notlockdoor;
- lockeddoorway();
- return /* (finishback) */;
-notlockdoor:
- _cmp(al, 3);
- if (!flags.z())
- goto notlift;
- liftsprite();
- return /* (finishback) */;
-notlift:
- _cmp(al, 2);
- if (!flags.z())
- goto notdoor;
- doorway();
- return /* (finishback) */;
-notdoor:
- _cmp(al, 1);
- if (!flags.z())
- goto steadyob;
- constant();
- return /* (finishback) */;
-steadyob:
- steady();
-}
-
void DreamGenContext::liftnoise() {
STACK_CHECK;
_cmp(data.byte(kReallocation), 5);
@@ -2966,231 +2523,6 @@ gotconst:
ds.byte(di+17) = al;
}
-void DreamGenContext::doorway() {
- STACK_CHECK;
- data.byte(kDoorcheck1) = -24;
- data.byte(kDoorcheck2) = 10;
- data.byte(kDoorcheck3) = -30;
- data.byte(kDoorcheck4) = 10;
- dodoor();
-}
-
-void DreamGenContext::widedoor() {
- STACK_CHECK;
- data.byte(kDoorcheck1) = -24;
- data.byte(kDoorcheck2) = 24;
- data.byte(kDoorcheck3) = -30;
- data.byte(kDoorcheck4) = 24;
- dodoor();
-}
-
-void DreamGenContext::lockeddoorway() {
- STACK_CHECK;
- al = data.byte(kRyanx);
- ah = data.byte(kRyany);
- cl = es.byte(bx+10);
- ch = es.byte(bx+11);
- _cmp(al, cl);
- if (!flags.c())
- goto rtofdoor2;
- _sub(al, cl);
- _cmp(al, -24);
- if (!flags.c())
- goto upordown2;
- goto shutdoor2;
-rtofdoor2:
- _sub(al, cl);
- _cmp(al, 10);
- if (!flags.c())
- goto shutdoor2;
-upordown2:
- _cmp(ah, ch);
- if (!flags.c())
- goto botofdoor2;
- _sub(ah, ch);
- _cmp(ah, -30);
- if (flags.c())
- goto shutdoor2;
- goto opendoor2;
-botofdoor2:
- _sub(ah, ch);
- _cmp(ah, 12);
- if (!flags.c())
- goto shutdoor2;
-opendoor2:
- _cmp(data.byte(kThroughdoor), 1);
- if (flags.z())
- goto mustbeopen;
- _cmp(data.byte(kLockstatus), 1);
- if (flags.z())
- goto shutdoor;
-mustbeopen:
- cl = es.byte(bx+19);
- _cmp(cl, 1);
- if (!flags.z())
- goto notdoorsound4;
- al = 0;
- playchannel1();
-notdoorsound4:
- _cmp(cl, 6);
- if (!flags.z())
- goto noturnonyet;
- al = data.byte(kDoorpath);
- push(es);
- push(bx);
- turnpathon();
- bx = pop();
- es = pop();
-noturnonyet:
- cl = es.byte(bx+19);
- _cmp(data.byte(kThroughdoor), 1);
- if (!flags.z())
- goto notthrough2;
- _cmp(cl, 0);
- if (!flags.z())
- goto notthrough2;
- cl = 6;
-notthrough2:
- _inc(cl);
- ch = 0;
- push(di);
- _add(di, cx);
- al = ds.byte(di+18);
- _cmp(al, 255);
- if (!flags.z())
- goto atlast3;
- _dec(di);
- _dec(cl);
-atlast3:
- es.byte(bx+19) = cl;
- al = ds.byte(di+18);
- di = pop();
- es.byte(bx+15) = al;
- ds.byte(di+17) = al;
- _cmp(cl, 5);
- if (!flags.z())
- return /* (justshutting) */;
- data.byte(kThroughdoor) = 1;
- return;
-shutdoor2:
- cl = es.byte(bx+19);
- _cmp(cl, 5);
- if (!flags.z())
- goto notdoorsound3;
- al = 1;
- playchannel1();
-notdoorsound3:
- _cmp(cl, 0);
- if (flags.z())
- goto atlast4;
- _dec(cl);
- es.byte(bx+19) = cl;
-atlast4:
- ch = 0;
- data.byte(kThroughdoor) = 0;
- push(di);
- _add(di, cx);
- al = ds.byte(di+18);
- di = pop();
- es.byte(bx+15) = al;
- ds.byte(di+17) = al;
- _cmp(cl, 0);
- if (!flags.z())
- return /* (notlocky) */;
- al = data.byte(kDoorpath);
- push(es);
- push(bx);
- turnpathoff();
- bx = pop();
- es = pop();
- data.byte(kLockstatus) = 1;
- return;
-/*continuing to unbounded code: shutdoor from dodoor:60-87*/
-shutdoor:
- cl = es.byte(bx+19);
- _cmp(cl, 5);
- if (!flags.z())
- goto notdoorsound1;
- al = 1;
- _cmp(data.byte(kReallocation), 5);
- if (!flags.z())
- goto nothoteldoor1;
- al = 13;
-nothoteldoor1:
- playchannel1();
-notdoorsound1:
- _cmp(cl, 0);
- if (flags.z())
- goto atlast2;
- _dec(cl);
- es.byte(bx+19) = cl;
-atlast2:
- ch = 0;
- push(di);
- _add(di, cx);
- al = ds.byte(di+18);
- di = pop();
- es.byte(bx+15) = al;
- ds.byte(di+17) = al;
- _cmp(cl, 5);
- if (!flags.z())
- return /* (notnearly) */;
- data.byte(kThroughdoor) = 0;
-}
-
-void DreamGenContext::updatepeople() {
- STACK_CHECK;
- es = data.word(kBuffers);
- di = (0+(228*13)+32+60+(32*32)+(11*10*3)+768+768+768+(32*32)+(128*5)+(80*5)+(100*5));
- data.word(kListpos) = di;
- cx = 12*5;
- al = 255;
- _stosb(cx, true);
- _inc(data.word(kMaintimer));
- es = cs;
- bx = 534;
- di = 991;
-updateloop:
- al = es.byte(bx);
- _cmp(al, 255);
- if (flags.z())
- return /* (endupdate) */;
- _cmp(al, data.byte(kReallocation));
- if (!flags.z())
- goto notinthisroom;
- cx = es.word(bx+1);
- _cmp(cl, data.byte(kMapx));
- if (!flags.z())
- goto notinthisroom;
- _cmp(ch, data.byte(kMapy));
- if (!flags.z())
- goto notinthisroom;
- push(di);
- ax = cs.word(di);
- __dispatch_call(ax);
- di = pop();
-notinthisroom:
- _add(bx, 8);
- _add(di, 2);
- goto updateloop;
-}
-
-void DreamGenContext::getreelframeax() {
- STACK_CHECK;
- push(ds);
- data.word(kCurrentframe) = ax;
- findsource();
- es = ds;
- ds = pop();
- ax = data.word(kCurrentframe);
- _sub(ax, data.word(kTakeoff));
- _add(ax, ax);
- cx = ax;
- _add(ax, ax);
- _add(ax, cx);
- bx = ax;
-}
-
void DreamGenContext::reelsonscreen() {
STACK_CHECK;
reconstruct();
@@ -3200,48 +2532,6 @@ void DreamGenContext::reelsonscreen() {
usetimedtext();
}
-void DreamGenContext::plotreel() {
- STACK_CHECK;
- getreelstart();
-retryreel:
- push(es);
- push(si);
- ax = es.word(si+2);
- _cmp(al, 220);
- if (flags.c())
- goto normalreel;
- _cmp(al, 255);
- if (flags.z())
- goto normalreel;
- dealwithspecial();
- _inc(data.word(kReelpointer));
- si = pop();
- es = pop();
- _add(si, 40);
- goto retryreel;
-normalreel:
- cx = 8;
-plotloop:
- push(cx);
- push(es);
- push(si);
- ax = es.word(si);
- _cmp(ax, 0x0ffff);
- if (flags.z())
- goto notplot;
- showreelframe();
-notplot:
- si = pop();
- es = pop();
- cx = pop();
- _add(si, 5);
- if (--cx)
- goto plotloop;
- soundonreels();
- bx = pop();
- es = pop();
-}
-
void DreamGenContext::soundonreels() {
STACK_CHECK;
bl = data.byte(kReallocation);
@@ -3307,126 +2597,6 @@ notfudge:
data.byte(kHavedoneobs) = 0;
}
-void DreamGenContext::dealwithspecial() {
- STACK_CHECK;
- _sub(al, 220);
- _cmp(al, 0);
- if (!flags.z())
- goto notplset;
- al = ah;
- placesetobject();
- data.byte(kHavedoneobs) = 1;
- return;
-notplset:
- _cmp(al, 1);
- if (!flags.z())
- goto notremset;
- al = ah;
- removesetobject();
- data.byte(kHavedoneobs) = 1;
- return;
-notremset:
- _cmp(al, 2);
- if (!flags.z())
- goto notplfree;
- al = ah;
- placefreeobject();
- data.byte(kHavedoneobs) = 1;
- return;
-notplfree:
- _cmp(al, 3);
- if (!flags.z())
- goto notremfree;
- al = ah;
- removefreeobject();
- data.byte(kHavedoneobs) = 1;
- return;
-notremfree:
- _cmp(al, 4);
- if (!flags.z())
- goto notryanoff;
- switchryanoff();
- return;
-notryanoff:
- _cmp(al, 5);
- if (!flags.z())
- goto notryanon;
- data.byte(kTurntoface) = ah;
- data.byte(kFacing) = ah;
- switchryanon();
- return;
-notryanon:
- _cmp(al, 6);
- if (!flags.z())
- goto notchangeloc;
- data.byte(kNewlocation) = ah;
- return;
-notchangeloc:
- movemap();
-}
-
-void DreamGenContext::movemap() {
- STACK_CHECK;
- _cmp(ah, 32);
- if (!flags.z())
- goto notmapup2;
- _sub(data.byte(kMapy), 20);
- data.byte(kNowinnewroom) = 1;
- return;
-notmapup2:
- _cmp(ah, 16);
- if (!flags.z())
- goto notmapupspec;
- _sub(data.byte(kMapy), 10);
- data.byte(kNowinnewroom) = 1;
- return;
-notmapupspec:
- _cmp(ah, 8);
- if (!flags.z())
- goto notmapdownspec;
- _add(data.byte(kMapy), 10);
- data.byte(kNowinnewroom) = 1;
- return;
-notmapdownspec:
- _cmp(ah, 2);
- if (!flags.z())
- goto notmaprightspec;
- _add(data.byte(kMapx), 11);
- data.byte(kNowinnewroom) = 1;
- return;
-notmaprightspec:
- _sub(data.byte(kMapx), 11);
- data.byte(kNowinnewroom) = 1;
-}
-
-void DreamGenContext::getreelstart() {
- STACK_CHECK;
- ax = data.word(kReelpointer);
- cx = 40;
- _mul(cx);
- es = data.word(kReels);
- si = ax;
- _add(si, (0+(36*144)));
-}
-
-void DreamGenContext::showreelframe() {
- STACK_CHECK;
- al = es.byte(si+2);
- ah = 0;
- di = ax;
- _add(di, data.word(kMapadx));
- al = es.byte(si+3);
- bx = ax;
- _add(bx, data.word(kMapady));
- ax = es.word(si);
- data.word(kCurrentframe) = ax;
- findsource();
- ax = data.word(kCurrentframe);
- _sub(ax, data.word(kTakeoff));
- ah = 8;
- showframe();
-}
-
void DreamGenContext::deleverything() {
STACK_CHECK;
al = data.byte(kMapysize);
@@ -3501,13 +2671,6 @@ dumpevery2:
goto dumpevery2;
}
-void DreamGenContext::allocatework() {
- STACK_CHECK;
- bx = 0x1000;
- allocatemem();
- data.word(kWorkspace) = ax;
-}
-
void DreamGenContext::loadpalfromiff() {
STACK_CHECK;
dx = 2481;
@@ -3669,68 +2832,6 @@ void DreamGenContext::createpanel2() {
showframe();
}
-void DreamGenContext::clearwork() {
- STACK_CHECK;
- ax = 0x0;
- es = data.word(kWorkspace);
- di = 0;
- cx = (200*320)/64;
-clearloop:
- _stosw(32);
- if (--cx)
- goto clearloop;
-}
-
-void DreamGenContext::zoom() {
- STACK_CHECK;
- _cmp(data.word(kWatchingtime), 0);
- if (!flags.z())
- return /* (inwatching) */;
- _cmp(data.byte(kZoomon), 1);
- if (flags.z())
- goto zoomswitch;
- return;
-zoomswitch:
- _cmp(data.byte(kCommandtype), 199);
- if (flags.c())
- goto zoomit;
- putunderzoom();
- return;
-zoomit:
- ax = data.word(kOldpointery);
- _sub(ax, 9);
- cx = (320);
- _mul(cx);
- _add(ax, data.word(kOldpointerx));
- _sub(ax, 11);
- si = ax;
- ax = (132)+4;
- cx = (320);
- _mul(cx);
- _add(ax, (8)+5);
- di = ax;
- es = data.word(kWorkspace);
- ds = data.word(kWorkspace);
- cx = 20;
-zoomloop:
- push(cx);
- cx = 23;
-zoomloop2:
- _lodsb();
- ah = al;
- _stosw();
- es.word(di+(320)-2) = ax;
- if (--cx)
- goto zoomloop2;
- _add(si, (320)-23);
- _add(di, (320)-46+(320));
- cx = pop();
- if (--cx)
- goto zoomloop;
- crosshair();
- data.byte(kDidzoom) = 1;
-}
-
void DreamGenContext::delthisone() {
STACK_CHECK;
push(ax);
@@ -3775,83 +2876,6 @@ deloneloop:
goto deloneloop;
}
-void DreamGenContext::doblocks() {
- STACK_CHECK;
- es = data.word(kWorkspace);
- ax = data.word(kMapady);
- cx = (320);
- _mul(cx);
- di = data.word(kMapadx);
- _add(di, ax);
- al = data.byte(kMapy);
- ah = 0;
- bx = (66);
- _mul(bx);
- bl = data.byte(kMapx);
- bh = 0;
- _add(ax, bx);
- si = (0);
- _add(si, ax);
- cx = 10;
-loop120:
- push(di);
- push(cx);
- cx = 11;
-loop124:
- push(cx);
- push(di);
- ds = data.word(kMapdata);
- _lodsb();
- ds = data.word(kBackdrop);
- push(si);
- _cmp(al, 0);
- if (flags.z())
- goto zeroblock;
- ah = al;
- al = 0;
- si = (0+192);
- _add(si, ax);
- bh = 14;
- bh = 4;
-firstbitofblock:
- _movsw(8);
- _add(di, (320)-16);
- _dec(bh);
- if (!flags.z())
- goto firstbitofblock;
- bh = 12;
-loop125:
- _movsw(8);
- ax = 0x0dfdf;
- _stosw(2);
- _add(di, (320)-20);
- _dec(bh);
- if (!flags.z())
- goto loop125;
- _add(di, 4);
- ax = 0x0dfdf;
- _stosw(8);
- _add(di, (320)-16);
- _stosw(8);
- _add(di, (320)-16);
- _stosw(8);
- _add(di, (320)-16);
- _stosw(8);
-zeroblock:
- si = pop();
- di = pop();
- cx = pop();
- _add(di, 16);
- if (--cx)
- goto loop124;
- _add(si, (66)-11);
- cx = pop();
- di = pop();
- _add(di, (320)*16);
- if (--cx)
- goto loop120;
-}
-
void DreamGenContext::transferinv() {
STACK_CHECK;
di = data.word(kExframepos);
@@ -7648,40 +6672,6 @@ blankframe:
goto showobsloop;
}
-void DreamGenContext::makebackob() {
- STACK_CHECK;
- _cmp(data.byte(kNewobs), 0);
- if (flags.z())
- return /* (nomake) */;
- al = es.byte(si+5);
- ah = es.byte(si+8);
- push(si);
- push(ax);
- push(si);
- ax = data.word(kObjectx);
- bx = data.word(kObjecty);
- ah = bl;
- si = ax;
- cx = 49520;
- dx = data.word(kSetframes);
- di = (0);
- makesprite();
- ax = pop();
- es.word(bx+20) = ax;
- ax = pop();
- _cmp(al, 255);
- if (!flags.z())
- goto usedpriority;
- al = 0;
-usedpriority:
- es.byte(bx+23) = al;
- es.byte(bx+30) = ah;
- es.byte(bx+16) = 0;
- es.byte(bx+18) = 0;
- es.byte(bx+19) = 0;
- si = pop();
-}
-
void DreamGenContext::showallfree() {
STACK_CHECK;
es = data.word(kBuffers);
@@ -12853,28 +11843,6 @@ notonsartroof:
placesetobject();
}
-void DreamGenContext::dumptimedtext() {
- STACK_CHECK;
- _cmp(data.byte(kNeedtodumptimed), 1);
- if (!flags.z())
- return /* (nodumptimed) */;
- al = data.byte(kTimedy);
- _cmp(data.byte(kForeignrelease), 0);
- if (flags.z())
- goto _tmp1;
- _sub(al, 3);
-_tmp1:
- ah = 0;
- bx = ax;
- al = data.byte(kTimedx);
- ah = 0;
- di = ax;
- cl = 240;
- ch = (30);
- multidump();
- data.byte(kNeedtodumptimed) = 0;
-}
-
void DreamGenContext::setuptimeduse() {
STACK_CHECK;
_cmp(data.word(kTimecount), 0);
@@ -12897,58 +11865,6 @@ void DreamGenContext::setuptimeduse() {
data.word(kTimedoffset) = bx;
}
-void DreamGenContext::setuptimedtemp() {
- STACK_CHECK;
- _cmp(ah, 0);
- if (flags.z())
- goto notloadspeech3;
- push(ax);
- push(bx);
- push(cx);
- push(dx);
- dl = 'T';
- dh = ah;
- cl = 'T';
- ah = 0;
- loadspeech();
- _cmp(data.byte(kSpeechloaded), 1);
- if (!flags.z())
- goto _tmp1;
- al = 50+12;
- playchannel1();
-_tmp1:
- dx = pop();
- cx = pop();
- bx = pop();
- ax = pop();
- _cmp(data.byte(kSpeechloaded), 1);
- if (!flags.z())
- goto notloadspeech3;
- _cmp(data.byte(kSubtitles), 1);
- if (flags.z())
- goto notloadspeech3;
- return;
-notloadspeech3:
- _cmp(data.word(kTimecount), 0);
- if (!flags.z())
- return /* (cantsetup2) */;
- data.byte(kTimedy) = bh;
- data.byte(kTimedx) = bl;
- data.word(kCounttotimed) = cx;
- _add(dx, cx);
- data.word(kTimecount) = dx;
- bl = al;
- bh = 0;
- _add(bx, bx);
- es = data.word(kTextfile1);
- cx = (66*2);
- ax = es.word(bx);
- _add(ax, cx);
- bx = ax;
- data.word(kTimedseg) = es;
- data.word(kTimedoffset) = bx;
-}
-
void DreamGenContext::edenscdplayer() {
STACK_CHECK;
showfirstuse();
@@ -16137,46 +15053,6 @@ notsecondbank1:
es = pop();
}
-void DreamGenContext::makenextblock() {
- STACK_CHECK;
- volumeadjust();
- loopchannel0();
- _cmp(data.word(kCh1blockstocopy), 0);
- if (flags.z())
- goto mightbeonlych0;
- _cmp(data.word(kCh0blockstocopy), 0);
- if (flags.z())
- goto mightbeonlych1;
- _dec(data.word(kCh0blockstocopy));
- _dec(data.word(kCh1blockstocopy));
- bothchannels();
- return;
-mightbeonlych1:
- data.byte(kCh0playing) = 255;
- _cmp(data.word(kCh1blockstocopy), 0);
- if (flags.z())
- return /* (notch1only) */;
- _dec(data.word(kCh1blockstocopy));
- channel1only();
- return;
-mightbeonlych0:
- data.byte(kCh1playing) = 255;
- _cmp(data.word(kCh0blockstocopy), 0);
- if (flags.z())
- goto notch0only;
- _dec(data.word(kCh0blockstocopy));
- channel0only();
- return;
-notch0only:
- es = data.word(kSoundbuffer);
- di = data.word(kSoundbufferwrite);
- cx = 1024;
- ax = 0x7f7f;
- _stosw(cx, true);
- _and(di, 16384-1);
- data.word(kSoundbufferwrite) = di;
-}
-
void DreamGenContext::volumeadjust() {
STACK_CHECK;
al = data.byte(kVolumedirection);
@@ -16198,162 +15074,6 @@ volfinish:
data.byte(kVolumedirection) = 0;
}
-void DreamGenContext::loopchannel0() {
- STACK_CHECK;
- _cmp(data.word(kCh0blockstocopy), 0);
- if (!flags.z())
- return /* (notloop) */;
- _cmp(data.byte(kCh0repeat), 0);
- if (flags.z())
- return /* (notloop) */;
- _cmp(data.byte(kCh0repeat), 255);
- if (flags.z())
- goto endlessloop;
- _dec(data.byte(kCh0repeat));
-endlessloop:
- ax = data.word(kCh0oldemmpage);
- data.word(kCh0emmpage) = ax;
- ax = data.word(kCh0oldoffset);
- data.word(kCh0offset) = ax;
- ax = data.word(kCh0blockstocopy);
- _add(ax, data.word(kCh0oldblockstocopy));
- data.word(kCh0blockstocopy) = ax;
-}
-
-void DreamGenContext::channel0tran() {
- STACK_CHECK;
- _cmp(data.byte(kVolume), 0);
- if (!flags.z())
- goto lowvolumetran;
- cx = 1024;
- _movsw(cx, true);
- return;
-lowvolumetran:
- cx = 1024;
- bh = data.byte(kVolume);
- bl = 0;
- _add(bx, 16384-256);
-volloop:
- _lodsw();
- bl = al;
- al = es.byte(bx);
- bl = ah;
- ah = es.byte(bx);
- _stosw();
- if (--cx)
- goto volloop;
-}
-
-void DreamGenContext::domix() {
- STACK_CHECK;
- _cmp(data.byte(kVolume), 0);
- if (!flags.z())
- goto lowvolumemix;
-slow:
- _lodsb();
- ah = ds.byte(bx);
- _inc(bx);
- _cmp(al, dh);
- if (!flags.c())
- goto toplot;
- _cmp(ah, dh);
- if (!flags.c())
- goto nodistort;
- _add(al, ah);
- if (flags.s())
- goto botok;
- _xor(al, al);
- _stosb();
- if (--cx)
- goto slow;
- return /* (doneit) */;
-botok:
- _xor(al, dh);
- _stosb();
- if (--cx)
- goto slow;
- return /* (doneit) */;
-toplot:
- _cmp(ah, dh);
- if (flags.c())
- goto nodistort;
- _add(al, ah);
- if (!flags.s())
- goto topok;
- al = dl;
- _stosb();
- if (--cx)
- goto slow;
- return /* (doneit) */;
-topok:
- _xor(al, dh);
- _stosb();
- if (--cx)
- goto slow;
- return /* (doneit) */;
-nodistort:
- _add(al, ah);
- _xor(al, dh);
- _stosb();
- if (--cx)
- goto slow;
- return /* (doneit) */;
-lowvolumemix:
- _lodsb();
- push(bx);
- bh = data.byte(kVolume);
- _add(bh, 63);
- bl = al;
- al = es.byte(bx);
- bx = pop();
- ah = ds.byte(bx);
- _inc(bx);
- _cmp(al, dh);
- if (!flags.c())
- goto toplotv;
- _cmp(ah, dh);
- if (!flags.c())
- goto nodistortv;
- _add(al, ah);
- if (flags.s())
- goto botokv;
- _xor(al, al);
- _stosb();
- if (--cx)
- goto lowvolumemix;
- return /* (doneit) */;
-botokv:
- _xor(al, dh);
- _stosb();
- if (--cx)
- goto lowvolumemix;
- return /* (doneit) */;
-toplotv:
- _cmp(ah, dh);
- if (flags.c())
- goto nodistortv;
- _add(al, ah);
- if (!flags.s())
- goto topokv;
- al = dl;
- _stosb();
- if (--cx)
- goto lowvolumemix;
- return /* (doneit) */;
-topokv:
- _xor(al, dh);
- _stosb();
- if (--cx)
- goto lowvolumemix;
- return /* (doneit) */;
-nodistortv:
- _add(al, ah);
- _xor(al, dh);
- _stosb();
- if (--cx)
- goto lowvolumemix;
-}
-
void DreamGenContext::entrytexts() {
STACK_CHECK;
_cmp(data.byte(kLocation), 21);
@@ -16776,84 +15496,6 @@ void DreamGenContext::clearrest() {
deallocatemem();
}
-void DreamGenContext::parseblaster() {
- STACK_CHECK;
-lookattail:
- al = es.byte(bx);
- _cmp(al, 0);
- if (flags.z())
- return /* (endtail) */;
- _cmp(al, 13);
- if (flags.z())
- return /* (endtail) */;
- _cmp(al, 'i');
- if (flags.z())
- goto issoundint;
- _cmp(al, 'I');
- if (flags.z())
- goto issoundint;
- _cmp(al, 'b');
- if (flags.z())
- goto isbright;
- _cmp(al, 'B');
- if (flags.z())
- goto isbright;
- _cmp(al, 'a');
- if (flags.z())
- goto isbaseadd;
- _cmp(al, 'A');
- if (flags.z())
- goto isbaseadd;
- _cmp(al, 'n');
- if (flags.z())
- goto isnosound;
- _cmp(al, 'N');
- if (flags.z())
- goto isnosound;
- _cmp(al, 'd');
- if (flags.z())
- goto isdma;
- _cmp(al, 'D');
- if (flags.z())
- goto isdma;
- _inc(bx);
- if (--cx)
- goto lookattail;
- return;
-issoundint:
- al = es.byte(bx+1);
- _sub(al, '0');
- data.byte(kSoundint) = al;
- _inc(bx);
- goto lookattail;
-isdma:
- al = es.byte(bx+1);
- _sub(al, '0');
- data.byte(kSounddmachannel) = al;
- _inc(bx);
- goto lookattail;
-isbaseadd:
- push(cx);
- al = es.byte(bx+2);
- _sub(al, '0');
- ah = 0;
- cl = 4;
- _shl(ax, cl);
- _add(ax, 0x200);
- data.word(kSoundbaseadd) = ax;
- cx = pop();
- _inc(bx);
- goto lookattail;
-isbright:
- data.byte(kBrightness) = 1;
- _inc(bx);
- goto lookattail;
-isnosound:
- data.byte(kSoundint) = 255;
- _inc(bx);
- goto lookattail;
-}
-
void DreamGenContext::startup() {
STACK_CHECK;
data.byte(kCurrentkey) = 0;
@@ -17488,69 +16130,6 @@ nothingund:
blank();
}
-void DreamGenContext::checkifperson() {
- STACK_CHECK;
- es = data.word(kBuffers);
- bx = (0+(228*13)+32+60+(32*32)+(11*10*3)+768+768+768+(32*32)+(128*5)+(80*5)+(100*5));
- cx = 12;
-identifyreel:
- push(cx);
- _cmp(es.byte(bx+4), 255);
- if (flags.z())
- goto notareelid;
- push(es);
- push(bx);
- push(ax);
- ax = es.word(bx+0);
- data.word(kReelpointer) = ax;
- getreelstart();
- _cmp(es.word(si+2), 0x0ffff);
- if (!flags.z())
- goto notblankpers;
- _add(si, 5);
-notblankpers:
- cx = es.word(si+2);
- ax = es.word(si+0);
- push(cx);
- getreelframeax();
- cx = pop();
- _add(cl, es.byte(bx+4));
- _add(ch, es.byte(bx+5));
- dx = cx;
- _add(dl, es.byte(bx+0));
- _add(dh, es.byte(bx+1));
- ax = pop();
- bx = pop();
- es = pop();
- _cmp(al, cl);
- if (flags.c())
- goto notareelid;
- _cmp(ah, ch);
- if (flags.c())
- goto notareelid;
- _cmp(al, dl);
- if (!flags.c())
- goto notareelid;
- _cmp(ah, dh);
- if (!flags.c())
- goto notareelid;
- cx = pop();
- ax = es.word(bx+2);
- data.word(kPersondata) = ax;
- al = es.byte(bx+4);
- ah = 5;
- obname();
- al = 0;
- _cmp(al, 1);
- return;
-notareelid:
- cx = pop();
- _add(bx, 5);
- _dec(cx);
- if (!flags.z())
- goto identifyreel;
-}
-
void DreamGenContext::checkifset() {
STACK_CHECK;
es = data.word(kBuffers);
@@ -18184,60 +16763,6 @@ void DreamGenContext::examineobtext() {
commandwithob();
}
-void DreamGenContext::commandwithob() {
- STACK_CHECK;
- push(ax);
- push(ax);
- push(bx);
- push(cx);
- push(dx);
- push(es);
- push(ds);
- push(si);
- push(di);
- deltextline();
- di = pop();
- si = pop();
- ds = pop();
- es = pop();
- dx = pop();
- cx = pop();
- bx = pop();
- ax = pop();
- push(bx);
- ah = 0;
- _add(ax, ax);
- bx = ax;
- es = data.word(kCommandtext);
- ax = es.word(bx);
- _add(ax, (66*2));
- si = ax;
- di = data.word(kTextaddressx);
- bx = data.word(kTextaddressy);
- dl = data.byte(kTextlen);
- al = 0;
- ah = 0;
- printdirect();
- ax = pop();
- di = 5847;
- copyname();
- ax = pop();
- di = data.word(kLastxpos);
- _cmp(al, 0);
- if (flags.z())
- goto noadd;
- _add(di, 5);
-noadd:
- bx = data.word(kTextaddressy);
- es = cs;
- si = 5847;
- dl = data.byte(kTextlen);
- al = 0;
- ah = 0;
- printdirect();
- data.byte(kNewtextline) = 1;
-}
-
void DreamGenContext::commandonly() {
STACK_CHECK;
push(ax);
@@ -18402,109 +16927,6 @@ holdingreel:
data.byte(kWatchmode) = 2;
}
-void DreamGenContext::autosetwalk() {
- STACK_CHECK;
- al = data.byte(kManspath);
- _cmp(data.byte(kFinaldest), al);
- if (!flags.z())
- goto notsamealready;
- return;
-notsamealready:
- getroomspaths();
- checkdest();
- push(bx);
- al = data.byte(kManspath);
- ah = 0;
- _add(ax, ax);
- _add(ax, ax);
- _add(ax, ax);
- _add(bx, ax);
- al = es.byte(bx);
- ah = 0;
- _sub(ax, 12);
- data.word(kLinestartx) = ax;
- al = es.byte(bx+1);
- ah = 0;
- _sub(ax, 12);
- data.word(kLinestarty) = ax;
- bx = pop();
- al = data.byte(kDestination);
- ah = 0;
- _add(ax, ax);
- _add(ax, ax);
- _add(ax, ax);
- _add(bx, ax);
- al = es.byte(bx);
- ah = 0;
- _sub(ax, 12);
- data.word(kLineendx) = ax;
- al = es.byte(bx+1);
- ah = 0;
- _sub(ax, 12);
- data.word(kLineendy) = ax;
- bresenhams();
- _cmp(data.byte(kLinedirection), 0);
- if (flags.z())
- goto normalline;
- al = data.byte(kLinelength);
- _dec(al);
- data.byte(kLinepointer) = al;
- data.byte(kLinedirection) = 1;
- return;
-normalline:
- data.byte(kLinepointer) = 0;
-}
-
-void DreamGenContext::checkdest() {
- STACK_CHECK;
- push(bx);
- _add(bx, 12*8);
- ah = data.byte(kManspath);
- cl = 4;
- _shl(ah, cl);
- al = data.byte(kDestination);
- cl = 24;
- ch = data.byte(kDestination);
-checkdestloop:
- dh = es.byte(bx);
- _and(dh, 0xf0);
- dl = es.byte(bx);
- _and(dl, 0xf);
- _cmp(ax, dx);
- if (!flags.z())
- goto nextcheck;
- al = es.byte(bx+1);
- _and(al, 15);
- data.byte(kDestination) = al;
- bx = pop();
- return;
-nextcheck:
- dl = es.byte(bx);
- _and(dl, 0xf0);
- _shr(dl, 1);
- _shr(dl, 1);
- _shr(dl, 1);
- _shr(dl, 1);
- dh = es.byte(bx);
- _and(dh, 0xf);
- _shl(dh, 1);
- _shl(dh, 1);
- _shl(dh, 1);
- _shl(dh, 1);
- _cmp(ax, dx);
- if (!flags.z())
- goto nextcheck2;
- ch = es.byte(bx+1);
- _and(ch, 15);
-nextcheck2:
- _add(bx, 2);
- _dec(cl);
- if (!flags.z())
- goto checkdestloop;
- data.byte(kDestination) = ch;
- bx = pop();
-}
-
void DreamGenContext::bresenhams() {
STACK_CHECK;
workoutframes();
@@ -18720,106 +17142,6 @@ success:
data.byte(kTurndirection) = 0;
}
-void DreamGenContext::getroomspaths() {
- STACK_CHECK;
- al = data.byte(kRoomnum);
- ah = 0;
- cx = 144;
- _mul(cx);
- es = data.word(kReels);
- bx = (0);
- _add(bx, ax);
-}
-
-void DreamGenContext::copyname() {
- STACK_CHECK;
- push(di);
- findobname();
- di = pop();
- es = cs;
- cx = 28;
-make:
- _lodsb();
- _cmp(al, ':');
- if (flags.z())
- goto finishmakename;
- _cmp(al, 0);
- if (flags.z())
- goto finishmakename;
- _stosb();
- if (--cx)
- goto make;
-finishmakename:
- _inc(cx);
- al = 0;
- _stosb();
- return;
- al = 255;
- _stosb(cx, true);
-}
-
-void DreamGenContext::findobname() {
- STACK_CHECK;
- push(ax);
- ah = 0;
- _add(ax, ax);
- bx = ax;
- ax = pop();
- _cmp(ah, 5);
- if (!flags.z())
- goto notpersonname;
- push(ax);
- _and(al, 127);
- ah = 0;
- bx = 64*2;
- _mul(bx);
- si = ax;
- ds = data.word(kPeople);
- _add(si, (0+24));
- cx = (0+24+(1026*2));
- ax = ds.word(si);
- _add(ax, cx);
- si = ax;
- ax = pop();
- return;
-notpersonname:
- _cmp(ah, 4);
- if (!flags.z())
- goto notextraname;
- ds = data.word(kExtras);
- _add(bx, (0+2080+30000+(16*114)));
- ax = ds.word(bx);
- _add(ax, (0+2080+30000+(16*114)+((114+2)*2)));
- si = ax;
- return;
-notextraname:
- _cmp(ah, 2);
- if (!flags.z())
- goto notfreename;
- ds = data.word(kFreedesc);
- _add(bx, (0));
- ax = ds.word(bx);
- _add(ax, (0+(82*2)));
- si = ax;
- return;
-notfreename:
- _cmp(ah, 1);
- if (!flags.z())
- goto notsetname;
- ds = data.word(kSetdesc);
- _add(bx, (0));
- ax = ds.word(bx);
- _add(ax, (0+(130*2)));
- si = ax;
- return;
-notsetname:
- ds = data.word(kBlockdesc);
- _add(bx, (0));
- ax = ds.word(bx);
- _add(ax, (0+(98*2)));
- si = ax;
-}
-
void DreamGenContext::showicon() {
STACK_CHECK;
_cmp(data.byte(kReallocation), 50);
@@ -18924,22 +17246,6 @@ void DreamGenContext::showman() {
showframe();
}
-void DreamGenContext::showpanel() {
- STACK_CHECK;
- ds = data.word(kIcons1);
- di = 72;
- bx = 0;
- al = 19;
- ah = 0;
- showframe();
- ds = data.word(kIcons1);
- di = 192;
- bx = 0;
- al = 19;
- ah = 0;
- showframe();
-}
-
void DreamGenContext::roomname() {
STACK_CHECK;
di = 88;
@@ -19248,32 +17554,6 @@ void DreamGenContext::putunderzoom() {
multiput();
}
-void DreamGenContext::crosshair() {
- STACK_CHECK;
- _cmp(data.byte(kCommandtype), 3);
- if (flags.z())
- goto nocross;
- _cmp(data.byte(kCommandtype), 10);
- if (!flags.c())
- goto nocross;
- es = data.word(kWorkspace);
- ds = data.word(kIcons1);
- di = (8)+24;
- bx = (132)+19;
- al = 9;
- ah = 0;
- showframe();
- return;
-nocross:
- es = data.word(kWorkspace);
- ds = data.word(kIcons1);
- di = (8)+24;
- bx = (132)+19;
- al = 29;
- ah = 0;
- showframe();
-}
-
void DreamGenContext::showpointer() {
STACK_CHECK;
showblink();
@@ -19446,22 +17726,6 @@ _tmp1:
multiget();
}
-void DreamGenContext::deltextline() {
- STACK_CHECK;
- di = data.word(kTextaddressx);
- bx = data.word(kTextaddressy);
- _cmp(data.byte(kForeignrelease), 0);
- if (flags.z())
- goto _tmp1;
- _sub(bx, 3);
-_tmp1:
- ds = data.word(kBuffers);
- si = (0);
- cl = (228);
- ch = (13);
- multiput();
-}
-
void DreamGenContext::animpointer() {
STACK_CHECK;
_cmp(data.byte(kPointermode), 2);
@@ -19941,142 +18205,6 @@ blimey:
es = pop();
}
-void DreamGenContext::startloading() {
- STACK_CHECK;
- data.byte(kCombatcount) = 0;
- al = cs.byte(bx+13);
- data.byte(kRoomssample) = al;
- al = cs.byte(bx+15);
- data.byte(kMapx) = al;
- al = cs.byte(bx+16);
- data.byte(kMapy) = al;
- al = cs.byte(bx+20);
- data.byte(kLiftflag) = al;
- al = cs.byte(bx+21);
- data.byte(kManspath) = al;
- data.byte(kDestination) = al;
- data.byte(kFinaldest) = al;
- al = cs.byte(bx+22);
- data.byte(kFacing) = al;
- data.byte(kTurntoface) = al;
- al = cs.byte(bx+23);
- data.byte(kCounttoopen) = al;
- al = cs.byte(bx+24);
- data.byte(kLiftpath) = al;
- al = cs.byte(bx+25);
- data.byte(kDoorpath) = al;
- data.byte(kLastweapon) = -1;
- al = cs.byte(bx+27);
- push(ax);
- al = cs.byte(bx+31);
- ah = data.byte(kReallocation);
- data.byte(kReallocation) = al;
- dx = bx;
- openfile();
- readheader();
- allocateload();
- ds = ax;
- data.word(kBackdrop) = ax;
- dx = (0);
- loadseg();
- ds = data.word(kWorkspace);
- dx = (0);
- cx = 132*66;
- al = 0;
- fillspace();
- loadseg();
- sortoutmap();
- allocateload();
- data.word(kSetframes) = ax;
- ds = ax;
- dx = (0);
- loadseg();
- ds = data.word(kSetdat);
- dx = 0;
- cx = (64*128);
- al = 255;
- fillspace();
- loadseg();
- allocateload();
- data.word(kReel1) = ax;
- ds = ax;
- dx = 0;
- loadseg();
- allocateload();
- data.word(kReel2) = ax;
- ds = ax;
- dx = 0;
- loadseg();
- allocateload();
- data.word(kReel3) = ax;
- ds = ax;
- dx = 0;
- loadseg();
- allocateload();
- data.word(kReels) = ax;
- ds = ax;
- dx = 0;
- loadseg();
- allocateload();
- data.word(kPeople) = ax;
- ds = ax;
- dx = 0;
- loadseg();
- allocateload();
- data.word(kSetdesc) = ax;
- ds = ax;
- dx = 0;
- loadseg();
- allocateload();
- data.word(kBlockdesc) = ax;
- ds = ax;
- dx = 0;
- loadseg();
- allocateload();
- data.word(kRoomdesc) = ax;
- ds = ax;
- dx = 0;
- loadseg();
- allocateload();
- data.word(kFreeframes) = ax;
- ds = ax;
- dx = 0;
- loadseg();
- ds = data.word(kFreedat);
- dx = 0;
- cx = (16*80);
- al = 255;
- fillspace();
- loadseg();
- allocateload();
- data.word(kFreedesc) = ax;
- ds = ax;
- dx = (0);
- loadseg();
- closefile();
- findroominloc();
- deletetaken();
- setallchanges();
- autoappear();
- al = data.byte(kNewlocation);
- getroomdata();
- data.byte(kLastweapon) = -1;
- data.byte(kMandead) = 0;
- data.word(kLookcounter) = 160;
- data.byte(kNewlocation) = 255;
- data.byte(kLinepointer) = 254;
- ax = pop();
- _cmp(al, 255);
- if (flags.z())
- goto dontwalkin;
- data.byte(kManspath) = al;
- push(bx);
- autosetwalk();
- bx = pop();
-dontwalkin:
- findxyfrompath();
-}
-
void DreamGenContext::disablepath() {
STACK_CHECK;
push(cx);
@@ -20146,25 +18274,6 @@ lookx:
data.byte(kRoomnum) = cl;
}
-void DreamGenContext::getroomdata() {
- STACK_CHECK;
- ah = 0;
- cx = 32;
- _mul(cx);
- bx = 6187;
- _add(bx, ax);
-}
-
-void DreamGenContext::readheader() {
- STACK_CHECK;
- ds = cs;
- dx = 6091;
- cx = (6187-6091);
- readfromfile();
- es = cs;
- di = 6141;
-}
-
void DreamGenContext::allocateload() {
STACK_CHECK;
push(es);
@@ -20177,23 +18286,6 @@ void DreamGenContext::allocateload() {
es = pop();
}
-void DreamGenContext::fillspace() {
- STACK_CHECK;
- push(es);
- push(ds);
- push(dx);
- push(di);
- push(bx);
- di = dx;
- es = ds;
- _stosb(cx, true);
- bx = pop();
- di = pop();
- dx = pop();
- ds = pop();
- es = pop();
-}
-
void DreamGenContext::getridoftemp() {
STACK_CHECK;
es = data.word(kTempgraphics);
@@ -20912,8 +19004,6 @@ void DreamGenContext::__dispatch_call(uint16 addr) {
case addr_priest: priest(); break;
case addr_madmanstelly: madmanstelly(); break;
case addr_madman: madman(); break;
- case addr_madmantext: madmantext(); break;
- case addr_madmode: madmode(); break;
case addr_priesttext: priesttext(); break;
case addr_textforend: textforend(); break;
case addr_textformonk: textformonk(); break;
@@ -20923,14 +19013,10 @@ void DreamGenContext::__dispatch_call(uint16 addr) {
case addr_sparky: sparky(); break;
case addr_train: train(); break;
case addr_addtopeoplelist: addtopeoplelist(); break;
- case addr_showgamereel: showgamereel(); break;
case addr_checkspeed: checkspeed(); break;
case addr_delsprite: delsprite(); break;
case addr_checkone: checkone(); break;
- case addr_findsource: findsource(); break;
case addr_mainman: mainman(); break;
- case addr_aboutturn: aboutturn(); break;
- case addr_facerightway: facerightway(); break;
case addr_checkforexit: checkforexit(); break;
case addr_adjustdown: adjustdown(); break;
case addr_adjustup: adjustup(); break;
@@ -20940,28 +19026,16 @@ void DreamGenContext::__dispatch_call(uint16 addr) {
case addr_initrain: initrain(); break;
case addr_splitintolines: splitintolines(); break;
case addr_getblockofpixel: getblockofpixel(); break;
- case addr_showrain: showrain(); break;
case addr_backobject: backobject(); break;
case addr_liftnoise: liftnoise(); break;
case addr_random: random(); break;
case addr_steady: steady(); break;
case addr_constant: constant(); break;
- case addr_doorway: doorway(); break;
- case addr_widedoor: widedoor(); break;
- case addr_lockeddoorway: lockeddoorway(); break;
- case addr_updatepeople: updatepeople(); break;
- case addr_getreelframeax: getreelframeax(); break;
case addr_reelsonscreen: reelsonscreen(); break;
- case addr_plotreel: plotreel(); break;
case addr_soundonreels: soundonreels(); break;
case addr_reconstruct: reconstruct(); break;
- case addr_dealwithspecial: dealwithspecial(); break;
- case addr_movemap: movemap(); break;
- case addr_getreelstart: getreelstart(); break;
- case addr_showreelframe: showreelframe(); break;
case addr_deleverything: deleverything(); break;
case addr_dumpeverything: dumpeverything(); break;
- case addr_allocatework: allocatework(); break;
case addr_showpcx: showpcx(); break;
case addr_loadpalfromiff: loadpalfromiff(); break;
case addr_setmode: setmode(); break;
@@ -20971,12 +19045,9 @@ void DreamGenContext::__dispatch_call(uint16 addr) {
case addr_pixelcheckset: pixelcheckset(); break;
case addr_createpanel: createpanel(); break;
case addr_createpanel2: createpanel2(); break;
- case addr_clearwork: clearwork(); break;
case addr_vsync: vsync(); break;
case addr_doshake: doshake(); break;
- case addr_zoom: zoom(); break;
case addr_delthisone: delthisone(); break;
- case addr_doblocks: doblocks(); break;
case addr_transferinv: transferinv(); break;
case addr_transfermap: transfermap(); break;
case addr_fadedos: fadedos(); break;
@@ -21099,7 +19170,6 @@ void DreamGenContext::__dispatch_call(uint16 addr) {
case addr_addlength: addlength(); break;
case addr_drawflags: drawflags(); break;
case addr_showallobs: showallobs(); break;
- case addr_makebackob: makebackob(); break;
case addr_showallfree: showallfree(); break;
case addr_showallex: showallex(); break;
case addr_calcfrframe: calcfrframe(); break;
@@ -21276,9 +19346,7 @@ void DreamGenContext::__dispatch_call(uint16 addr) {
case addr_setallchanges: setallchanges(); break;
case addr_dochange: dochange(); break;
case addr_autoappear: autoappear(); break;
- case addr_dumptimedtext: dumptimedtext(); break;
case addr_setuptimeduse: setuptimeduse(); break;
- case addr_setuptimedtemp: setuptimedtemp(); break;
case addr_edenscdplayer: edenscdplayer(); break;
case addr_usewall: usewall(); break;
case addr_usechurchgate: usechurchgate(); break;
@@ -21398,16 +19466,12 @@ void DreamGenContext::__dispatch_call(uint16 addr) {
case addr_out22c: out22c(); break;
case addr_playchannel0: playchannel0(); break;
case addr_playchannel1: playchannel1(); break;
- case addr_makenextblock: makenextblock(); break;
case addr_volumeadjust: volumeadjust(); break;
- case addr_loopchannel0: loopchannel0(); break;
case addr_channel0only: channel0only(); break;
case addr_channel1only: channel1only(); break;
- case addr_channel0tran: channel0tran(); break;
case addr_bothchannels: bothchannels(); break;
case addr_saveems: saveems(); break;
case addr_restoreems: restoreems(); break;
- case addr_domix: domix(); break;
case addr_dmaend: dmaend(); break;
case addr_startdmablock: startdmablock(); break;
case addr_setuppit: setuppit(); break;
@@ -21430,7 +19494,6 @@ void DreamGenContext::__dispatch_call(uint16 addr) {
case addr_clearrest: clearrest(); break;
case addr_deallocatemem: deallocatemem(); break;
case addr_allocatemem: allocatemem(); break;
- case addr_parseblaster: parseblaster(); break;
case addr_startup: startup(); break;
case addr_startup1: startup1(); break;
case addr_screenupdate: screenupdate(); break;
@@ -21448,7 +19511,6 @@ void DreamGenContext::__dispatch_call(uint16 addr) {
case addr_madmanrun: madmanrun(); break;
case addr_checkcoords: checkcoords(); break;
case addr_identifyob: identifyob(); break;
- case addr_checkifperson: checkifperson(); break;
case addr_checkifset: checkifset(); break;
case addr_checkifex: checkifex(); break;
case addr_checkiffree: checkiffree(); break;
@@ -21467,7 +19529,6 @@ void DreamGenContext::__dispatch_call(uint16 addr) {
case addr_obname: obname(); break;
case addr_finishedwalking: finishedwalking(); break;
case addr_examineobtext: examineobtext(); break;
- case addr_commandwithob: commandwithob(); break;
case addr_commandonly: commandonly(); break;
case addr_printmessage: printmessage(); break;
case addr_printmessage2: printmessage2(); break;
@@ -21476,17 +19537,11 @@ void DreamGenContext::__dispatch_call(uint16 addr) {
case addr_walktotext: walktotext(); break;
case addr_getflagunderp: getflagunderp(); break;
case addr_setwalk: setwalk(); break;
- case addr_autosetwalk: autosetwalk(); break;
- case addr_checkdest: checkdest(); break;
case addr_bresenhams: bresenhams(); break;
case addr_workoutframes: workoutframes(); break;
- case addr_getroomspaths: getroomspaths(); break;
- case addr_copyname: copyname(); break;
- case addr_findobname: findobname(); break;
case addr_showicon: showicon(); break;
case addr_middlepanel: middlepanel(); break;
case addr_showman: showman(); break;
- case addr_showpanel: showpanel(); break;
case addr_roomname: roomname(); break;
case addr_usecharset1: usecharset1(); break;
case addr_usetempcharset: usetempcharset(); break;
@@ -21506,12 +19561,10 @@ void DreamGenContext::__dispatch_call(uint16 addr) {
case addr_getunderzoom: getunderzoom(); break;
case addr_dumpzoom: dumpzoom(); break;
case addr_putunderzoom: putunderzoom(); break;
- case addr_crosshair: crosshair(); break;
case addr_showpointer: showpointer(); break;
case addr_delpointer: delpointer(); break;
case addr_dumppointer: dumppointer(); break;
case addr_undertextline: undertextline(); break;
- case addr_deltextline: deltextline(); break;
case addr_animpointer: animpointer(); break;
case addr_setmouse: setmouse(); break;
case addr_readmouse: readmouse(); break;
@@ -21538,15 +19591,11 @@ void DreamGenContext::__dispatch_call(uint16 addr) {
case addr_restorereels: restorereels(); break;
case addr_restoreall: restoreall(); break;
case addr_sortoutmap: sortoutmap(); break;
- case addr_startloading: startloading(); break;
case addr_disablepath: disablepath(); break;
case addr_findxyfrompath: findxyfrompath(); break;
case addr_findroominloc: findroominloc(); break;
- case addr_getroomdata: getroomdata(); break;
- case addr_readheader: readheader(); break;
case addr_dontloadseg: dontloadseg(); break;
case addr_allocateload: allocateload(); break;
- case addr_fillspace: fillspace(); break;
case addr_getridoftemp: getridoftemp(); break;
case addr_getridoftemptext: getridoftemptext(); break;
case addr_getridoftemp2: getridoftemp2(); break;
diff --git a/engines/dreamweb/dreamgen.h b/engines/dreamweb/dreamgen.h
index c2aa204942..e1071dfebc 100644
--- a/engines/dreamweb/dreamgen.h
+++ b/engines/dreamweb/dreamgen.h
@@ -57,15 +57,11 @@ public:
static const uint16 addr_getridoftemp2 = 0xcb78;
static const uint16 addr_getridoftemptext = 0xcb74;
static const uint16 addr_getridoftemp = 0xcb70;
- static const uint16 addr_fillspace = 0xcb6c;
static const uint16 addr_allocateload = 0xcb68;
static const uint16 addr_dontloadseg = 0xcb64;
- static const uint16 addr_readheader = 0xcb60;
- static const uint16 addr_getroomdata = 0xcb5c;
static const uint16 addr_findroominloc = 0xcb58;
static const uint16 addr_findxyfrompath = 0xcb54;
static const uint16 addr_disablepath = 0xcb50;
- static const uint16 addr_startloading = 0xcb4c;
static const uint16 addr_sortoutmap = 0xcb48;
static const uint16 addr_restoreall = 0xcb44;
static const uint16 addr_restorereels = 0xcb40;
@@ -92,12 +88,10 @@ public:
static const uint16 addr_readmouse = 0xcae4;
static const uint16 addr_setmouse = 0xcae0;
static const uint16 addr_animpointer = 0xcadc;
- static const uint16 addr_deltextline = 0xcad4;
static const uint16 addr_undertextline = 0xcad0;
static const uint16 addr_dumppointer = 0xcacc;
static const uint16 addr_delpointer = 0xcac8;
static const uint16 addr_showpointer = 0xcac4;
- static const uint16 addr_crosshair = 0xcac0;
static const uint16 addr_putunderzoom = 0xcabc;
static const uint16 addr_dumpzoom = 0xcab8;
static const uint16 addr_getunderzoom = 0xcab4;
@@ -117,17 +111,11 @@ public:
static const uint16 addr_usetempcharset = 0xca7c;
static const uint16 addr_usecharset1 = 0xca78;
static const uint16 addr_roomname = 0xca74;
- static const uint16 addr_showpanel = 0xca70;
static const uint16 addr_showman = 0xca6c;
static const uint16 addr_middlepanel = 0xca68;
static const uint16 addr_showicon = 0xca64;
- static const uint16 addr_findobname = 0xca60;
- static const uint16 addr_copyname = 0xca5c;
- static const uint16 addr_getroomspaths = 0xca58;
static const uint16 addr_workoutframes = 0xca54;
static const uint16 addr_bresenhams = 0xca50;
- static const uint16 addr_checkdest = 0xca4c;
- static const uint16 addr_autosetwalk = 0xca48;
static const uint16 addr_setwalk = 0xca44;
static const uint16 addr_getflagunderp = 0xca40;
static const uint16 addr_walktotext = 0xca3c;
@@ -136,7 +124,6 @@ public:
static const uint16 addr_printmessage2 = 0xca30;
static const uint16 addr_printmessage = 0xca2c;
static const uint16 addr_commandonly = 0xca28;
- static const uint16 addr_commandwithob = 0xca24;
static const uint16 addr_examineobtext = 0xca20;
static const uint16 addr_finishedwalking = 0xca1c;
static const uint16 addr_obname = 0xca18;
@@ -155,7 +142,6 @@ public:
static const uint16 addr_checkiffree = 0xc9e4;
static const uint16 addr_checkifex = 0xc9e0;
static const uint16 addr_checkifset = 0xc9dc;
- static const uint16 addr_checkifperson = 0xc9d8;
static const uint16 addr_identifyob = 0xc9d4;
static const uint16 addr_checkcoords = 0xc9d0;
static const uint16 addr_madmanrun = 0xc9cc;
@@ -174,7 +160,6 @@ public:
static const uint16 addr_screenupdate = 0xc99c;
static const uint16 addr_startup1 = 0xc998;
static const uint16 addr_startup = 0xc994;
- static const uint16 addr_parseblaster = 0xc990;
static const uint16 addr_allocatemem = 0xc988;
static const uint16 addr_deallocatemem = 0xc984;
static const uint16 addr_clearrest = 0xc980;
@@ -196,16 +181,12 @@ public:
static const uint16 addr_setuppit = 0xc93c;
static const uint16 addr_startdmablock = 0xc938;
static const uint16 addr_dmaend = 0xc934;
- static const uint16 addr_domix = 0xc930;
static const uint16 addr_restoreems = 0xc92c;
static const uint16 addr_saveems = 0xc928;
static const uint16 addr_bothchannels = 0xc924;
- static const uint16 addr_channel0tran = 0xc920;
static const uint16 addr_channel1only = 0xc91c;
static const uint16 addr_channel0only = 0xc918;
- static const uint16 addr_loopchannel0 = 0xc90c;
static const uint16 addr_volumeadjust = 0xc908;
- static const uint16 addr_makenextblock = 0xc904;
static const uint16 addr_playchannel1 = 0xc900;
static const uint16 addr_playchannel0 = 0xc8fc;
static const uint16 addr_out22c = 0xc8f8;
@@ -327,9 +308,7 @@ public:
static const uint16 addr_usechurchgate = 0xc730;
static const uint16 addr_usewall = 0xc72c;
static const uint16 addr_edenscdplayer = 0xc728;
- static const uint16 addr_setuptimedtemp = 0xc720;
static const uint16 addr_setuptimeduse = 0xc71c;
- static const uint16 addr_dumptimedtext = 0xc718;
static const uint16 addr_autoappear = 0xc70c;
static const uint16 addr_dochange = 0xc708;
static const uint16 addr_setallchanges = 0xc704;
@@ -506,7 +485,6 @@ public:
static const uint16 addr_calcfrframe = 0xc454;
static const uint16 addr_showallex = 0xc450;
static const uint16 addr_showallfree = 0xc44c;
- static const uint16 addr_makebackob = 0xc448;
static const uint16 addr_showallobs = 0xc444;
static const uint16 addr_drawflags = 0xc43c;
static const uint16 addr_addlength = 0xc438;
@@ -629,12 +607,9 @@ public:
static const uint16 addr_fadedos = 0xc248;
static const uint16 addr_transfermap = 0xc244;
static const uint16 addr_transferinv = 0xc240;
- static const uint16 addr_doblocks = 0xc228;
static const uint16 addr_delthisone = 0xc214;
- static const uint16 addr_zoom = 0xc210;
static const uint16 addr_doshake = 0xc20c;
static const uint16 addr_vsync = 0xc208;
- static const uint16 addr_clearwork = 0xc204;
static const uint16 addr_createpanel2 = 0xc200;
static const uint16 addr_createpanel = 0xc1fc;
static const uint16 addr_pixelcheckset = 0xc1f8;
@@ -644,28 +619,16 @@ public:
static const uint16 addr_setmode = 0xc1dc;
static const uint16 addr_loadpalfromiff = 0xc1d8;
static const uint16 addr_showpcx = 0xc1cc;
- static const uint16 addr_allocatework = 0xc1c8;
static const uint16 addr_dumpeverything = 0xc1c4;
static const uint16 addr_deleverything = 0xc1c0;
- static const uint16 addr_showreelframe = 0xc1bc;
- static const uint16 addr_getreelstart = 0xc1b8;
- static const uint16 addr_movemap = 0xc1b4;
- static const uint16 addr_dealwithspecial = 0xc1b0;
static const uint16 addr_reconstruct = 0xc1ac;
static const uint16 addr_soundonreels = 0xc1a8;
- static const uint16 addr_plotreel = 0xc1a4;
static const uint16 addr_reelsonscreen = 0xc1a0;
- static const uint16 addr_getreelframeax = 0xc19c;
- static const uint16 addr_updatepeople = 0xc198;
- static const uint16 addr_lockeddoorway = 0xc194;
- static const uint16 addr_widedoor = 0xc18c;
- static const uint16 addr_doorway = 0xc188;
static const uint16 addr_constant = 0xc184;
static const uint16 addr_steady = 0xc180;
static const uint16 addr_random = 0xc17c;
static const uint16 addr_liftnoise = 0xc178;
static const uint16 addr_backobject = 0xc170;
- static const uint16 addr_showrain = 0xc16c;
static const uint16 addr_getblockofpixel = 0xc168;
static const uint16 addr_splitintolines = 0xc164;
static const uint16 addr_initrain = 0xc160;
@@ -675,14 +638,10 @@ public:
static const uint16 addr_adjustup = 0xc150;
static const uint16 addr_adjustdown = 0xc14c;
static const uint16 addr_checkforexit = 0xc148;
- static const uint16 addr_facerightway = 0xc144;
- static const uint16 addr_aboutturn = 0xc13c;
static const uint16 addr_mainman = 0xc138;
- static const uint16 addr_findsource = 0xc130;
static const uint16 addr_checkone = 0xc12c;
static const uint16 addr_delsprite = 0xc11c;
static const uint16 addr_checkspeed = 0xc110;
- static const uint16 addr_showgamereel = 0xc10c;
static const uint16 addr_addtopeoplelist = 0xc108;
static const uint16 addr_train = 0xc104;
static const uint16 addr_sparky = 0xc100;
@@ -692,8 +651,6 @@ public:
static const uint16 addr_textformonk = 0xc0f0;
static const uint16 addr_textforend = 0xc0ec;
static const uint16 addr_priesttext = 0xc0e8;
- static const uint16 addr_madmode = 0xc0e4;
- static const uint16 addr_madmantext = 0xc0e0;
static const uint16 addr_madman = 0xc0dc;
static const uint16 addr_madmanstelly = 0xc0d8;
static const uint16 addr_priest = 0xc0d4;
@@ -1323,10 +1280,10 @@ public:
void bothchannels();
void usewire();
void getnamepos();
- void drawitall();
+ void loadtemptext();
void clearstartpal();
void femalefan();
- void showgamereel();
+ //void showgamereel();
void identifyob();
void trysoundalloc();
void uselighter();
@@ -1338,7 +1295,7 @@ public:
void clearbuffers();
void neterror();
void storeit();
- void lockeddoorway();
+ //void lockeddoorway();
void isitworn();
//void putundertimed();
void dumpmap();
@@ -1356,14 +1313,14 @@ public:
void readkey();
void louis();
void entrytexts();
- void getreelstart();
+ //void getreelstart();
void buttonenter();
void checkinput();
- void crosshair();
+ //void crosshair();
void bresenhams();
void getbackfromops();
//void frameoutv();
- void restoreall();
+ void opensarters();
void screenupdate();
void addlength();
void wornerror();
@@ -1372,29 +1329,32 @@ public:
void commandonly();
void adjustlen();
void deallocatemem();
- void mainscreen();
+ void checkforemm();
void watchreel();
void showfolder();
void turnanypathoff();
void openfilefromc();
void gettime();
- void clearwork();
+ //void clearwork();
void loadtraveltext();
//void worktoscreen();
void getexpos();
void fadedos();
+ //void fillspace();
//void multiget();
+ //void autosetwalk();
void fadeupmonfirst();
void drawfloor();
void loadkeypad();
- void findsource();
+ //void findsource();
void clearendpal();
void findtext1();
void isryanholding();
- void interupttest();
+ void showslots();
void usecashcard();
void usewall();
void opentomb();
+ //void findobname();
void buttonfour();
void animpointer();
//void lockmon();
@@ -1409,8 +1369,8 @@ public:
void additionaltext();
//void kernchars();
void othersmoker();
- void autosetwalk();
- void setuptimedtemp();
+ void dofade();
+ //void setuptimedtemp();
void blocknametext();
void useelevator5();
void useelevator4();
@@ -1420,13 +1380,13 @@ public:
void useelevator2();
void buttonone();
void keyboardread();
- void deltextline();
+ //void deltextline();
void entercode();
void getopenedsize();
void getpersframe();
void doshake();
void resetkeyboard();
- void showpanel();
+ //void showpanel();
void soundstartup();
void slabdoora();
void fadeupyellows();
@@ -1450,17 +1410,16 @@ public:
void eden();
void showdiary();
void purgealocation();
- void updatepeople();
+ //void updatepeople();
void slabdoorf();
void addtopeoplelist();
void hangoncurs();
void sparkydrip();
- //void modifychar();
void compare();
void printcurs();
//void convertkey();
void outofopen();
- void dealwithspecial();
+ //void dealwithspecial();
//void eraseoldobs();
void dircom();
//void liftsprite();
@@ -1473,8 +1432,8 @@ public:
void fadescreenup();
void loadold();
void loadtempcharset();
+ void showbyte();
void useslab();
- void aboutturn();
void usealtar();
void createpanel2();
void turnonpower();
@@ -1488,7 +1447,7 @@ public:
void endgame();
void monprint();
void usepipe();
- void startloading();
+ //void startloading();
void getunderzoom();
void candles();
void backobject();
@@ -1496,7 +1455,7 @@ public:
void reminders();
void selectslot2();
void runtap();
- void domix();
+ //void domix();
void priesttext();
void paneltomap();
void obname();
@@ -1508,13 +1467,11 @@ public:
void disablesoundint();
void checkifset();
void showallex();
- void showrain();
void openpoolboss();
void buttontwo();
- void fillopen();
//void usetimedtext();
void delsprite();
- void getroomspaths();
+ //void getroomspaths();
//void dumptextline();
void fadescreendownhalf();
void useplate();
@@ -1524,9 +1481,10 @@ public:
void isitdescribed();
void hotelbell();
void loadspeech();
+ void interupttest();
//void cls();
//void printsprites();
- void checkifperson();
+ //void checkifperson();
void showallobs();
//void getnumber();
void adjustleft();
@@ -1546,6 +1504,7 @@ public:
//void printchar();
void showkeypad();
void obtoinv();
+ //void getroomdata();
void removeobfrominv();
void usecoveredbox();
void openyourneighbour();
@@ -1562,7 +1521,7 @@ public:
void discops();
//void printdirect();
void delthisone();
- void makebackob();
+ //void makebackob();
void middlepanel();
void dumpwatch();
void saveload();
@@ -1577,8 +1536,8 @@ public:
void locklightoff();
void wearwatch();
void runintroseq();
- void doblocks();
- void showbyte();
+ //void doblocks();
+ void restoreall();
void allpalette();
void findormake();
void nextsymbol();
@@ -1593,14 +1552,14 @@ public:
void folderhints();
void openhoteldoor();
void removesetobject();
- void dumptimedtext();
+ //void dumptimedtext();
//void frameoutfx();
void blank();
void drinker();
void nextcolon();
void placefreeobject();
void delpointer();
- void loopchannel0();
+ //void loopchannel0();
void initrain();
void showleftpage();
void rockstar();
@@ -1635,7 +1594,7 @@ public:
void showpointer();
void usecooker();
void loadmenu();
- void checkforemm();
+ //void aboutturn();
void checkifpathison();
void smallcandle();
void receptionist();
@@ -1656,7 +1615,7 @@ public:
void putundermenu();
void checkifex();
void intromagic2();
- void findobname();
+ void mainscreen();
void edeninbath();
void intromagic1();
void showdiarypage();
@@ -1671,12 +1630,12 @@ public:
void steady();
void pixelcheckset();
void reexfrominv();
- void fillspace();
+ void examinventory();
void talk();
void usedryer();
void dumpeverything();
void usehatch();
- void zoom();
+ //void zoom();
void outofinv();
void viewfolder();
//void walking();
@@ -1690,7 +1649,7 @@ public:
void playguitar();
void lastfolder();
void transfermap();
- void showreelframe();
+ //void showreelframe();
void showmonk();
void diarykeyn();
void set16colpalette();
@@ -1711,7 +1670,7 @@ public:
void getridofpit();
void convnum();
void nothelderror();
- void readheader();
+ //void readheader();
void getsetad();
void getyad();
void reconstruct();
@@ -1778,11 +1737,10 @@ public:
void loadintotemp2();
void gamer();
void personnametext();
- void quitsymbol();
void readfromfile();
void initialinv();
- void showslots();
- void dofade();
+ void quitsymbol();
+ //void modifychar();
void hangon();
void settopright();
void findsetobject();
@@ -1809,14 +1767,15 @@ public:
void scrollmonitor();
void setsoundoff();
void setpickup();
+ //void doorway();
void dropobject();
void printmessage();
void reexfromopen();
void fillryan();
- void loadtemptext();
+ void drawitall();
void usestereo();
void showcurrentfile();
- void copyname();
+ //void copyname();
void look();
void setmouse();
void checkone();
@@ -1832,32 +1791,32 @@ public:
void afterintroroom();
void blockget();
void usetrainer();
- void allocatework();
+ //void allocatework();
void addtopresslist();
void walkandexamine();
void dmaend();
//void quickquit2();
void twodigitnum();
- void madmantext();
+ //void madmantext();
void dumpcurrent();
void textforend();
void showdiarykeys();
void dontloadseg();
- void madmode();
+ //void madmode();
void intro3text();
void allocatemem();
void sortoutmap();
- void doorway();
+ //void showrain();
void useopened();
void inventory();
void powerlightoff();
- void getroomdata();
+ void fillopen();
void showoutermenu();
void signon();
void deleteextext();
void foghornsound();
void showrightpage();
- void openhoteldoor2();
+ void showloadops();
void examicon();
void showgun();
void switchryanon();
@@ -1869,7 +1828,7 @@ public:
void opentvdoor();
void triggermessage();
void finalframe();
- void plotreel();
+ //void plotreel();
void swapwithopen();
//void makesprite();
void dreamweb();
@@ -1883,7 +1842,6 @@ public:
void turnanypathon();
void restorereels();
void setwalk();
- //void printboth();
void useroutine();
void zoomicon();
void hotelcontrol();
@@ -1900,10 +1858,10 @@ public:
void makecaps();
void read();
void fadescreenups();
- void checkdest();
+ //void checkdest();
//void initman();
void loadpalfromiff();
- void facerightway();
+ //void facerightway();
void startup1();
void findlen();
void showsymbol();
@@ -1917,7 +1875,7 @@ public:
//void clearsprites();
void obpicture();
void selectopenob();
- void widedoor();
+ //void widedoor();
void security();
//void printasprite();
void buttonfive();
@@ -1931,7 +1889,7 @@ public:
void showman();
void readmouse2();
void newplace();
- void movemap();
+ //void movemap();
void loadsample();
void usecardreader1();
void usecardreader2();
@@ -1941,7 +1899,7 @@ public:
void quitkey();
void openfile();
void usecharset1();
- void makenextblock();
+ //void makenextblock();
void showpuztext();
void addalong();
//void width160();
@@ -1949,7 +1907,6 @@ public:
//void dodoor();
void greyscalesum();
void buttoneight();
- void opensarters();
void findexobject();
void errormessage2();
void usechurchhole();
@@ -1958,7 +1915,7 @@ public:
void fadecalculation();
void waitframes();
void clearrest();
- void getreelframeax();
+ //void getreelframeax();
void barwoman();
void roomname();
void credits();
@@ -1998,9 +1955,9 @@ public:
void redrawmainscrn();
void finishedwalking();
void findallryan();
- void channel0tran();
+ //void channel0tran();
void buttonpress();
- void parseblaster();
+ //void parseblaster();
void callhotellift();
void makemainscreen();
void intromonks2();
@@ -2034,12 +1991,12 @@ public:
void intro();
void hangonp();
void fadescreendowns();
- void showloadops();
+ void openhoteldoor2();
void getridoftempsp();
void scanfornames();
void setallchanges();
void newgame();
- void examinventory();
+ //void printboth();
void standardload();
void undertextline();
void findroominloc();
@@ -2063,7 +2020,7 @@ public:
void isitright();
void businessman();
void switchryanoff();
- void commandwithob();
+ //void commandwithob();
void panelicons1();
void adjustdown();
void withwhat();
diff --git a/engines/dreamweb/module.mk b/engines/dreamweb/module.mk
index 3b0c7f3325..6c4c506695 100644
--- a/engines/dreamweb/module.mk
+++ b/engines/dreamweb/module.mk
@@ -5,7 +5,10 @@ MODULE_OBJS := \
detection.o \
dreamweb.o \
dreamgen.o \
- stubs.o
+ print.o \
+ sprite.o \
+ stubs.o \
+ vgagrafx.o
# This module can be built as a plugin
ifeq ($(ENABLE_DREAMWEB), DYNAMIC_PLUGIN)
diff --git a/engines/dreamweb/print.cpp b/engines/dreamweb/print.cpp
new file mode 100644
index 0000000000..26084c35d1
--- /dev/null
+++ b/engines/dreamweb/print.cpp
@@ -0,0 +1,224 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "dreamweb/dreamweb.h"
+#include "engines/util.h"
+#include "graphics/surface.h"
+
+namespace DreamGen {
+
+void DreamGenContext::printboth(const Frame *charSet, uint16 *x, uint16 y, uint8 c, uint8 nextChar) {
+ uint16 newX = *x;
+ uint8 width, height;
+ printchar(charSet, &newX, y, c, nextChar, &width, &height);
+ multidump(*x, y, width, height);
+ *x = newX;
+}
+
+uint8 DreamGenContext::getnextword(const Frame *charSet, const uint8 *string, uint8 *totalWidth, uint8 *charCount) {
+ *totalWidth = 0;
+ *charCount = 0;
+ while(true) {
+ uint8 firstChar = *string;
+ ++string;
+ ++*charCount;
+ if ((firstChar == ':') || (firstChar == 0)) { //endall
+ *totalWidth += 6;
+ return 1;
+ }
+ if (firstChar == 32) { //endword
+ *totalWidth += 6;
+ return 0;
+ }
+ firstChar = engine->modifyChar(firstChar);
+ if (firstChar != 255) {
+ uint8 secondChar = *string;
+ uint8 width = charSet[firstChar - 32 + data.word(kCharshift)].width;
+ width = kernchars(firstChar, secondChar, width);
+ *totalWidth += width;
+ }
+ }
+}
+
+void DreamGenContext::printchar() {
+ uint16 x = di;
+ uint8 width, height;
+ printchar((const Frame *)ds.ptr(0, 0), &x, bx, al, ah, &width, &height);
+ di = x;
+ cl = width;
+ ch = height;
+}
+
+void DreamGenContext::printchar(const Frame *charSet, uint16* x, uint16 y, uint8 c, uint8 nextChar, uint8 *width, uint8 *height) {
+ if (c == 255)
+ return;
+ push(si);
+ push(di);
+ if (data.byte(kForeignrelease) != 0)
+ y -= 3;
+ uint16 tmp = c - 32 + data.word(kCharshift);
+ showframe(charSet, *x, y, tmp & 0x1ff, (tmp >> 8) & 0xfe, width, height);
+ di = pop();
+ si = pop();
+ _cmp(data.byte(kKerning), 0);
+ if (flags.z())
+ *width = kernchars(c, nextChar, *width);
+ (*x) += *width;
+}
+
+void DreamGenContext::printslow() {
+ al = printslow(es.ptr(si, 0), di, bx, dl, (bool)(dl & 1));
+}
+
+uint8 DreamGenContext::printslow(const uint8 *string, uint16 x, uint16 y, uint8 maxWidth, bool centered) {
+ data.byte(kPointerframe) = 1;
+ data.byte(kPointermode) = 3;
+ const Frame* charSet = (const Frame *)segRef(data.word(kCharset1)).ptr(0, 0);
+ do {
+ uint16 offset = x;
+ uint16 charCount = getnumber(charSet, string, maxWidth, centered, &offset);
+ do {
+ uint8 c0 = string[0];
+ uint8 c1 = string[1];
+ uint8 c2 = string[2];
+ c0 = engine->modifyChar(c0);
+ printboth(charSet, &offset, y, c0, c1);
+ if ((c1 == 0) || (c1 == ':')) {
+ return 0;
+ }
+ if (charCount != 1) {
+ c1 = engine->modifyChar(c1);
+ data.word(kCharshift) = 91;
+ uint16 offset2 = offset;
+ printboth(charSet, &offset2, y, c1, c2);
+ data.word(kCharshift) = 0;
+ for (int i=0; i<2; ++i) {
+ waitframes();
+ if (ax == 0)
+ continue;
+ if (ax != data.word(kOldbutton)) {
+ return 1;
+ }
+ }
+ }
+
+ ++string;
+ --charCount;
+ } while (charCount);
+ y += 10;
+ } while (true);
+}
+
+void DreamGenContext::printdirect() {
+ uint16 y = bx;
+ uint16 initialSi = si;
+ const uint8 *initialString = es.ptr(si, 0);
+ const uint8 *string = initialString;
+ printdirect(&string, di, &y, dl, (bool)(dl & 1));
+ si = initialSi + (string - initialString);
+ bx = y;
+}
+
+void DreamGenContext::printdirect(const uint8** string, uint16 x, uint16 *y, uint8 maxWidth, bool centered) {
+ data.word(kLastxpos) = x;
+ const Frame *charSet = (const Frame *)segRef(data.word(kCurrentset)).ptr(0, 0);
+ while (true) {
+ uint16 offset = x;
+ uint8 charCount = getnumber(charSet, *string, maxWidth, centered, &offset);
+ uint16 i = offset;
+ do {
+ uint8 c = (*string)[0];
+ uint8 nextChar = (*string)[1];
+ ++(*string);
+ if ((c == 0) || (c == ':')) {
+ return;
+ }
+ c = engine->modifyChar(c);
+ uint8 width, height;
+ printchar(charSet, &i, *y, c, nextChar, &width, &height);
+ data.word(kLastxpos) = i;
+ --charCount;
+ } while(charCount);
+ *y += data.word(kLinespacing);
+ }
+}
+
+void DreamGenContext::getnumber() {
+ uint16 offset = di;
+ cl = getnumber((Frame *)ds.ptr(0, 0), es.ptr(si, 0), dl, (bool)(dl & 1), &offset);
+ di = offset;
+}
+
+uint8 DreamGenContext::getnumber(const Frame *charSet, const uint8 *string, uint16 maxWidth, bool centered, uint16* offset) {
+ uint8 totalWidth = 0;
+ uint8 charCount = 0;
+ while (true) {
+ uint8 wordTotalWidth, wordCharCount;
+ uint8 done = getnextword(charSet, string, &wordTotalWidth, &wordCharCount);
+ string += wordCharCount;
+
+ if (done == 1) { //endoftext
+ ax = totalWidth + wordTotalWidth - 10;
+ if (ax < maxWidth) {
+ totalWidth += wordTotalWidth;
+ charCount += wordCharCount;
+ }
+
+ if (centered) {
+ ax = (maxWidth & 0xfe) + 2 + 20 - totalWidth;
+ ax /= 2;
+ } else {
+ ax = 0;
+ }
+ *offset += ax;
+ return charCount;
+ }
+ ax = totalWidth + wordTotalWidth - 10;
+ if (ax >= maxWidth) { //gotoverend
+ if (centered) {
+ ax = (maxWidth & 0xfe) - totalWidth + 20;
+ ax /= 2;
+ } else {
+ ax = 0;
+ }
+ *offset += ax;
+ return charCount;
+ }
+ totalWidth += wordTotalWidth;
+ charCount += wordCharCount;
+ }
+}
+
+uint8 DreamGenContext::kernchars(uint8 firstChar, uint8 secondChar, uint8 width) {
+ if ((firstChar == 'a') || (al == 'u')) {
+ if ((secondChar == 'n') || (secondChar == 't') || (secondChar == 'r') || (secondChar == 'i') || (secondChar == 'l'))
+ return width-1;
+ }
+ return width;
+}
+
+void DreamGenContext::kernchars() {
+ cl = kernchars(al, ah, cl);
+}
+
+} /*namespace dreamgen */
+
diff --git a/engines/dreamweb/runtime.h b/engines/dreamweb/runtime.h
index 0c27c12e3c..8aa71b285c 100644
--- a/engines/dreamweb/runtime.h
+++ b/engines/dreamweb/runtime.h
@@ -287,6 +287,12 @@ public:
_freeSegments.push_back(id);
}
+ SegmentRef segRef(uint16 seg) {
+ SegmentRef result(this);
+ result = seg;
+ return result;
+ }
+
inline void _cmp(uint8 a, uint8 b) {
_sub(a, b);
}
diff --git a/engines/dreamweb/sprite.cpp b/engines/dreamweb/sprite.cpp
new file mode 100644
index 0000000000..2129d1ca6d
--- /dev/null
+++ b/engines/dreamweb/sprite.cpp
@@ -0,0 +1,874 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "dreamweb/dreamweb.h"
+#include "engines/util.h"
+#include "graphics/surface.h"
+
+namespace DreamGen {
+
+Sprite *DreamGenContext::spritetable() {
+ Sprite *sprite = (Sprite *)segRef(data.word(kBuffers)).ptr(kSpritetable, 16 * sizeof(Sprite));
+ return sprite;
+}
+
+void DreamGenContext::printsprites() {
+ for (size_t priority = 0; priority < 7; ++priority) {
+ Sprite *sprites = spritetable();
+ for (size_t j = 0; j < 16; ++j) {
+ const Sprite &sprite = sprites[j];
+ if (sprite.updateCallback() == 0x0ffff)
+ continue;
+ if (priority != sprite.priority)
+ continue;
+ if (sprite.hidden == 1)
+ continue;
+ printasprite(&sprite);
+ }
+ }
+}
+
+void DreamGenContext::printasprite(const Sprite *sprite) {
+ uint16 x, y;
+ if (sprite->y >= 220) {
+ y = data.word(kMapady) - (256 - sprite->y);
+ } else {
+ y = sprite->y + data.word(kMapady);
+ }
+
+ if (sprite->x >= 220) {
+ x = data.word(kMapadx) - (256 - sprite->x);
+ } else {
+ x = sprite->x + data.word(kMapadx);
+ }
+
+ uint8 c;
+ if (sprite->b29 != 0)
+ c = 8;
+ else
+ c = 0;
+ uint8 width, height;
+ showframe((const Frame *)segRef(sprite->frameData()).ptr(0, 0), x, y, sprite->b15, c, &width, &height);
+}
+
+void DreamGenContext::clearsprites() {
+ memset(spritetable(), 0xff, sizeof(Sprite) * 16);
+}
+
+Sprite *DreamGenContext::makesprite(uint8 x, uint8 y, uint16 updateCallback, uint16 frameData, uint16 somethingInDi) {
+ Sprite *sprite = spritetable();
+ while (sprite->b15 != 0xff) { // NB: No boundchecking in the original code either
+ ++sprite;
+ }
+
+ sprite->setUpdateCallback(updateCallback);
+ sprite->x = x;
+ sprite->y = y;
+ sprite->setFrameData(frameData);
+ WRITE_LE_UINT16(&sprite->w8, somethingInDi);
+ sprite->w2 = 0xffff;
+ sprite->b15 = 0;
+ sprite->delay = 0;
+ return sprite;
+}
+
+void DreamGenContext::makesprite() { // NB: returns new sprite in es:bx
+ Sprite *sprite = makesprite(si & 0xff, si >> 8, cx, dx, di);
+
+ // Recover es:bx from sprite
+ es = data.word(kBuffers);
+ bx = kSpritetable;
+ Sprite *sprites = (Sprite *)es.ptr(bx, sizeof(Sprite) * 16);
+ bx += sizeof(Sprite) * (sprite - sprites);
+ //
+}
+
+void DreamGenContext::spriteupdate() {
+ Sprite *sprites = spritetable();
+ sprites[0].hidden = data.byte(kRyanon);
+
+ Sprite *sprite = sprites;
+ for (size_t i=0; i < 16; ++i) {
+ uint16 updateCallback = sprite->updateCallback();
+ if (updateCallback != 0xffff) {
+ sprite->w24 = sprite->w2;
+ if (updateCallback == addr_mainman) // NB : Let's consider the callback as an enum while more code is not ported to C++
+ mainman(sprite);
+ else {
+ assert(updateCallback == addr_backobject);
+ backobject(sprite);
+ }
+ }
+
+ if (data.byte(kNowinnewroom) == 1)
+ break;
+ ++sprite;
+ }
+}
+
+void DreamGenContext::initman() {
+ Sprite *sprite = makesprite(data.byte(kRyanx), data.byte(kRyany), addr_mainman, data.word(kMainsprites), 0);
+ sprite->priority = 4;
+ sprite->b22 = 0;
+ sprite->b29 = 0;
+}
+
+void DreamGenContext::mainman() {
+ assert(false);
+}
+
+void DreamGenContext::mainman(Sprite *sprite) {
+ push(es);
+ push(ds);
+
+ // Recover es:bx from sprite
+ es = data.word(kBuffers);
+ bx = kSpritetable;
+ Sprite *sprites = (Sprite *)es.ptr(bx, sizeof(Sprite) * 16);
+ bx += 32 * (sprite - sprites);
+ //
+
+ if (data.byte(kResetmanxy) == 1) {
+ data.byte(kResetmanxy) = 0;
+ sprite->x = data.byte(kRyanx);
+ sprite->y = data.byte(kRyany);
+ sprite->b29 = 0;
+ }
+ --sprite->b22;
+ if (sprite->b22 != 0xff) {
+ ds = pop();
+ es = pop();
+ return;
+ }
+ sprite->b22 = 0;
+ if (data.byte(kTurntoface) != data.byte(kFacing)) {
+ aboutturn(sprite);
+ } else {
+ if ((data.byte(kTurndirection) != 0) && (data.byte(kLinepointer) == 254)) {
+ data.byte(kReasseschanges) = 1;
+ if (data.byte(kFacing) == data.byte(kLeavedirection))
+ checkforexit();
+ }
+ data.byte(kTurndirection) = 0;
+ if (data.byte(kLinepointer) == 254) {
+ sprite->b29 = 0;
+ } else {
+ ++sprite->b29;
+ if (sprite->b29 == 11)
+ sprite->b29 = 1;
+ walking(sprite);
+ if (data.byte(kLinepointer) != 254) {
+ if ((data.byte(kFacing) & 1) == 0)
+ walking(sprite);
+ else if ((sprite->b29 != 2) && (sprite->b29 != 7))
+ walking(sprite);
+ }
+ if (data.byte(kLinepointer) == 254) {
+ if (data.byte(kTurntoface) == data.byte(kFacing)) {
+ data.byte(kReasseschanges) = 1;
+ if (data.byte(kFacing) == data.byte(kLeavedirection))
+ checkforexit();
+ }
+ }
+ }
+ }
+ static const uint8 facelist[] = { 0,60,33,71,11,82,22,93 };
+ sprite->b15 = sprite->b29 + facelist[data.byte(kFacing)];
+ data.byte(kRyanx) = sprite->x;
+ data.byte(kRyany) = sprite->y;
+
+ ds = pop();
+ es = pop();
+}
+
+void DreamGenContext::walking(Sprite *sprite) {
+ uint8 comp;
+ if (data.byte(kLinedirection) != 0) {
+ --data.byte(kLinepointer);
+ comp = 200;
+ } else {
+ ++data.byte(kLinepointer);
+ comp = data.byte(kLinelength);
+ }
+ if (data.byte(kLinepointer) < comp) {
+ sprite->x = data.byte(kLinedata + data.byte(kLinepointer) * 2 + 0);
+ sprite->y = data.byte(kLinedata + data.byte(kLinepointer) * 2 + 1);
+ return;
+ }
+
+ data.byte(kLinepointer) = 254;
+ data.byte(kManspath) = data.byte(kDestination);
+ if (data.byte(kDestination) == data.byte(kFinaldest)) {
+ facerightway();
+ return;
+ }
+ data.byte(kDestination) = data.byte(kFinaldest);
+ push(es);
+ push(bx);
+ autosetwalk();
+ bx = pop();
+ es = pop();
+}
+
+void DreamGenContext::aboutturn(Sprite *sprite) {
+ bool incdir = true;
+
+ if (data.byte(kTurndirection) == 1)
+ incdir = true;
+ else if ((int8)data.byte(kTurndirection) == -1)
+ incdir = false;
+ else {
+ if (data.byte(kFacing) < data.byte(kTurntoface)) {
+ uint8 delta = data.byte(kTurntoface) - data.byte(kFacing);
+ if (delta >= 4)
+ incdir = false;
+ else
+ incdir = true;
+ } else {
+ uint8 delta = data.byte(kFacing) - data.byte(kTurntoface);
+ if (delta >= 4)
+ incdir = true;
+ else
+ incdir = false;
+ }
+ }
+
+ if (incdir) {
+ data.byte(kTurndirection) = 1;
+ data.byte(kFacing) = (data.byte(kFacing) + 1) & 7;
+ sprite->b29 = 0;
+ } else {
+ data.byte(kTurndirection) = -1;
+ data.byte(kFacing) = (data.byte(kFacing) - 1) & 7;
+ sprite->b29 = 0;
+ }
+}
+
+void DreamGenContext::backobject() {
+ assert(false);
+}
+
+void DreamGenContext::backobject(Sprite *sprite) {
+ ObjData *objData = (ObjData *)segRef(data.word(kSetdat)).ptr(sprite->objData(), 0);
+
+ if (sprite->delay != 0) {
+ --sprite->delay;
+ return;
+ }
+
+ sprite->delay = objData->delay;
+ if (objData->type == 6)
+ widedoor(sprite, objData);
+ else if (objData->type == 5)
+ random(sprite, objData);
+ else if (objData->type == 4)
+ lockeddoorway(sprite, objData);
+ else if (objData->type == 3)
+ liftsprite(sprite, objData);
+ else if (objData->type == 2)
+ doorway(sprite, objData);
+ else if (objData->type == 1)
+ constant(sprite, objData);
+ else
+ steady(sprite, objData);
+}
+
+void DreamGenContext::constant(Sprite *sprite, ObjData *objData) {
+ ++sprite->frame;
+ if (objData->b18[sprite->frame] == 255) {
+ sprite->frame = 0;
+ }
+ uint8 b18 = objData->b18[sprite->frame];
+ objData->b17 = b18;
+ sprite->b15 = b18;
+}
+
+void DreamGenContext::random(Sprite *sprite, ObjData *objData) {
+ randomnum1();
+ uint16 r = ax;
+ sprite->b15 = objData->b18[r&7];
+}
+
+void DreamGenContext::doorway(Sprite *sprite, ObjData *objData) {
+ data.byte(kDoorcheck1) = -24;
+ data.byte(kDoorcheck2) = 10;
+ data.byte(kDoorcheck3) = -30;
+ data.byte(kDoorcheck4) = 10;
+ dodoor(sprite, objData);
+}
+
+void DreamGenContext::widedoor(Sprite *sprite, ObjData *objData) {
+ data.byte(kDoorcheck1) = -24;
+ data.byte(kDoorcheck2) = 24;
+ data.byte(kDoorcheck3) = -30;
+ data.byte(kDoorcheck4) = 24;
+ dodoor(sprite, objData);
+}
+
+void DreamGenContext::dodoor() {
+ Sprite *sprite = (Sprite *)es.ptr(bx, sizeof(Sprite));
+ ObjData *objData = (ObjData *)ds.ptr(di, 0);
+ dodoor(sprite, objData);
+}
+
+void DreamGenContext::dodoor(Sprite *sprite, ObjData *objData) {
+ uint8 ryanx = data.byte(kRyanx);
+ uint8 ryany = data.byte(kRyany);
+ if (ryanx < sprite->x) {
+ if (ryanx < sprite->x + (int8)data.byte(kDoorcheck1))
+ goto shutdoor;
+ } else {
+ if (ryanx >= sprite->x + data.byte(kDoorcheck2))
+ goto shutdoor;
+ }
+ if (ryany < sprite->y) {
+ if (ryany < sprite->y + (int8)data.byte(kDoorcheck3))
+ goto shutdoor;
+ } else {
+ if (ryany >= sprite->y + data.byte(kDoorcheck4))
+ goto shutdoor;
+ }
+//opendoor:
+ if ((data.byte(kThroughdoor) == 1) && (sprite->frame == 0))
+ sprite->frame = 6;
+
+ ++sprite->frame;
+ if (sprite->frame == 1) { //doorsound2
+ if (data.byte(kReallocation) == 5) //hoteldoor2
+ al = 13;
+ else
+ al = 0;
+ playchannel1();
+ }
+ if (objData->b18[sprite->frame] == 255) {
+ --sprite->frame;
+ }
+ sprite->b15 = objData->b17 = objData->b18[sprite->frame];
+ data.byte(kThroughdoor) = 1;
+ return;
+shutdoor:
+ if (sprite->frame == 5) { //doorsound1;
+ if (data.byte(kReallocation) == 5) //hoteldoor1
+ al = 13;
+ else
+ al = 1;
+ playchannel1();
+ }
+ if (sprite->frame != 0) {
+ --sprite->frame;
+ }
+ sprite->b15 = objData->b17 = objData->b18[sprite->frame];
+ if (sprite->frame == 5) //nearly
+ data.byte(kThroughdoor) = 0;
+}
+
+void DreamGenContext::steady(Sprite *sprite, ObjData *objData) {
+ uint8 b18 = objData->b18[0];
+ objData->b17 = b18;
+ sprite->b15 = b18;
+}
+
+void DreamGenContext::lockeddoorway(Sprite *sprite, ObjData *objData) {
+ if (data.byte(kRyanx) < sprite->x) {
+ if (sprite->x - data.byte(kRyanx) > 24)
+ goto shutdoor2;
+ } else {
+ if (data.byte(kRyanx) - sprite->x >= 10)
+ goto shutdoor2;
+ }
+
+ if (data.byte(kRyany) < sprite->y) {
+ if (sprite->y - data.byte(kRyany) > 30)
+ goto shutdoor2;
+ } else {
+ if (data.byte(kRyany) - sprite->y >= 12)
+ goto shutdoor2;
+ }
+
+ if (data.byte(kThroughdoor) != 1) {
+ if (data.byte(kLockstatus) == 1)
+ goto shutdoor2;
+ }
+
+ if (sprite->frame == 1) {
+ al = 0;
+ playchannel1();
+ }
+
+ if (sprite->frame == 6) {
+ turnpathonCPP(data.byte(kDoorpath));
+ }
+
+ if ((data.byte(kThroughdoor) == 1) && (sprite->frame == 0)) {
+ sprite->frame = 6;
+ }
+
+ ++sprite->frame;
+ if (objData->b18[sprite->frame] == 255) {
+ --sprite->frame;
+ }
+
+ sprite->b15 = objData->b17 = objData->b18[sprite->frame];
+ if (sprite->frame == 5)
+ data.byte(kThroughdoor) = 1;
+ return;
+
+shutdoor2:
+ if (sprite->frame == 5) {
+ al = 1;
+ playchannel1();
+ }
+
+ if (sprite->frame != 0) {
+ --sprite->frame;
+ }
+
+ data.byte(kThroughdoor) = 0;
+ sprite->b15 = objData->b17 = objData->b18[sprite->frame];
+
+ if (sprite->frame == 0) {
+ turnpathoffCPP(data.byte(kDoorpath));
+ data.byte(kLockstatus) = 1;
+ }
+}
+
+void DreamGenContext::liftsprite(Sprite *sprite, ObjData *objData) {
+ uint8 liftFlag = data.byte(kLiftflag);
+ if (liftFlag == 0) { //liftclosed
+ turnpathoffCPP(data.byte(kLiftpath));
+
+ if (data.byte(kCounttoopen) != 0) {
+ _dec(data.byte(kCounttoopen));
+ if (data.byte(kCounttoopen) == 0)
+ data.byte(kLiftflag) = 3;
+ }
+ sprite->frame = 0;
+ sprite->b15 = objData->b17 = objData->b18[sprite->frame];
+ }
+ else if (liftFlag == 1) { //liftopen
+ turnpathonCPP(data.byte(kLiftpath));
+
+ if (data.byte(kCounttoclose) != 0) {
+ _dec(data.byte(kCounttoclose));
+ if (data.byte(kCounttoclose) == 0)
+ data.byte(kLiftflag) = 2;
+ }
+ sprite->frame = 12;
+ sprite->b15 = objData->b17 = objData->b18[sprite->frame];
+ }
+ else if (liftFlag == 3) { //openlift
+ if (sprite->frame == 12) {
+ data.byte(kLiftflag) = 1;
+ return;
+ }
+ ++sprite->frame;
+ if (sprite->frame == 1) {
+ al = 2;
+ liftnoise();
+ }
+ sprite->b15 = objData->b17 = objData->b18[sprite->frame];
+ } else { //closeLift
+ assert(liftFlag == 2);
+ if (sprite->frame == 0) {
+ data.byte(kLiftflag) = 0;
+ return;
+ }
+ --sprite->frame;
+ if (sprite->frame == 11) {
+ al = 3;
+ liftnoise();
+ }
+ sprite->b15 = objData->b17 = objData->b18[sprite->frame];
+ }
+}
+
+void DreamGenContext::facerightway() {
+ uint8 *paths = getroomspathsCPP();
+ uint8 dir = paths[8 * data.byte(kManspath) + 7];
+ data.byte(kTurntoface) = dir;
+ data.byte(kLeavedirection) = dir;
+}
+
+void DreamGenContext::findsource() {
+ uint16 currentFrame = data.word(kCurrentframe);
+ if (currentFrame < 160) {
+ ds = data.word(kReel1);
+ data.word(kTakeoff) = 0;
+ } else if (currentFrame < 320) {
+ ds = data.word(kReel2);
+ data.word(kTakeoff) = 160;
+ } else {
+ ds = data.word(kReel3);
+ data.word(kTakeoff) = 320;
+ }
+}
+
+Frame *DreamGenContext::findsourceCPP() {
+ push(ds);
+ findsource();
+ Frame *result = (Frame *)ds.ptr(0, 0);
+ ds = pop();
+ return result;
+}
+
+Reel *DreamGenContext::getreelstart() {
+ Reel *reel = (Reel *)segRef(data.word(kReels)).ptr(kReellist + data.word(kReelpointer) * sizeof(Reel) * 8, sizeof(Reel));
+ return reel;
+}
+
+void DreamGenContext::showreelframe() {
+ Reel *reel = (Reel *)es.ptr(si, sizeof(Reel));
+ showreelframe(reel);
+}
+
+void DreamGenContext::showreelframe(Reel *reel) {
+ uint16 x = reel->x + data.word(kMapadx);
+ uint16 y = reel->y + data.word(kMapady);
+ data.word(kCurrentframe) = reel->frame();
+ Frame *source = findsourceCPP();
+ uint16 frame = data.word(kCurrentframe) - data.word(kTakeoff);
+ uint8 width, height;
+ showframe(source, x, y, frame, 8, &width, &height);
+}
+
+void DreamGenContext::showgamereel() {
+ uint16 reelpointer = es.word(bx+3);
+ if (reelpointer >= 512)
+ return;
+ data.word(kReelpointer) = reelpointer;
+ push(es);
+ push(bx);
+ plotreel();
+ bx = pop();
+ es = pop();
+ es.word(bx+3) = data.word(kReelpointer);
+}
+
+const Frame *DreamGenContext::getreelframeax(uint16 frame) {
+ data.word(kCurrentframe) = frame;
+ uint16 offset = data.word(kCurrentframe) - data.word(kTakeoff);
+ return findsourceCPP() + offset;
+}
+
+void DreamGenContext::showrain() {
+ ds = data.word(kMainsprites);
+ si = 6*58;
+ ax = ds.word(si+2);
+ si = ax + 2080;
+ Rain *rain = (Rain *)segRef(data.word(kBuffers)).ptr(kRainlist, 0);
+ if (rain->x == 255)
+ return;
+ while (true) {
+ if (rain->x == 255) {
+ if (data.word(kCh1blockstocopy) != 0)
+ return;
+ if ((data.byte(kReallocation) == 2) && (data.byte(kBeenmugged) != 1))
+ return;
+ if (data.byte(kReallocation) == 55)
+ return;
+ randomnum1();
+ if (al >= 1)
+ return;
+ if (data.byte(kCh0playing) != 6)
+ al = 4;
+ else
+ al = 7;
+ playchannel1();
+ return;
+ }
+ uint16 y = rain->y + data.word(kMapady) + data.word(kMapystart);
+ uint16 x = rain->x + data.word(kMapadx) + data.word(kMapxstart);
+ uint16 size = rain->size;
+ ax = ((uint16)(rain->w3() - rain->b5)) & 511;
+ rain->setW3(ax);
+ ++rain;
+ const uint8 *src = ds.ptr(si, 0) + ax;
+ uint8 *dst = workspace() + y * 320 + x;
+ for(uint16 i = 0; i < size; ++i) {
+ uint8 v = src[i];
+ if (v != 0)
+ *dst = v;
+ dst += 320-1;
+ }
+ }
+}
+
+void DreamGenContext::updatepeople() {
+ data.word(kListpos) = kPeoplelist;
+ memset(segRef(data.word(kBuffers)).ptr(kPeoplelist, 12 * sizeof(People)), 0xff, 12 * sizeof(People));
+ ++data.word(kMaintimer);
+ es = cs;
+ bx = kReelroutines;
+ const ReelRoutine *reelRoutine = (const ReelRoutine *)cs.ptr(bx, 0);
+ const uint16 *callbacks = (const uint16 *)cs.ptr(kReelcalls, 0);
+ while (true) {
+ uint8 realLocation = reelRoutine->reallocation;
+ if (realLocation == 255)
+ return;
+ if ((realLocation == data.byte(kReallocation)) &&
+ (reelRoutine->mapX == data.byte(kMapx)) &&
+ (reelRoutine->mapY == data.byte(kMapy))) {
+ uint16 callback = READ_LE_UINT16(callbacks);
+ //dw gamer,sparkydrip,eden,edeninbath,sparky,smokebloke
+ if (callback == addr_gamer)
+ gamer();
+ else if (callback == addr_sparkydrip)
+ sparkydrip();
+ else if (callback == addr_eden)
+ eden();
+ else if (callback == addr_edeninbath)
+ edeninbath();
+ else if (callback == addr_sparky)
+ sparky();
+ else if (callback == addr_smokebloke)
+ smokebloke();
+ //dw manasleep,drunk,receptionist,malefan,femalefan
+ else if (callback == addr_manasleep)
+ manasleep();
+ else if (callback == addr_drunk)
+ drunk();
+ else if (callback == addr_receptionist)
+ receptionist();
+ else if (callback == addr_malefan)
+ malefan();
+ else if (callback == addr_femalefan)
+ femalefan();
+ //dw louis,louischair,soldier1,bossman,interviewer
+ else if (callback == addr_louis)
+ louis();
+ else if (callback == addr_louischair)
+ louischair();
+ else if (callback == addr_soldier1)
+ soldier1();
+ else if (callback == addr_bossman)
+ bossman();
+ else if (callback == addr_interviewer)
+ interviewer();
+ //dw heavy,manasleep2,mansatstill,drinker,bartender
+ else if (callback == addr_heavy)
+ heavy();
+ else if (callback == addr_manasleep2)
+ manasleep2();
+ else if (callback == addr_mansatstill)
+ mansatstill();
+ else if (callback == addr_drinker)
+ drinker();
+ else if (callback == addr_bartender)
+ bartender();
+ //dw othersmoker,tattooman,attendant,keeper,candles1
+ else if (callback == addr_othersmoker)
+ othersmoker();
+ else if (callback == addr_tattooman)
+ tattooman();
+ else if (callback == addr_attendant)
+ attendant();
+ else if (callback == addr_keeper)
+ keeper();
+ else if (callback == addr_candles1)
+ candles1();
+ //dw smallcandle,security,copper,poolguard,rockstar
+ else if (callback == addr_smallcandle)
+ smallcandle();
+ else if (callback == addr_security)
+ security();
+ else if (callback == addr_copper)
+ copper();
+ else if (callback == addr_poolguard)
+ poolguard();
+ else if (callback == addr_rockstar)
+ rockstar();
+ //dw businessman,train,aide,mugger,helicopter
+ else if (callback == addr_businessman)
+ businessman();
+ else if (callback == addr_train)
+ train();
+ else if (callback == addr_aide)
+ aide();
+ else if (callback == addr_mugger)
+ mugger();
+ else if (callback == addr_helicopter)
+ helicopter();
+ //dw intromagic1,intromusic,intromagic2,candles2,gates
+ else if (callback == addr_intromagic1)
+ intromagic1();
+ else if (callback == addr_intromusic)
+ intromusic();
+ else if (callback == addr_intromagic2)
+ intromagic2();
+ else if (callback == addr_candles2)
+ candles2();
+ else if (callback == addr_gates)
+ gates();
+ //dw intromagic3,intromonks1,candles,intromonks2
+ else if (callback == addr_intromagic3)
+ intromagic3();
+ else if (callback == addr_intromonks1)
+ intromonks1();
+ else if (callback == addr_candles)
+ candles();
+ else if (callback == addr_intromonks2)
+ intromonks2();
+ //dw handclap,monkandryan,endgameseq,priest,madman
+ else if (callback == addr_handclap)
+ handclap();
+ else if (callback == addr_monkandryan)
+ monkandryan();
+ else if (callback == addr_endgameseq)
+ endgameseq();
+ else if (callback == addr_priest)
+ priest();
+ else if (callback == addr_madman)
+ madman();
+ //dw madmanstelly,alleybarksound,foghornsound
+ else if (callback == addr_madmanstelly)
+ madmanstelly();
+ else if (callback == addr_alleybarksound)
+ alleybarksound();
+ else if (callback == addr_foghornsound)
+ foghornsound();
+ //dw carparkdrip,carparkdrip,carparkdrip,carparkdrip
+ else if (callback == addr_carparkdrip)
+ carparkdrip();
+ else
+ assert(false); // Oops I forgot something in the dispatch table
+ }
+ bx += 8;
+ ++reelRoutine;
+ ++callbacks;
+ }
+}
+
+void DreamGenContext::madmantext() {
+ if (isCD()) {
+ if (data.byte(kSpeechcount) >= 63)
+ return;
+ if (data.byte(kCh1playing) != 255)
+ return;
+ al = data.byte(kSpeechcount);
+ ++data.byte(kSpeechcount);
+ } else {
+ if (data.byte(kCombatcount) >= 61)
+ return;
+ al = data.byte(kCombatcount);
+ _and(al, 3);
+ if (!flags.z())
+ return;
+ al = data.byte(kCombatcount) / 4;
+ }
+ setuptimedtemp(47 + al, 82, 72, 80, 90, 1);
+}
+
+void DreamGenContext::madman() {
+ data.word(kWatchingtime) = 2;
+ checkspeed();
+ if (flags.z()) {
+ ax = es.word(bx+3);
+ if (ax >= 364) {
+ data.byte(kMandead) = 2;
+ showgamereel();
+ return;
+ }
+ if (ax == 10) {
+ push(es);
+ push(bx);
+ push(ax);
+ dx = kIntrotextname;
+ loadtemptext();
+ ax = pop();
+ bx = pop();
+ es = pop();
+ data.byte(kCombatcount) = -1;
+ data.byte(kSpeechcount) = 0;
+ }
+ ++ax;
+ if (ax == 294) {
+ if (data.byte(kWongame) == 1)
+ return;
+ data.byte(kWongame) = 1;
+ push(es);
+ push(bx);
+ getridoftemptext();
+ bx = pop();
+ es = pop();
+ return;
+ }
+ if (ax == 66) {
+ ++data.byte(kCombatcount);
+ push(es);
+ push(bx);
+ madmantext();
+ bx = pop();
+ es = pop();
+ ax = 53;
+ if (data.byte(kCombatcount) >= (isCD() ? 64 : 62)) {
+ if (data.byte(kCombatcount) == (isCD() ? 70 : 68))
+ ax = 310;
+ else {
+ if (data.byte(kLastweapon) == 8) {
+ data.byte(kCombatcount) = isCD() ? 72 : 70;
+ data.byte(kLastweapon) = -1;
+ data.byte(kMadmanflag) = 1;
+ ax = 67;
+ }
+ }
+ }
+ }
+ es.word(bx+3) = ax;
+ }
+ showgamereel();
+ es.byte(bx+1) = data.byte(kMapx);
+ madmode();
+}
+
+void DreamGenContext::madmode() {
+ data.word(kWatchingtime) = 2;
+ data.byte(kPointermode) = 0;
+ if (data.byte(kCombatcount) < (isCD() ? 65 : 63))
+ return;
+ if (data.byte(kCombatcount) >= (isCD() ? 70 : 68))
+ return;
+ data.byte(kPointermode) = 2;
+}
+
+void DreamGenContext::movemap(uint8 param) {
+ switch (param) {
+ case 32:
+ data.byte(kMapy) -= 20;
+ break;
+ case 16:
+ data.byte(kMapy) -= 10;
+ break;
+ case 8:
+ data.byte(kMapy) += 10;
+ break;
+ case 2:
+ data.byte(kMapx) += 11;
+ break;
+ default:
+ data.byte(kMapx) -= 11;
+ break;
+ }
+ data.byte(kNowinnewroom) = 1;
+}
+
+} /*namespace dreamgen */
+
diff --git a/engines/dreamweb/structs.h b/engines/dreamweb/structs.h
index e274375cf4..685e4cffe1 100644
--- a/engines/dreamweb/structs.h
+++ b/engines/dreamweb/structs.h
@@ -20,21 +20,30 @@
*
*/
+#include "common/endian.h"
+
struct Sprite {
- uint16 updateCallback;
+ uint16 _updateCallback;
+ uint16 updateCallback() const { return READ_LE_UINT16(&_updateCallback); }
+ void setUpdateCallback(uint16 v) { WRITE_LE_UINT16(&_updateCallback, v); }
uint16 w2;
uint16 w4;
- uint16 w6;
+ uint16 _frameData;
+ uint16 frameData() const { return READ_LE_UINT16(&_frameData); }
+ void setFrameData(uint16 v) { WRITE_LE_UINT16(&_frameData, v); }
uint16 w8;
uint8 x;
uint8 y;
uint16 w12;
uint8 b14;
uint8 b15;
- uint16 w16;
+ uint8 b16;
+ uint8 b17;
uint8 delay;
uint8 frame;
- uint16 obj_data;
+ uint16 _objData;
+ uint16 objData() const { return READ_LE_UINT16(&_objData); }
+ void setObjData(uint16 v) { WRITE_LE_UINT16(&_objData, v); }
uint8 b22;
uint8 priority;
uint16 w24;
@@ -66,3 +75,85 @@ struct ObjData {
uint8 b17;
uint8 b18[256]; // NB: Don't know the size yet
};
+
+struct Frame {
+ uint8 width;
+ uint8 height;
+ uint16 _ptr;
+ uint16 ptr() const { return READ_LE_UINT16(&_ptr); }
+ void setPtr(uint16 v) { WRITE_LE_UINT16(&_ptr, v); }
+ uint8 x;
+ uint8 y;
+};
+
+struct Reel {
+ uint8 frame_lo;
+ uint8 frame_hi;
+ uint16 frame() const { return READ_LE_UINT16(&frame_lo); }
+ void setFrame(uint16 v) { WRITE_LE_UINT16(&frame_lo, v); }
+ uint8 x;
+ uint8 y;
+ uint8 b4;
+};
+
+struct ReelRoutine {
+ uint8 reallocation;
+ uint8 mapX;
+ uint8 mapY;
+ uint8 b3;
+ uint8 b4;
+ uint8 b5;
+ uint8 b6;
+ uint8 b7;
+};
+
+struct People {
+ uint8 b0;
+ uint8 b1;
+ uint16 w0() const { return READ_LE_UINT16(&b0); }
+ void setW0(uint16 v) { WRITE_LE_UINT16(&b0, v); }
+ uint8 b2;
+ uint8 b3;
+ uint16 w2() const { return READ_LE_UINT16(&b2); }
+ void setW2(uint16 v) { WRITE_LE_UINT16(&b2, v); }
+ uint8 b4;
+
+};
+
+struct Room {
+ uint8 name[10];
+ uint8 b10;
+ uint8 b11;
+ uint8 b12;
+ uint8 roomsSample;
+ uint8 b14;
+ uint8 mapX;
+ uint8 mapY;
+ uint8 b17;
+ uint8 b18;
+ uint8 b19;
+ uint8 liftFlag;
+ uint8 b21;
+ uint8 b22;
+ uint8 countToOpen;
+ uint8 liftPath;
+ uint8 doorPath;
+ uint8 b26;
+ uint8 b27;
+ uint8 b28;
+ uint8 b29;
+ uint8 b30;
+ uint8 b31;
+};
+
+struct Rain {
+ uint8 x;
+ uint8 y;
+ uint8 size;
+ uint8 w3_lo;
+ uint8 w3_hi;
+ uint16 w3() const { return READ_LE_UINT16(&w3_lo); }
+ void setW3(uint16 v) { WRITE_LE_UINT16(&w3_lo, v); }
+ uint8 b5;
+};
+
diff --git a/engines/dreamweb/stubs.cpp b/engines/dreamweb/stubs.cpp
index 5ba3796e30..c978d8d475 100644
--- a/engines/dreamweb/stubs.cpp
+++ b/engines/dreamweb/stubs.cpp
@@ -174,7 +174,7 @@ void DreamGenContext::dreamweb() {
}
}
-Common::String getFilename(Context &context) {
+static Common::String getFilename(Context &context) {
uint16 name_ptr = context.dx;
Common::String name;
uint8 c;
@@ -183,126 +183,6 @@ Common::String getFilename(Context &context) {
return name;
}
-void DreamGenContext::multiget() {
- multiget(di, bx, cl, ch);
-}
-
-void DreamGenContext::multiget(uint16 x, uint16 y, uint8 w, uint8 h) {
- unsigned src = x + y * kScreenwidth;
- unsigned dst = (uint16)si;
- es = ds;
- ds = data.word(kWorkspace);
- if (y + h > 200)
- h = 200 - y;
- if (x + w > 320)
- w = 320 - x;
- //debug(1, "multiget %u,%u %ux%u -> segment: %04x->%04x", x, y, w, h, (uint16)ds, (uint16)es);
- for(unsigned l = 0; l < h; ++l) {
- uint8 *src_p = ds.ptr(src + kScreenwidth * l, w);
- uint8 *dst_p = es.ptr(dst + w * l, w);
- memcpy(dst_p, src_p, w);
- }
- si += w * h;
- di = src + kScreenwidth * h;
- cx = 0;
-}
-
-void DreamGenContext::multiput() {
- multiput(di, bx, cl, ch);
-}
-
-void DreamGenContext::multiput(uint16 x, uint16 y, uint8 w, uint8 h) {
- unsigned src = (uint16)si;
- unsigned dst = x + y * kScreenwidth;
- es = data.word(kWorkspace);
- if (y + h > 200)
- h = 200 - y;
- if (x + w > 320)
- w = 320 - x;
- //debug(1, "multiput %ux%u -> segment: %04x->%04x", w, h, (uint16)ds, (uint16)es);
- for(unsigned l = 0; l < h; ++l) {
- uint8 *src_p = ds.ptr(src + w * l, w);
- uint8 *dst_p = es.ptr(dst + kScreenwidth * l, w);
- memcpy(dst_p, src_p, w);
- }
- si += w * h;
- di = dst + kScreenwidth * h;
- cx = 0;
-}
-
-void DreamGenContext::multidump(uint16 x, uint16 y, uint8 width, uint8 height) {
- ds = data.word(kWorkspace);
- unsigned offset = x + y * kScreenwidth;
- //debug(1, "multidump %ux%u(segment: %04x) -> %d,%d(address: %d)", w, h, (uint16)ds, x, y, offset);
- engine->blit(ds.ptr(offset, width * height), kScreenwidth, x, y, width, height);
-}
-
-void DreamGenContext::multidump() {
- multidump(di, bx, cl, ch);
- unsigned offset = di + bx * kScreenwidth;
- si = di = offset + ch * kScreenwidth;
- cx = 0;
-}
-
-void DreamGenContext::worktoscreen() {
- ds = data.word(kWorkspace);
- uint size = 320 * 200;
- engine->blit(ds.ptr(0, size), 320, 0, 0, 320, 200);
- di = si = size;
- cx = 0;
-}
-
-void DreamGenContext::printundermon() {
- engine->printUnderMonitor();
-}
-
-void DreamGenContext::cls() {
- engine->cls();
-}
-
-void DreamGenContext::frameoutnm(uint8 *dst, const uint8 *src, uint16 pitch, uint16 width, uint16 height, uint16 x, uint16 y) {
- dst += pitch * y + x;
-
- for (uint16 j = 0; j < height; ++j) {
- memcpy(dst, src, width);
- dst += pitch;
- src += width;
- }
-}
-
-void DreamGenContext::frameoutbh(uint8 *dst, const uint8 *src, uint16 pitch, uint16 width, uint16 height, uint16 x, uint16 y) {
- uint16 stride = pitch - width;
- dst += y * pitch + x;
-
- for (uint16 i = 0; i < height; ++i) {
- for (uint16 j = 0; j < width; ++j) {
- if (*dst == 0xff) {
- *dst = *src;
- }
- ++src;
- ++dst;
- }
- dst += stride;
- }
-}
-
-void DreamGenContext::frameoutfx(uint8 *dst, const uint8 *src, uint16 pitch, uint16 width, uint16 height, uint16 x, uint16 y) {
- uint16 stride = pitch - width;
- dst += y * pitch + x;
- dst -= width;
-
- for (uint16 j = 0; j < height; ++j) {
- for (uint16 i = 0; i < width; ++i) {
- uint8 pixel = src[width - i - 1];
- if (pixel)
- *dst = pixel;
- ++dst;
- }
- src += width;
- dst += stride;
- }
-}
-
void DreamGenContext::seecommandtail() {
data.word(kSoundbaseadd) = 0x220;
data.byte(kSoundint) = 5;
@@ -394,84 +274,6 @@ void DreamGenContext::setmouse() {
data.word(kOldpointerx) = 0xffff;
}
-void DreamGenContext::printboth() {
- uint16 x = di;
- printboth(es, ds, &x, bx, al);
- di = x;
-}
-
-void DreamGenContext::printboth(uint16 dst, uint16 src, uint16 *x, uint16 y, uint8 c) {
- uint16 newX = *x;
- uint8 width, height;
- printchar(dst, src, &newX, y, c, &width, &height);
- multidump(*x, y, width, height);
- *x = newX;
-}
-
-uint8 DreamGenContext::getnextword(const uint8 *string, uint8 *totalWidth, uint8 *charCount) {
- *totalWidth = 0;
- *charCount = 0;
- while(true) {
- uint8 firstChar = *string;
- ++string;
- ++*charCount;
- if ((firstChar == ':') || (firstChar == 0)) { //endall
- *totalWidth += 6;
- return 1;
- }
- if (firstChar == 32) { //endword
- *totalWidth += 6;
- return 0;
- }
- firstChar = engine->modifyChar(firstChar);
- if (firstChar != 255) {
- uint8 secondChar = *string;
- uint8 width = ds.byte(6*(firstChar - 32 + data.word(kCharshift)));
- width = kernchars(firstChar, secondChar, width);
- *totalWidth += width;
- }
- }
-}
-
-void DreamGenContext::getnextword() {
- uint8 totalWidth, charCount;
- al = getnextword(es.ptr(di, 0), &totalWidth, &charCount);
- bl = totalWidth;
- bh = charCount;
- di += charCount;
-}
-
-void DreamGenContext::printchar() {
- uint16 x = di;
- uint8 width, height;
- printchar(es, ds, &x, bx, al, &width, &height);
- di = x;
- cl = width;
- ch = height;
-}
-
-void DreamGenContext::printchar(uint16 dst, uint16 src, uint16* x, uint16 y, uint8 c, uint8 *width, uint8 *height) {
- if (c == 255)
- return;
- push(si);
- push(di);
- push(ax);
- if (data.byte(kForeignrelease) != 0)
- y -= 3;
- showframe(dst, src, *x, y, c - 32 + data.word(kCharshift), 0, width, height);
- ax = pop();
- di = pop();
- si = pop();
- _cmp(data.byte(kKerning), 0);
- if (flags.z())
- *width = kernchars(c, ah, *width);
- (*x) += *width;
-}
-
-void DreamGenContext::printslow() {
- al = printslow(di, bx, dl, (bool)(dl & 1));
-}
-
void DreamGenContext::dumptextline() {
if (data.byte(kNewtextline) != 1)
return;
@@ -483,100 +285,13 @@ void DreamGenContext::dumptextline() {
multidump(x, y, 228, 13);
}
-uint8 DreamGenContext::printslow(uint16 x, uint16 y, uint8 maxWidth, bool centered) {
- data.byte(kPointerframe) = 1;
- data.byte(kPointermode) = 3;
- ds = data.word(kCharset1);
- do {
- uint16 offset = x;
- uint16 charCount = getnumber(si, maxWidth, centered, &offset);
- do {
- push(si);
- push(es);
- uint8 c0 = es.byte(si);
- push(es);
- push(ds);
- c0 = engine->modifyChar(c0);
- printboth(es, ds, &offset, y, c0);
- ds = pop();
- es = pop();
- uint8 c1 = es.byte(si+1);
- ++si;
- if ((c1 == 0) || (c1 == ':')) {
- es = pop();
- si = pop();
- return 0;
- }
- if (charCount != 1) {
- push(ds);
- push(es);
- c1 = engine->modifyChar(c1);
- data.word(kCharshift) = 91;
- uint16 offset2 = offset;
- printboth(es, ds, &offset2, y, c1);
- data.word(kCharshift) = 0;
- es = pop();
- ds = pop();
- for (int i=0; i<2; ++i) {
- waitframes();
- if (ax == 0)
- continue;
- if (ax != data.word(kOldbutton)) {
- es = pop();
- si = pop();
- return 1;
- }
- }
- }
-
- es = pop();
- si = pop();
- ++si;
- --charCount;
- } while (charCount);
- y += 10;
- } while (true);
-}
-
-void DreamGenContext::printdirect() {
- uint16 y = bx;
- printdirect(di, &y, dl, (bool)(dl & 1));
- bx = y;
-}
-
-void DreamGenContext::printdirect(uint16 x, uint16 *y, uint8 maxWidth, bool centered) {
- data.word(kLastxpos) = x;
- ds = data.word(kCurrentset);
- while (true) {
- uint16 offset = x;
- uint8 charCount = getnumber(si, maxWidth, centered, &offset);
- uint16 i = offset;
- do {
- uint8 c = es.byte(si);
- ++si;
- if ((c == 0) || (c == ':')) {
- return;
- }
- c = engine->modifyChar(c);
- ah = es.byte(si); // get next char for kerning
- uint8 width, height;
- push(es);
- printchar(es, ds, &i, *y, c, &width, &height);
- es = pop();
- data.word(kLastxpos) = i;
- --charCount;
- } while(charCount);
- *y += data.word(kLinespacing);
- }
-}
-
void DreamGenContext::getundertimed() {
uint16 y = data.byte(kTimedy);
if (data.byte(kForeignrelease))
y -= 3;
ds = data.word(kBuffers);
si = kUndertimedtext;
- multiget(data.byte(kTimedx), y, 240, kUndertimedysize);
+ multiget(ds.ptr(si, 0), data.byte(kTimedx), y, 240, kUndertimedysize);
}
void DreamGenContext::putundertimed() {
@@ -585,7 +300,7 @@ void DreamGenContext::putundertimed() {
y -= 3;
ds = data.word(kBuffers);
si = kUndertimedtext;
- multiput(data.byte(kTimedx), y, 240, kUndertimedysize);
+ multiput(ds.ptr(si, 0), data.byte(kTimedx), y, 240, kUndertimedysize);
}
void DreamGenContext::usetimedtext() {
@@ -605,67 +320,62 @@ void DreamGenContext::usetimedtext() {
es = data.word(kTimedseg);
si = data.word(kTimedoffset);
+ const uint8 *string = es.ptr(si, 0);
uint16 y = data.byte(kTimedy);
- printdirect(data.byte(kTimedx), &y, 237, true);
+ printdirect(&string, data.byte(kTimedx), &y, 237, true);
data.byte(kNeedtodumptimed) = 1;
}
-void DreamGenContext::getnumber() {
- uint16 offset = di;
- cl = getnumber(si, dl, (bool)(dl & 1), &offset);
- di = offset;
-}
-
-uint8 DreamGenContext::getnumber(uint16 index, uint16 maxWidth, bool centered, uint16* offset) {
- uint8 totalWidth = 0;
- uint8 charCount = 0;
- while (true) {
- uint8 wordTotalWidth, wordCharCount;
- uint8 done = getnextword(es.ptr(index, 0), &wordTotalWidth, &wordCharCount);
- index += wordCharCount;
-
- if (done == 1) { //endoftext
- ax = totalWidth + wordTotalWidth - 10;
- if (ax < maxWidth) {
- totalWidth += wordTotalWidth;
- charCount += wordCharCount;
- }
-
- if (centered) {
- ax = (maxWidth & 0xfe) + 2 + 20 - totalWidth;
- ax /= 2;
- } else {
- ax = 0;
- }
- *offset += ax;
- return charCount;
- }
- ax = totalWidth + wordTotalWidth - 10;
- if (ax >= maxWidth) { //gotoverend
- if (centered) {
- ax = (maxWidth & 0xfe) - totalWidth + 20;
- ax /= 2;
- } else {
- ax = 0;
- }
- *offset += ax;
- return charCount;
+void DreamGenContext::setuptimedtemp() {
+ setuptimedtemp(al, ah, bl, bh, cx, dx);
+}
+
+void DreamGenContext::setuptimedtemp(uint8 textIndex, uint8 voiceIndex, uint8 x, uint8 y, uint16 countToTimed, uint16 timeCount) {
+#if 1 // if cd
+ if (voiceIndex != 0) {
+ push(ax);
+ push(bx);
+ push(cx);
+ push(dx);
+ dl = 'T';
+ dh = voiceIndex;
+ cl = 'T';
+ ah = 0;
+ loadspeech();
+ if (data.byte(kSpeechloaded) == 1) {
+ al = 50+12;
+ playchannel1();
}
- totalWidth += wordTotalWidth;
- charCount += wordCharCount;
+ dx = pop();
+ cx = pop();
+ bx = pop();
+ ax = pop();
+ if ((data.byte(kSpeechloaded) == 1) && (data.byte(kSubtitles) != 1))
+ return;
}
-}
+#endif
-uint8 DreamGenContext::kernchars(uint8 firstChar, uint8 secondChar, uint8 width) {
- if ((firstChar == 'a') || (al == 'u')) {
- if ((secondChar == 'n') || (secondChar == 't') || (secondChar == 'r') || (secondChar == 'i') || (secondChar == 'l'))
- return width-1;
- }
- return width;
-}
+ if (data.word(kTimecount) != 0)
+ return;
+ data.byte(kTimedy) = y;
+ data.byte(kTimedx) = x;
+ data.word(kCounttotimed) = countToTimed;
+ data.word(kTimecount) = timeCount + countToTimed;
+ data.word(kTimedseg) = data.word(kTextfile1);
+ data.word(kTimedoffset) = kTextstart + segRef(data.word(kTextfile1)).word(textIndex * 2);
+ const uint8 *string = segRef(data.word(kTextfile1)).ptr(data.word(kTimedoffset), 0);
+ debug(1, "setuptimedtemp: (%d, %d) => '%s'", textIndex, voiceIndex, string);
+}
+
+void DreamGenContext::dumptimedtext() {
+ if (data.byte(kNeedtodumptimed) != 1)
+ return;
+ uint8 y = data.byte(kTimedy);
+ if (data.byte(kForeignrelease) != 0)
+ y -= 3;
-void DreamGenContext::kernchars() {
- cl = kernchars(al, ah, cl);
+ multidump(data.byte(kTimedx), y, 240, kUndertimedysize);
+ data.byte(kNeedtodumptimed) = 0;
}
void DreamGenContext::gettime() {
@@ -681,12 +391,17 @@ void DreamGenContext::gettime() {
}
void DreamGenContext::allocatemem() {
- uint size = (bx + 2) * 16;
+ ax = allocatemem(bx);
+}
+
+uint16 DreamGenContext::allocatemem(uint16 paragraphs) {
+ uint size = (paragraphs + 2) * 16;
debug(1, "allocate mem, %u bytes", size);
flags._c = false;
SegmentRef seg = allocateSegment(size);
- ax = (uint16)seg;
- debug(1, "\tsegment address -> %04x", (uint16)ax);
+ uint16 result = (uint16)seg;
+ debug(1, "\tsegment address -> %04x", result);
+ return result;
}
void DreamGenContext::deallocatemem() {
@@ -880,349 +595,96 @@ void DreamGenContext::fadedos() {
engine->fadeDos();
}
-void DreamGenContext::doshake() {
- uint8 &counter = data.byte(kShakecounter);
- _cmp(counter, 48);
- if (flags.z())
- return;
-
- _add(counter, 1);
- static const int shakeTable[] = {
- 0, -2, 3, -2, 0, 2, 4, -1,
- 1, -3, 3, 2, 0, -2, 3, -2,
- 0, 2, 4, -1, 1, -3, 3, 2,
- 0, -2, 3, -2, 0, 2, 4, -1,
-
- 1, -3, 3, 2, 0, -2, 3, -2,
- 0, 2, 4, -1, 1, -3, 3, 2,
- 0, -2, 3, -2, 0, 2, 4, -1,
- 1, -3, 3, 2, 0, -2, 3, -2,
-
- 0, 2, 4, -1, 1, -3, 3, 2,
- 0, -2, 3, -2, 0, 2, 4, -1,
- 1, -3, 3, 2, 0, -2, 3, -2,
- 0, 2, 4, -1, 1, -3, 3, 2,
-
- 0, -2, 3, -2, 0, 2, 4, -1,
- 1, -3, 3, 0,
- };
- int offset = shakeTable[counter];
- engine->setShakePos(offset >= 0 ? offset : -offset);
-}
-
-void DreamGenContext::vsync() {
- push(ax);
- push(bx);
- push(cx);
- push(dx);
- push(si);
- push(di);
- push(es);
- push(ds);
- engine->waitForVSync();
- ds = pop();
- es = pop();
- di = pop();
- si = pop();
- dx = pop();
- cx = pop();
- bx = pop();
- ax = pop();
-}
-
-void DreamGenContext::setmode() {
- vsync();
- initGraphics(320, 200, false);
-}
-
-void DreamGenContext::showpcx() {
- Common::String name = getFilename(*this);
- Common::File pcxFile;
-
- if (!pcxFile.open(name)) {
- warning("showpcx: Could not open '%s'", name.c_str());
- return;
- }
-
- uint8 *maingamepal;
- int i, j;
-
- // Read the 16-color palette into the 'maingamepal' buffer. Note that
- // the color components have to be adjusted from 8 to 6 bits.
-
- pcxFile.seek(16, SEEK_SET);
- es = data.word(kBuffers);
- maingamepal = es.ptr(kMaingamepal, 768);
- pcxFile.read(maingamepal, 48);
-
- memset(maingamepal + 48, 0xff, 720);
- for (i = 0; i < 48; i++) {
- maingamepal[i] >>= 2;
- }
-
- // Decode the image data.
-
- Graphics::Surface *s = g_system->lockScreen();
- Common::Rect rect(640, 480);
-
- s->fillRect(rect, 0);
- pcxFile.seek(128, SEEK_SET);
-
- for (int y = 0; y < 480; y++) {
- byte *dst = (byte *)s->getBasePtr(0, y);
- int decoded = 0;
-
- while (decoded < 320) {
- byte col = pcxFile.readByte();
- byte len;
-
- if ((col & 0xc0) == 0xc0) {
- len = col & 0x3f;
- col = pcxFile.readByte();
- } else {
- len = 1;
- }
-
- // The image uses 16 colors and is stored as four bit
- // planes, one for each bit of the color, least
- // significant bit plane first.
-
- for (i = 0; i < len; i++) {
- int plane = decoded / 80;
- int pos = decoded % 80;
-
- for (j = 0; j < 8; j++) {
- byte bit = (col >> (7 - j)) & 1;
- dst[8 * pos + j] |= (bit << plane);
- }
-
- decoded++;
- }
- }
- }
-
- g_system->unlockScreen();
- pcxFile.close();
-}
-
-/*
-void DreamGenContext::frameoutv() {
- uint16 pitch = dx;
- uint16 width = cx & 0xff;
- uint16 height = cx >> 8;
-
- const uint8 *src = ds.ptr(si, width * height);
- uint8 *dst = es.ptr(0, pitch * height);
-
- frameoutv(dst, src, pitch, width, height, di, bx);
-}
-*/
-
-void DreamGenContext::frameoutv(uint8 *dst, const uint8 *src, uint16 pitch, uint16 width, uint16 height, uint16 x, uint16 y) {
- // NB : These resilience checks were not in the original engine, but did they result in undefined behaviour
- // or was something broken during porting to C++?
- assert(pitch == 320);
-
- if(x >= 320)
- return;
- if(y >= 200)
+void DreamGenContext::eraseoldobs() {
+ if (data.byte(kNewobs) == 0)
return;
- if(x + width > 320) {
- width = 320 - x;
- }
- if(y + height > 200) {
- height = 200 - y;
- }
- uint16 stride = pitch - width;
- dst += pitch * y + x;
-
- for (uint16 j = 0; j < height; ++j) {
- for (uint16 i = 0; i < width; ++i) {
- uint8 pixel = *src++;
- if (pixel)
- *dst = pixel;
- ++dst;
+ Sprite *sprites = spritetable();
+ for (size_t i=0; i < 16; ++i) {
+ Sprite &sprite = sprites[i];
+ if (sprite.objData() != 0xffff) {
+ memset(&sprite, 0xff, sizeof(Sprite));
}
- dst += stride;
}
}
-Sprite *DreamGenContext::spritetable() {
+void DreamGenContext::turnpathonCPP(uint8 param) {
+ al = param;
push(es);
push(bx);
-
- es = data.word(kBuffers);
- bx = kSpritetable;
- Sprite *sprite = (Sprite *)es.ptr(bx, 16 * sizeof(Sprite));
-
+ turnpathon();
bx = pop();
es = pop();
-
- return sprite;
-}
-
-void DreamGenContext::showframe(uint16 dst, uint16 src, uint16 x, uint16 y, uint16 frameNumber, uint8 effectsFlag, uint8 *width, uint8 *height) {
- // frameNumber takes up 9 bits of ax, and effectsFlag 7.
- assert(!(effectsFlag & 1));
-
- es = dst;
- ds = src;
- di = x;
- bx = y;
- ax = frameNumber | (effectsFlag << 8);
-
-
- si = (ax & 0x1ff) * 6;
- if (ds.word(si) == 0) {
- *width = 0;
- *height = 0;
- return;
- }
-
-//notblankshow:
- if ((effectsFlag & 128) == 0) {
- di += ds.byte(si + 4);
- bx += ds.byte(si + 5);
- }
-//skipoffsets:
- cx = ds.word(si + 0);
- *width = cl;
- *height = ch;
- si = ds.word(si+2) + 2080;
-
- if (effectsFlag) {
- if (effectsFlag & 128) { //centred
- di -= *width / 2;
- bx -= *height / 2;
- }
- if (effectsFlag & 64) { //diffdest
- frameoutfx(es.ptr(0, dx * *height), ds.ptr(si, *width * *height), dx, *width, *height, di, bx);
- return;
- }
- if (effectsFlag & 8) { //printlist
- push(ax);
- ax = di - data.word(kMapadx);
- push(bx);
- bx -= data.word(kMapady);
- ah = bl;
- bx = pop();
- //addtoprintlist(); // NB: Commented in the original asm
- ax = pop();
- }
- if (effectsFlag & 4) { //flippedx
- es = data.word(kWorkspace);
- frameoutfx(es.ptr(0, 320 * *height), ds.ptr(si, *width * *height), 320, *width, *height, di, bx);
- return;
- }
- if (effectsFlag & 2) { //nomask
- es = data.word(kWorkspace);
- frameoutnm(es.ptr(0, 320 * *height), ds.ptr(si, *width * *height), 320, *width, *height, di, bx);
- return;
- }
- if (effectsFlag & 32) {
- es = data.word(kWorkspace);
- frameoutbh(es.ptr(0, 320 * *height), ds.ptr(si, *width * *height), 320, *width, *height, di, bx);
- return;
- }
- }
-//noeffects:
- es = data.word(kWorkspace);
- frameoutv(es.ptr(0, 65536), ds.ptr(si, *width * *height), 320, *width, *height, di, bx);
- return;
}
-void DreamGenContext::showframe() {
- uint8 width, height;
- showframe(es, ds, di, bx, ax & 0x1ff, ah & 0xfe, &width, &height);
- cl = width;
- ch = height;
-}
-
-void DreamGenContext::printsprites() {
- for (size_t priority = 0; priority < 7; ++priority) {
- Sprite *sprites = spritetable();
- for (size_t j = 0; j < 16; ++j) {
- const Sprite &sprite = sprites[j];
- if (READ_LE_UINT16(&sprite.updateCallback) == 0x0ffff)
- continue;
- if (priority != sprite.priority)
- continue;
- if (sprite.hidden == 1)
- continue;
- printasprite(&sprite);
- }
- }
-}
-
-void DreamGenContext::printasprite(const Sprite *sprite) {
+void DreamGenContext::turnpathoffCPP(uint8 param) {
+ al = param;
push(es);
push(bx);
- ds = READ_LE_UINT16(&sprite->w6);
- ax = sprite->y;
- if (al >= 220) {
- bx = data.word(kMapady) - (256 - al);
- } else {
- bx = ax + data.word(kMapady);
- }
-
- ax = sprite->x;
- if (al >= 220) {
- di = data.word(kMapadx) - (256 - al);
- } else {
- di = ax + data.word(kMapadx);
- }
-
- uint8 c;
- if (sprite->b29 != 0)
- c = 8;
- else
- c = 0;
- uint8 width, height;
- showframe(es, ds, di, bx, sprite->b15, c, &width, &height);
- cl = width;
- ch = height;
-
+ turnpathoff();
bx = pop();
es = pop();
}
-void DreamGenContext::eraseoldobs() {
- if (data.byte(kNewobs) == 0)
- return;
+void DreamGenContext::modifychar() {
+ al = engine->modifyChar(al);
+}
- Sprite *sprites = spritetable();
- for (size_t i=0; i < 16; ++i) {
- Sprite &sprite = sprites[i];
- if (READ_LE_UINT16(&sprite.obj_data) != 0xffff) {
- memset(&sprite, 0xff, sizeof(Sprite));
+void DreamGenContext::lockmon() {
+ // Pressing space pauses text output in the monitor. We use the "hard"
+ // key because calling readkey() drains characters from the input
+ // buffer, we we want the user to be able to type ahead while the text
+ // is being printed.
+ if (data.byte(kLasthardkey) == 57) {
+ // Clear the keyboard buffer. Otherwise the space that caused
+ // the pause will be read immediately unpause the game.
+ do {
+ readkey();
+ } while (data.byte(kCurrentkey) != 0);
+
+ locklighton();
+ while (!engine->shouldQuit()) {
+ engine->waitForVSync();
+ readkey();
+ if (data.byte(kCurrentkey) == ' ')
+ break;
}
+ // Forget the last "hard" key, otherwise the space that caused
+ // the unpausing will immediately re-pause the game.
+ data.byte(kLasthardkey) = 0;
+ locklightoff();
}
}
-void DreamGenContext::clearsprites() {
- memset(spritetable(), 0xff, sizeof(Sprite) * 16);
+void DreamGenContext::cancelch0() {
+ data.byte(kCh0repeat) = 0;
+ data.word(kCh0blockstocopy) = 0;
+ data.byte(kCh0playing) = 255;
+ engine->stopSound(0);
}
-Sprite *DreamGenContext::makesprite(uint8 x, uint8 y, uint16 updateCallback, uint16 somethingInDx, uint16 somethingInDi) {
- Sprite *sprite = spritetable();
- while (sprite->b15 != 0xff) { // NB: No boundchecking in the original code either
- ++sprite;
- }
+void DreamGenContext::cancelch1() {
+ data.word(kCh1blockstocopy) = 0;
+ data.byte(kCh1playing) = 255;
+ engine->stopSound(1);
+}
- WRITE_LE_UINT16(&sprite->updateCallback, updateCallback);
- sprite->x = x;
- sprite->y = y;
- WRITE_LE_UINT16(&sprite->w6, somethingInDx);
- WRITE_LE_UINT16(&sprite->w8, somethingInDi);
- sprite->w2 = 0xffff;
- sprite->b15 = 0;
- sprite->delay = 0;
- return sprite;
+void DreamGenContext::getroomspaths() {
+ es = data.word(kReels);
+ bx = data.byte(kRoomnum) * 144;
+}
+
+uint8 *DreamGenContext::getroomspathsCPP() {
+ void *result = segRef(data.word(kReels)).ptr(data.byte(kRoomnum) * 144, 144);
+ return (uint8 *)result;
}
-void DreamGenContext::makesprite() { // NB: returns new sprite in es:bx
- Sprite *sprite = makesprite(si & 0xff, si >> 8, cx, dx, di);
+void DreamGenContext::makebackob() {
+ if (data.byte(kNewobs) == 0)
+ return;
+ uint8 priority = es.byte(si+5);
+ uint8 type = es.byte(si+8);
+ Sprite *sprite = makesprite(data.word(kObjectx), data.word(kObjecty), addr_backobject, data.word(kSetframes), 0);
// Recover es:bx from sprite
es = data.word(kBuffers);
@@ -1230,428 +692,391 @@ void DreamGenContext::makesprite() { // NB: returns new sprite in es:bx
Sprite *sprites = (Sprite *)es.ptr(bx, sizeof(Sprite) * 16);
bx += sizeof(Sprite) * (sprite - sprites);
//
+ sprite->setObjData(si);
+ if (priority == 255)
+ priority = 0;
+ sprite->priority = priority;
+ sprite->type = type;
+ sprite->b16 = 0;
+ sprite->delay = 0;
+ sprite->frame = 0;
}
-void DreamGenContext::spriteupdate() {
- Sprite *sprites = spritetable();
- sprites[0].hidden = data.byte(kRyanon);
-
- Sprite *sprite = sprites;
- for (size_t i=0; i < 16; ++i) {
- uint16 updateCallback = READ_LE_UINT16(&sprite->updateCallback);
- if (updateCallback != 0xffff) {
- sprite->w24 = sprite->w2;
- if (updateCallback == addr_mainman) // NB : Let's consider the callback as an enum while more code is not ported to C++
- mainmanCPP(sprite);
- else {
- assert(updateCallback == addr_backobject);
- backobject(sprite);
- }
- }
-
- if (data.byte(kNowinnewroom) == 1)
- break;
- ++sprite;
- }
+void DreamGenContext::getroomdata() {
+ bx = kRoomdata + sizeof(Room) * al;
}
-void DreamGenContext::initman() {
- Sprite *sprite = makesprite(data.byte(kRyanx), data.byte(kRyany), addr_mainman, data.word(kMainsprites), 0);
- sprite->priority = 4;
- sprite->b22 = 0;
- sprite->b29 = 0;
-
- // Recover es:bx from sprite
- es = data.word(kBuffers);
- bx = kSpritetable;
- Sprite *sprites = (Sprite *)es.ptr(bx, sizeof(Sprite) * 16);
- bx += 32 * (sprite - sprites);
- //
+void DreamGenContext::getroomdata(uint8 roomIndex) {
+ getroomdata(roomIndex);
}
-void DreamGenContext::mainmanCPP(Sprite *sprite) {
- push(es);
- push(ds);
+void DreamGenContext::startloading() {
+ const Room *room = (Room *)cs.ptr(bx, sizeof(Room));
+ startloading(room);
+}
- // Recover es:bx from sprite
- es = data.word(kBuffers);
- bx = kSpritetable;
- Sprite *sprites = (Sprite *)es.ptr(bx, sizeof(Sprite) * 16);
- bx += 32 * (sprite - sprites);
- //
+void DreamGenContext::readheader() {
+ ax = engine->readFromFile(cs.ptr(kFileheader, kHeaderlen), kHeaderlen);
+ es = cs;
+ di = kFiledata;
+}
- if (data.byte(kResetmanxy) == 1) {
- data.byte(kResetmanxy) = 0;
- sprite->x = data.byte(kRyanx);
- sprite->y = data.byte(kRyany);
- sprite->b29 = 0;
- }
- --sprite->b22;
- if (sprite->b22 != 0xff) {
- ds = pop();
- es = pop();
- return;
+void DreamGenContext::startloading(const Room *room) {
+ data.byte(kCombatcount) = 0;
+ data.byte(kRoomssample) = room->roomsSample;
+ data.byte(kMapx) = room->mapX;
+ data.byte(kMapy) = room->mapY;
+ data.byte(kLiftflag) = room->liftFlag;
+ data.byte(kManspath) = room->b21;
+ data.byte(kDestination) = room->b21;
+ data.byte(kFinaldest) = room->b21;
+ data.byte(kFacing) = room->b22;
+ data.byte(kTurntoface) = room->b22;
+ data.byte(kCounttoopen) = room->countToOpen;
+ data.byte(kLiftpath) = room->liftPath;
+ data.byte(kDoorpath) = room->doorPath;
+ data.byte(kLastweapon) = -1;
+ al = room->b27;
+ push(ax);
+ al = room->b31;
+ ah = data.byte(kReallocation);
+ data.byte(kReallocation) = al;
+ dx = bx;
+ Common::String name = getFilename(*this);
+ engine->openFile(name);
+ cs.word(kHandle) = 1; //only one handle
+ flags._c = false;
+ readheader();
+ allocateload();
+ ds = ax;
+ data.word(kBackdrop) = ax;
+ dx = (0);
+ loadseg();
+ ds = data.word(kWorkspace);
+ dx = (0);
+ cx = 132*66;
+ al = 0;
+ fillspace();
+ loadseg();
+ sortoutmap();
+ allocateload();
+ data.word(kSetframes) = ax;
+ ds = ax;
+ dx = (0);
+ loadseg();
+ ds = data.word(kSetdat);
+ dx = 0;
+ cx = (64*128);
+ al = 255;
+ fillspace();
+ loadseg();
+ allocateload();
+ data.word(kReel1) = ax;
+ ds = ax;
+ dx = 0;
+ loadseg();
+ allocateload();
+ data.word(kReel2) = ax;
+ ds = ax;
+ dx = 0;
+ loadseg();
+ allocateload();
+ data.word(kReel3) = ax;
+ ds = ax;
+ dx = 0;
+ loadseg();
+ allocateload();
+ data.word(kReels) = ax;
+ ds = ax;
+ dx = 0;
+ loadseg();
+ allocateload();
+ data.word(kPeople) = ax;
+ ds = ax;
+ dx = 0;
+ loadseg();
+ allocateload();
+ data.word(kSetdesc) = ax;
+ ds = ax;
+ dx = 0;
+ loadseg();
+ allocateload();
+ data.word(kBlockdesc) = ax;
+ ds = ax;
+ dx = 0;
+ loadseg();
+ allocateload();
+ data.word(kRoomdesc) = ax;
+ ds = ax;
+ dx = 0;
+ loadseg();
+ allocateload();
+ data.word(kFreeframes) = ax;
+ ds = ax;
+ dx = 0;
+ loadseg();
+ ds = data.word(kFreedat);
+ dx = 0;
+ cx = (16*80);
+ al = 255;
+ fillspace();
+ loadseg();
+ allocateload();
+ data.word(kFreedesc) = ax;
+ ds = ax;
+ dx = (0);
+ loadseg();
+ closefile();
+ findroominloc();
+ deletetaken();
+ setallchanges();
+ autoappear();
+ al = data.byte(kNewlocation);
+ getroomdata();
+ data.byte(kLastweapon) = -1;
+ data.byte(kMandead) = 0;
+ data.word(kLookcounter) = 160;
+ data.byte(kNewlocation) = 255;
+ data.byte(kLinepointer) = 254;
+ ax = pop();
+ if (al != 255) {
+ data.byte(kManspath) = al;
+ push(bx);
+ autosetwalk();
+ bx = pop();
}
- sprite->b22 = 0;
- if (data.byte(kTurntoface) != data.byte(kFacing)) {
- aboutturn(sprite);
+ findxyfrompath();
+}
+
+void DreamGenContext::fillspace() {
+ memset(ds.ptr(dx, cx), al, cx);
+}
+
+void DreamGenContext::dealwithspecial(uint8 firstParam, uint8 secondParam) {
+ uint8 type = firstParam - 220;
+ if (type == 0) {
+ al = secondParam;
+ placesetobject();
+ data.byte(kHavedoneobs) = 1;
+ } else if (type == 1) {
+ al = secondParam;
+ removesetobject();
+ data.byte(kHavedoneobs) = 1;
+ } else if (type == 2) {
+ al = secondParam;
+ placefreeobject();
+ data.byte(kHavedoneobs) = 1;
+ } else if (type == 3) {
+ al = secondParam;
+ removefreeobject();
+ data.byte(kHavedoneobs) = 1;
+ } else if (type == 4) {
+ switchryanoff();
+ } else if (type == 5) {
+ data.byte(kTurntoface) = secondParam;
+ data.byte(kFacing) = secondParam;
+ switchryanon();
+ } else if (type == 6) {
+ data.byte(kNewlocation) = secondParam;
} else {
- if ((data.byte(kTurndirection) != 0) && (data.byte(kLinepointer) == 254)) {
- data.byte(kReasseschanges) = 1;
- if (data.byte(kFacing) == data.byte(kLeavedirection))
- checkforexit();
- }
- data.byte(kTurndirection) = 0;
- if (data.byte(kLinepointer) == 254) {
- sprite->b29 = 0;
- } else {
- ++sprite->b29;
- if (sprite->b29 == 11)
- sprite->b29 = 1;
- walking();
- if (data.byte(kLinepointer) != 254) {
- if ((data.byte(kFacing) & 1) == 0)
- walking();
- else if ((sprite->b29 != 2) && (sprite->b29 != 7))
- walking();
- }
- if (data.byte(kLinepointer) == 254) {
- if (data.byte(kTurntoface) == data.byte(kFacing)) {
- data.byte(kReasseschanges) = 1;
- if (data.byte(kFacing) == data.byte(kLeavedirection))
- checkforexit();
- }
- }
- }
+ movemap(secondParam);
}
- static const uint8 facelist[] = { 0,60,33,71,11,82,22,93 };
- sprite->b15 = sprite->b29 + facelist[data.byte(kFacing)];
- data.byte(kRyanx) = sprite->x;
- data.byte(kRyany) = sprite->y;
-
- ds = pop();
- es = pop();
}
-void DreamGenContext::walking() {
- Sprite *sprite = (Sprite *)es.ptr(bx, sizeof(Sprite));
-
- uint8 comp;
- if (data.byte(kLinedirection) != 0) {
- --data.byte(kLinepointer);
- comp = 200;
- } else {
- ++data.byte(kLinepointer);
- comp = data.byte(kLinelength);
- }
- if (data.byte(kLinepointer) < comp) {
- sprite->x = data.byte(kLinedata + data.byte(kLinepointer) * 2 + 0);
- sprite->y = data.byte(kLinedata + data.byte(kLinepointer) * 2 + 1);
- return;
+void DreamGenContext::plotreel() {
+ Reel *reel = getreelstart();
+ while (true) {
+ if (reel->x < 220)
+ break;
+ if (reel->x == 255)
+ break;
+ dealwithspecial(reel->x, reel->y);
+ ++data.word(kReelpointer);
+ reel += 8;
}
- data.byte(kLinepointer) = 254;
- data.byte(kManspath) = data.byte(kDestination);
- if (data.byte(kDestination) == data.byte(kFinaldest)) {
- facerightway();
- return;
+ for (size_t i = 0; i < 8; ++i) {
+ if (reel->frame() != 0xffff)
+ showreelframe(reel);
+ ++reel;
}
- data.byte(kDestination) = data.byte(kFinaldest);
- push(es);
- push(bx);
- autosetwalk();
- bx = pop();
- es = pop();
+ soundonreels();
}
-void DreamGenContext::aboutturn(Sprite *sprite) {
- bool incdir = true;
-
- if (data.byte(kTurndirection) == 1)
- incdir = true;
- else if ((int8)data.byte(kTurndirection) == -1)
- incdir = false;
- else {
- if (data.byte(kFacing) < data.byte(kTurntoface)) {
- uint8 delta = data.byte(kTurntoface) - data.byte(kFacing);
- if (delta >= 4)
- incdir = false;
- else
- incdir = true;
- } else {
- uint8 delta = data.byte(kFacing) - data.byte(kTurntoface);
- if (delta >= 4)
- incdir = true;
- else
- incdir = false;
- }
- }
-
- if (incdir) {
- data.byte(kTurndirection) = 1;
- data.byte(kFacing) = (data.byte(kFacing) + 1) & 7;
- sprite->b29 = 0;
+void DreamGenContext::crosshair() {
+ uint8 frame;
+ if ((data.byte(kCommandtype) != 3) && (data.byte(kCommandtype) < 10)) {
+ frame = 9;
} else {
- data.byte(kTurndirection) = -1;
- data.byte(kFacing) = (data.byte(kFacing) - 1) & 7;
- sprite->b29 = 0;
+ frame = 29;
}
+ const Frame *src = (const Frame *)segRef(data.word(kIcons1)).ptr(0, 0);
+ uint8 width, height;
+ showframe(src, kZoomx + 24, kZoomy + 19, frame, 0, &width, &height);
}
-void DreamGenContext::backobject(Sprite *sprite) {
- push(es);
- push(ds);
-
- // Recover es:bx from sprite
- es = data.word(kBuffers);
- bx = kSpritetable;
- Sprite *sprites = (Sprite *)es.ptr(bx, sizeof(Sprite) * 16);
- bx += 32 * (sprite - sprites);
- //
-
- ds = data.word(kSetdat);
- di = READ_LE_UINT16(&sprite->obj_data);
- ObjData *objData = (ObjData *)ds.ptr(di, 0);
+void DreamGenContext::deltextline() {
+ uint16 x = data.word(kTextaddressx);
+ uint16 y = data.word(kTextaddressy);
+ if (data.byte(kForeignrelease) != 0)
+ y -= 3;
+ multiput(segRef(data.word(kBuffers)).ptr(kTextunder, 0), x, y, kUndertextsizex, kUndertextsizey);
+}
- if (sprite->delay != 0) {
- --sprite->delay;
- ds = pop();
- es = pop();
+void DreamGenContext::autosetwalk() {
+ al = data.byte(kManspath);
+ if (data.byte(kFinaldest) == al)
+ return;
+ const uint8 *roomsPaths = getroomspathsCPP();
+ checkdest(roomsPaths);
+ data.word(kLinestartx) = roomsPaths[data.byte(kManspath) * 8 + 0] - 12;
+ data.word(kLinestarty) = roomsPaths[data.byte(kManspath) * 8 + 1] - 12;
+ data.word(kLineendx) = roomsPaths[data.byte(kDestination) * 8 + 0] - 12;
+ data.word(kLineendy) = roomsPaths[data.byte(kDestination) * 8 + 1] - 12;
+ bresenhams();
+ if (data.byte(kLinedirection) != 0) {
+ data.byte(kLinepointer) = data.byte(kLinelength) - 1;
+ data.byte(kLinedirection) = 1;
return;
}
-
- sprite->delay = objData->delay;
- if (objData->type == 6)
- widedoor(sprite, objData);
- else if (objData->type == 5)
- random(sprite, objData);
- else if (objData->type == 4)
- lockeddoorway();
- else if (objData->type == 3)
- liftsprite(sprite, objData);
- else if (objData->type == 2)
- doorway(sprite, objData);
- else if (objData->type == 1)
- constant(sprite, objData);
- else
- steady(sprite, objData);
-
- ds = pop();
- es = pop();
-}
-
-void DreamGenContext::constant(Sprite *sprite, ObjData *objData) {
- ++sprite->frame;
- if (objData->b18[sprite->frame] == 255) {
- sprite->frame = 0;
+ data.byte(kLinepointer) = 0;
+}
+
+void DreamGenContext::checkdest(const uint8 *roomsPaths) {
+ const uint8 *p = roomsPaths + 12 * 8;
+ ah = data.byte(kManspath) << 4;
+ al = data.byte(kDestination);
+ uint8 destination = data.byte(kDestination);
+ for (size_t i = 0; i < 24; ++i) {
+ dh = p[0] & 0xf0;
+ dl = p[0] & 0x0f;
+ if (ax == dx) {
+ data.byte(kDestination) = p[1] & 0x0f;
+ return;
+ }
+ dl = (p[0] & 0xf0) >> 4;
+ dh = (p[0] & 0x0f) << 4;
+ if (ax == dx) {
+ destination = p[1] & 0x0f;
+ }
+ p += 2;
}
- uint8 b18 = objData->b18[sprite->frame];
- objData->b17 = b18;
- sprite->b15 = b18;
-}
-
-void DreamGenContext::random(Sprite *sprite, ObjData *objData) {
- randomnum1();
- uint16 r = ax;
- sprite->b15 = objData->b18[r&7];
-}
-
-void DreamGenContext::doorway(Sprite *sprite, ObjData *objData) {
- data.byte(kDoorcheck1) = -24;
- data.byte(kDoorcheck2) = 10;
- data.byte(kDoorcheck3) = -30;
- data.byte(kDoorcheck4) = 10;
- dodoor(sprite, objData);
-}
-
-void DreamGenContext::widedoor(Sprite *sprite, ObjData *objData) {
- data.byte(kDoorcheck1) = -24;
- data.byte(kDoorcheck2) = 24;
- data.byte(kDoorcheck3) = -30;
- data.byte(kDoorcheck4) = 24;
- dodoor(sprite, objData);
-}
-
-void DreamGenContext::dodoor() {
- Sprite *sprite = (Sprite *)es.ptr(bx, sizeof(Sprite));
- ObjData *objData = (ObjData *)ds.ptr(di, 0);
- dodoor(sprite, objData);
-}
-
-void DreamGenContext::dodoor(Sprite *sprite, ObjData *objData) {
- uint8 ryanx = data.byte(kRyanx);
- uint8 ryany = data.byte(kRyany);
- int8 deltax = ryanx - sprite->x;
- int8 deltay = ryany - sprite->y;
- if (ryanx < sprite->x) {
- if (deltax < (int8)data.byte(kDoorcheck1))
- goto shutdoor;
- } else {
- if (deltax >= data.byte(kDoorcheck2))
- goto shutdoor;
+ data.byte(kDestination) = destination;
+}
+
+void DreamGenContext::checkifperson() {
+ flags._z = not checkifperson(al, ah);
+}
+
+bool DreamGenContext::checkifperson(uint8 x, uint8 y) {
+ People *people = (People *)segRef(data.word(kBuffers)).ptr(kPeoplelist, 0);
+
+ for (size_t i = 0; i < 12; ++i, ++people) {
+ if (people->b4 == 255)
+ continue;
+ data.word(kReelpointer) = people->w0();
+ Reel *reel = getreelstart();
+ if (reel->frame() == 0xffff)
+ ++reel;
+ const Frame *frame = getreelframeax(reel->frame());
+ uint8 xmin = reel->x + frame->x;
+ uint8 ymin = reel->y + frame->y;
+ uint8 xmax = xmin + frame->width;
+ uint8 ymax = ymin + frame->height;
+ if (x < xmin)
+ continue;
+ if (y < ymin)
+ continue;
+ if (x >= xmax)
+ continue;
+ if (y >= ymax)
+ continue;
+ data.word(kPersondata) = people->w2();
+ al = people->b4;
+ ah = 5;
+ obname();
+ return true;
}
- if (ryany < sprite->y) {
- if (deltay < (int8)data.byte(kDoorcheck3))
- goto shutdoor;
+ return false;
+}
+
+const uint8 *DreamGenContext::findobname(uint8 type, uint8 index) {
+ if (type == 5) {
+ uint16 i = 64 * 2 * (index & 127);
+ uint16 offset = segRef(data.word(kPeople)).word(kPersontxtdat + i) + kPersontext;
+ return segRef(data.word(kPeople)).ptr(offset, 0);
+ } else if (type == 4) {
+ uint16 offset = segRef(data.word(kExtras)).word(kExtextdat + index * 2) + kExtext;
+ return segRef(data.word(kExtras)).ptr(offset, 0);
+ } else if (type == 2) {
+ uint16 offset = segRef(data.word(kFreedesc)).word(kFreetextdat + index * 2) + kFreetext;
+ return segRef(data.word(kFreedesc)).ptr(offset, 0);
+ } else if (type == 1) {
+ uint16 offset = segRef(data.word(kSetdesc)).word(kSettextdat + index * 2) + kSettext;
+ return segRef(data.word(kSetdesc)).ptr(offset, 0);
} else {
- if (deltay >= data.byte(kDoorcheck4))
- goto shutdoor;
- }
-//opendoor:
- if ((data.byte(kThroughdoor) == 1) && (sprite->frame == 0))
- sprite->frame = 6;
-
- ++sprite->frame;
- if (sprite->frame == 1) { //doorsound2
- if (data.byte(kReallocation) == 5) //hoteldoor2
- al = 13;
- else
- al = 0;
- playchannel1();
- }
- if (objData->b18[sprite->frame] == 255) {
- --sprite->frame;
- }
- sprite->b15 = objData->b17 = objData->b18[sprite->frame];
- data.byte(kThroughdoor) = 1;
- return;
-shutdoor:
- if (sprite->frame == 5) { //doorsound1;
- if (data.byte(kReallocation) == 5) //hoteldoor1
- al = 13;
- else
- al = 1;
- playchannel1();
- }
- if (sprite->frame != 0) {
- --sprite->frame;
+ uint16 offset = segRef(data.word(kBlockdesc)).word(kBlocktextdat + index * 2) + kBlocktext;
+ return segRef(data.word(kBlockdesc)).ptr(offset, 0);
}
- sprite->b15 = objData->b17 = objData->b18[sprite->frame];
- if (sprite->frame == 5) //nearly
- data.byte(kThroughdoor) = 0;
-}
-
-void DreamGenContext::steady(Sprite *sprite, ObjData *objData) {
- uint8 b18 = objData->b18[0];
- objData->b17 = b18;
- sprite->b15 = b18;
-}
-
-void DreamGenContext::turnpathonCPP(uint8 param) {
- al = param;
- push(es);
- push(bx);
- turnpathon();
- bx = pop();
- es = pop();
}
-void DreamGenContext::turnpathoffCPP(uint8 param) {
- al = param;
- push(es);
- push(bx);
- turnpathoff();
- bx = pop();
- es = pop();
+void DreamGenContext::copyname() {
+ copyname(ah, al, cs.ptr(di, 0));
}
-void DreamGenContext::liftsprite() {
- Sprite *sprite = (Sprite *)es.ptr(bx, sizeof(Sprite));
- ObjData *objData = (ObjData *)ds.ptr(di, 0);
- liftsprite(sprite, objData);
-}
-
-void DreamGenContext::liftsprite(Sprite *sprite, ObjData *objData) {
- uint8 liftFlag = data.byte(kLiftflag);
- if (liftFlag == 0) { //liftclosed
- turnpathoffCPP(data.byte(kLiftpath));
-
- if (data.byte(kCounttoopen) != 0) {
- _dec(data.byte(kCounttoopen));
- if (data.byte(kCounttoopen) == 0)
- data.byte(kLiftflag) = 3;
- }
- sprite->frame = 0;
- sprite->b15 = objData->b17 = objData->b18[sprite->frame];
- }
- else if (liftFlag == 1) { //liftopen
- turnpathonCPP(data.byte(kLiftpath));
-
- if (data.byte(kCounttoclose) != 0) {
- _dec(data.byte(kCounttoclose));
- if (data.byte(kCounttoclose) == 0)
- data.byte(kLiftflag) = 2;
- }
- sprite->frame = 12;
- sprite->b15 = objData->b17 = objData->b18[sprite->frame];
- }
- else if (liftFlag == 3) { //openlift
- if (sprite->frame == 12) {
- data.byte(kLiftflag) = 1;
- return;
- }
- ++sprite->frame;
- if (sprite->frame == 1) {
- al = 2;
- liftnoise();
- }
- sprite->b15 = objData->b17 = objData->b18[sprite->frame];
- } else { //closeLift
- assert(liftFlag == 2);
- if (sprite->frame == 0) {
- data.byte(kLiftflag) = 0;
- return;
- }
- --sprite->frame;
- if (sprite->frame == 11) {
- al = 3;
- liftnoise();
- }
- sprite->b15 = objData->b17 = objData->b18[sprite->frame];
+void DreamGenContext::copyname(uint8 type, uint8 index, uint8 *dst) {
+ const uint8 *src = findobname(type, index);
+ size_t i;
+ for (i = 0; i < 28; ++i) {
+ char c = src[i];
+ if (c == ':')
+ break;
+ if (c == 0)
+ break;
+ dst[i] = c;
}
+ dst[i] = 0;
}
-void DreamGenContext::modifychar() {
- al = engine->modifyChar(al);
+void DreamGenContext::commandwithob() {
+ commandwithob(al, bh, bl);
}
-void DreamGenContext::lockmon() {
- // Pressing space pauses text output in the monitor. We use the "hard"
- // key because calling readkey() drains characters from the input
- // buffer, we we want the user to be able to type ahead while the text
- // is being printed.
- if (data.byte(kLasthardkey) == 57) {
- // Clear the keyboard buffer. Otherwise the space that caused
- // the pause will be read immediately unpause the game.
- do {
- readkey();
- } while (data.byte(kCurrentkey) != 0);
-
- locklighton();
- while (!engine->shouldQuit()) {
- engine->waitForVSync();
- readkey();
- if (data.byte(kCurrentkey) == ' ')
- break;
- }
- // Forget the last "hard" key, otherwise the space that caused
- // the unpausing will immediately re-pause the game.
- data.byte(kLasthardkey) = 0;
- locklightoff();
+void DreamGenContext::commandwithob(uint8 command, uint8 type, uint8 index) {
+ uint8 commandLine[64] = "OBJECT NAME ONE ";
+ deltextline();
+ uint16 commandText = kTextstart + segRef(data.word(kCommandtext)).word(command * 2);
+ uint8 textLen = data.byte(kTextlen);
+ {
+ uint16 y = data.word(kTextaddressy);
+ const uint8 *string = segRef(data.word(kCommandtext)).ptr(commandText, 0);
+ printdirect(&string, data.word(kTextaddressx), &y, textLen, (bool)(textLen & 1));
}
+ copyname(type, index, commandLine);
+ uint16 x = data.word(kLastxpos);
+ if (command != 0)
+ x += 5;
+ {
+ uint16 y = data.word(kTextaddressy);
+ const uint8 *string = commandLine;
+ printdirect(&string, x, &y, textLen, (bool)(textLen & 1));
+ }
+ data.byte(kNewtextline) = 1;
}
-void DreamGenContext::cancelch0() {
- data.byte(kCh0repeat) = 0;
- data.word(kCh0blockstocopy) = 0;
- data.byte(kCh0playing) = 255;
- engine->stopSound(0);
+void DreamGenContext::showpanel() {
+ Frame *frame = (Frame *)segRef(data.word(kIcons1)).ptr(0, sizeof(Frame));
+ uint8 width, height;
+ showframe(frame, 72, 0, 19, 0, &width, &height);
+ showframe(frame, 192, 0, 19, 0, &width, &height);
}
-void DreamGenContext::cancelch1() {
- data.word(kCh1blockstocopy) = 0;
- data.byte(kCh1playing) = 255;
- engine->stopSound(1);
+bool DreamGenContext::isCD() {
+ // The original sources has two codepaths depending if the game is 'if cd' or not
+ // This is a hack to guess which version to use with the assumption that if we have a cd version
+ // we managed to load the speech. At least it is isolated in this function and can be changed.
+ // Maybe detect the version during game id?
+ return (data.byte(kSpeechloaded) == 1);
}
-
} /*namespace dreamgen */
+
diff --git a/engines/dreamweb/stubs.h b/engines/dreamweb/stubs.h
index b633684f4d..c4385613f6 100644
--- a/engines/dreamweb/stubs.h
+++ b/engines/dreamweb/stubs.h
@@ -19,7 +19,10 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
*/
-
+ uint16 allocatemem(uint16 paragraphs);
+ uint8 *workspace();
+ void allocatework();
+ void clearwork();
void multidump();
void multidump(uint16 x, uint16 y, uint8 width, uint8 height);
void frameoutv(uint8 *dst, const uint8 *src, uint16 pitch, uint16 width, uint16 height, uint16 x, uint16 y);
@@ -28,7 +31,7 @@
void frameoutfx(uint8 *dst, const uint8 *src, uint16 pitch, uint16 width, uint16 height, uint16 x, uint16 y);
void worktoscreen();
void multiget();
- void multiget(uint16 x, uint16 y, uint8 width, uint8 height);
+ void multiget(uint8 *dst, uint16 x, uint16 y, uint8 width, uint8 height);
void convertkey();
void cls();
void printsprites();
@@ -38,39 +41,49 @@
void seecommandtail();
void randomnumber();
void quickquit2();
- void getnextword();
- uint8 getnextword(const uint8 *string, uint8 *totalWidth, uint8 *charCount);
- void printboth();
- void printboth(uint16 dst, uint16 src, uint16 *x, uint16 y, uint8 c);
+ uint8 getnextword(const Frame *charSet, const uint8 *string, uint8 *totalWidth, uint8 *charCount);
+ void printboth(const Frame* charSet, uint16 *x, uint16 y, uint8 c, uint8 nextChar);
void printchar();
- void printchar(uint16 dst, uint16 src, uint16 *x, uint16 y, uint8 c, uint8 *width, uint8 *height);
+ void printchar(const Frame* charSet, uint16 *x, uint16 y, uint8 c, uint8 nextChar, uint8 *width, uint8 *height);
void printdirect();
- void printdirect(uint16 x, uint16 *y, uint8 maxWidth, bool centered);
+ void printdirect(const uint8** string, uint16 x, uint16 *y, uint8 maxWidth, bool centered);
void usetimedtext();
+ void dumptimedtext();
+ void setuptimedtemp();
+ void setuptimedtemp(uint8 textIndex, uint8 voiceIndex, uint8 x, uint8 y, uint16 countToTimed, uint16 timeCount);
void getundertimed();
void putundertimed();
- uint8 printslow(uint16 x, uint16 y, uint8 maxWidth, bool centered);
+ uint8 printslow(const uint8 *string, uint16 x, uint16 y, uint8 maxWidth, bool centered);
void printslow();
void dumptextline();
void getnumber();
- uint8 getnumber(uint16 index, uint16 maxWidth, bool centered, uint16* offset);
+ uint8 getnumber(const Frame *charSet, const uint8 *string, uint16 maxWidth, bool centered, uint16 *offset);
void kernchars();
uint8 kernchars(uint8 firstChar, uint8 secondChar, uint8 width);
+ void getroomdata();
+ void getroomdata(uint8 roomIndex);
+ void readheader();
+ void fillspace();
+ void startloading();
+ void startloading(const Room *room);
Sprite *spritetable();
void showframe();
- void showframe(uint16 dst, uint16 src, uint16 x, uint16 y, uint16 frameNumber, uint8 effectsFlag, uint8 *width, uint8 *height);
+ void showframe(const Frame *frameData, uint16 x, uint16 y, uint16 frameNumber, uint8 effectsFlag, uint8 *width, uint8 *height);
void printasprite(const Sprite *sprite);
void width160();
- void multiput(uint16 x, uint16 y, uint8 width, uint8 height);
+ void multiput(const uint8 *src, uint16 x, uint16 y, uint8 width, uint8 height);
void multiput();
void eraseoldobs();
void clearsprites();
void makesprite();
- Sprite *makesprite(uint8 x, uint8 y, uint16 updateCallback, uint16 somethingInDx, uint16 somethingInDi);
+ Sprite *makesprite(uint8 x, uint8 y, uint16 updateCallback, uint16 frameData, uint16 somethingInDi);
void spriteupdate();
void initman();
- void mainmanCPP(Sprite *sprite);
- void walking();
+ void mainman(Sprite *sprite);
+ void facerightway();
+ void walking(Sprite *sprite);
+ void autosetwalk();
+ void checkdest(const uint8 *roomsPaths);
void aboutturn(Sprite *sprite);
void backobject(Sprite *sprite);
void constant(Sprite *sprite, ObjData *objData);
@@ -80,11 +93,42 @@
void dodoor(Sprite *sprite, ObjData *objData);
void doorway(Sprite *sprite, ObjData *objData);
void widedoor(Sprite *sprite, ObjData *objData);
- void liftsprite();
+ void lockeddoorway(Sprite *sprite, ObjData *objData);
void liftsprite(Sprite *sprite, ObjData *objData);
+ void findsource();
+ Frame *findsourceCPP();
+ void showgamereel();
+ void showreelframe();
+ void showreelframe(Reel *reel);
+ const Frame *getreelframeax(uint16 frame);
void turnpathonCPP(uint8 param);
void turnpathoffCPP(uint8 param);
+ void getroomspaths();
+ uint8 *getroomspathsCPP();
+ void makebackob();
void modifychar();
void lockmon();
void cancelch0();
void cancelch1();
+ void plotreel();
+ Reel *getreelstart();
+ void dealwithspecial(uint8 firstParam, uint8 secondParam);
+ void zoom();
+ void crosshair();
+ void showrain();
+ void deltextline();
+ void doblocks();
+ void checkifperson();
+ bool checkifperson(uint8 x, uint8 y);
+ const uint8 *findobname(uint8 type, uint8 index);
+ void copyname();
+ void copyname(uint8 type, uint8 index, uint8 *dst);
+ void commandwithob();
+ void commandwithob(uint8 command, uint8 type, uint8 index);
+ void showpanel();
+ void updatepeople();
+ void madmantext();
+ void madmode();
+ void movemap(uint8 param);
+ bool isCD();
+
diff --git a/engines/dreamweb/vgagrafx.cpp b/engines/dreamweb/vgagrafx.cpp
new file mode 100644
index 0000000000..c87e27a8c4
--- /dev/null
+++ b/engines/dreamweb/vgagrafx.cpp
@@ -0,0 +1,452 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "dreamweb/dreamweb.h"
+#include "engines/util.h"
+#include "graphics/surface.h"
+
+namespace DreamGen {
+
+uint8 *DreamGenContext::workspace() {
+ uint8 *result = segRef(data.word(kWorkspace)).ptr(0, 0);
+ return result;
+}
+
+void DreamGenContext::allocatework() {
+ data.word(kWorkspace) = allocatemem(0x1000);
+}
+
+void DreamGenContext::multiget() {
+ multiget(ds.ptr(si, 0), di, bx, cl, ch);
+ si += cl * ch;
+ di += bx * kScreenwidth + kScreenwidth * ch;
+ cx = 0;
+}
+
+void DreamGenContext::multiget(uint8 *dst, uint16 x, uint16 y, uint8 w, uint8 h) {
+ const uint8 *src = workspace() + x + y * kScreenwidth;
+ if (y + h > 200)
+ h = 200 - y;
+ if (x + w > 320)
+ w = 320 - x;
+ //debug(1, "multiget %u,%u %ux%u -> segment: %04x->%04x", x, y, w, h, (uint16)ds, (uint16)es);
+ for(unsigned l = 0; l < h; ++l) {
+ const uint8 *src_p = src + kScreenwidth * l;
+ uint8 *dst_p = dst + w * l;
+ memcpy(dst_p, src_p, w);
+ }
+}
+
+void DreamGenContext::multiput() {
+ multiput(ds.ptr(si, 0), di, bx, cl, ch);
+ si += cl * ch;
+ di += bx * kScreenwidth + kScreenwidth * ch;
+ cx = 0;
+}
+
+void DreamGenContext::multiput(const uint8 *src, uint16 x, uint16 y, uint8 w, uint8 h) {
+ uint8 *dst = workspace() + x + y * kScreenwidth;
+ if (y + h > 200)
+ h = 200 - y;
+ if (x + w > 320)
+ w = 320 - x;
+ //debug(1, "multiput %ux%u -> segment: %04x->%04x", w, h, (uint16)ds, (uint16)es);
+ for(unsigned l = 0; l < h; ++l) {
+ const uint8 *src_p = src + w * l;
+ uint8 *dst_p = dst + kScreenwidth * l;
+ memcpy(dst_p, src_p, w);
+ }
+}
+
+void DreamGenContext::multidump(uint16 x, uint16 y, uint8 width, uint8 height) {
+ unsigned offset = x + y * kScreenwidth;
+ //debug(1, "multidump %ux%u(segment: %04x) -> %d,%d(address: %d)", w, h, (uint16)ds, x, y, offset);
+ engine->blit(workspace() + offset, kScreenwidth, x, y, width, height);
+}
+
+void DreamGenContext::multidump() {
+ multidump(di, bx, cl, ch);
+ unsigned offset = di + bx * kScreenwidth;
+ si = di = offset + ch * kScreenwidth;
+ cx = 0;
+}
+
+void DreamGenContext::worktoscreen() {
+ uint size = 320 * 200;
+ engine->blit(workspace(), 320, 0, 0, 320, 200);
+ di = si = size;
+ cx = 0;
+}
+
+void DreamGenContext::printundermon() {
+ engine->printUnderMonitor();
+}
+
+void DreamGenContext::cls() {
+ engine->cls();
+}
+
+void DreamGenContext::frameoutnm(uint8 *dst, const uint8 *src, uint16 pitch, uint16 width, uint16 height, uint16 x, uint16 y) {
+ dst += pitch * y + x;
+
+ for (uint16 j = 0; j < height; ++j) {
+ memcpy(dst, src, width);
+ dst += pitch;
+ src += width;
+ }
+}
+
+void DreamGenContext::frameoutbh(uint8 *dst, const uint8 *src, uint16 pitch, uint16 width, uint16 height, uint16 x, uint16 y) {
+ uint16 stride = pitch - width;
+ dst += y * pitch + x;
+
+ for (uint16 i = 0; i < height; ++i) {
+ for (uint16 j = 0; j < width; ++j) {
+ if (*dst == 0xff) {
+ *dst = *src;
+ }
+ ++src;
+ ++dst;
+ }
+ dst += stride;
+ }
+}
+
+void DreamGenContext::frameoutfx(uint8 *dst, const uint8 *src, uint16 pitch, uint16 width, uint16 height, uint16 x, uint16 y) {
+ uint16 stride = pitch - width;
+ dst += y * pitch + x;
+ dst -= width;
+
+ for (uint16 j = 0; j < height; ++j) {
+ for (uint16 i = 0; i < width; ++i) {
+ uint8 pixel = src[width - i - 1];
+ if (pixel)
+ *dst = pixel;
+ ++dst;
+ }
+ src += width;
+ dst += stride;
+ }
+}
+
+void DreamGenContext::doshake() {
+ uint8 &counter = data.byte(kShakecounter);
+ _cmp(counter, 48);
+ if (flags.z())
+ return;
+
+ _add(counter, 1);
+ static const int shakeTable[] = {
+ 0, -2, 3, -2, 0, 2, 4, -1,
+ 1, -3, 3, 2, 0, -2, 3, -2,
+ 0, 2, 4, -1, 1, -3, 3, 2,
+ 0, -2, 3, -2, 0, 2, 4, -1,
+
+ 1, -3, 3, 2, 0, -2, 3, -2,
+ 0, 2, 4, -1, 1, -3, 3, 2,
+ 0, -2, 3, -2, 0, 2, 4, -1,
+ 1, -3, 3, 2, 0, -2, 3, -2,
+
+ 0, 2, 4, -1, 1, -3, 3, 2,
+ 0, -2, 3, -2, 0, 2, 4, -1,
+ 1, -3, 3, 2, 0, -2, 3, -2,
+ 0, 2, 4, -1, 1, -3, 3, 2,
+
+ 0, -2, 3, -2, 0, 2, 4, -1,
+ 1, -3, 3, 0,
+ };
+ int offset = shakeTable[counter];
+ engine->setShakePos(offset >= 0 ? offset : -offset);
+}
+
+void DreamGenContext::vsync() {
+ push(ax);
+ push(bx);
+ push(cx);
+ push(dx);
+ push(si);
+ push(di);
+ push(es);
+ push(ds);
+ engine->waitForVSync();
+ ds = pop();
+ es = pop();
+ di = pop();
+ si = pop();
+ dx = pop();
+ cx = pop();
+ bx = pop();
+ ax = pop();
+}
+
+void DreamGenContext::setmode() {
+ vsync();
+ initGraphics(320, 200, false);
+}
+
+static Common::String getFilename(Context &context) {
+ uint16 name_ptr = context.dx;
+ Common::String name;
+ uint8 c;
+ while((c = context.cs.byte(name_ptr++)) != 0)
+ name += (char)c;
+ return name;
+}
+
+void DreamGenContext::showpcx() {
+ Common::String name = getFilename(*this);
+ Common::File pcxFile;
+
+ if (!pcxFile.open(name)) {
+ warning("showpcx: Could not open '%s'", name.c_str());
+ return;
+ }
+
+ uint8 *maingamepal;
+ int i, j;
+
+ // Read the 16-color palette into the 'maingamepal' buffer. Note that
+ // the color components have to be adjusted from 8 to 6 bits.
+
+ pcxFile.seek(16, SEEK_SET);
+ es = data.word(kBuffers);
+ maingamepal = es.ptr(kMaingamepal, 768);
+ pcxFile.read(maingamepal, 48);
+
+ memset(maingamepal + 48, 0xff, 720);
+ for (i = 0; i < 48; i++) {
+ maingamepal[i] >>= 2;
+ }
+
+ // Decode the image data.
+
+ Graphics::Surface *s = g_system->lockScreen();
+ Common::Rect rect(640, 480);
+
+ s->fillRect(rect, 0);
+ pcxFile.seek(128, SEEK_SET);
+
+ for (int y = 0; y < 480; y++) {
+ byte *dst = (byte *)s->getBasePtr(0, y);
+ int decoded = 0;
+
+ while (decoded < 320) {
+ byte col = pcxFile.readByte();
+ byte len;
+
+ if ((col & 0xc0) == 0xc0) {
+ len = col & 0x3f;
+ col = pcxFile.readByte();
+ } else {
+ len = 1;
+ }
+
+ // The image uses 16 colors and is stored as four bit
+ // planes, one for each bit of the color, least
+ // significant bit plane first.
+
+ for (i = 0; i < len; i++) {
+ int plane = decoded / 80;
+ int pos = decoded % 80;
+
+ for (j = 0; j < 8; j++) {
+ byte bit = (col >> (7 - j)) & 1;
+ dst[8 * pos + j] |= (bit << plane);
+ }
+
+ decoded++;
+ }
+ }
+ }
+
+ g_system->unlockScreen();
+ pcxFile.close();
+}
+
+void DreamGenContext::frameoutv(uint8 *dst, const uint8 *src, uint16 pitch, uint16 width, uint16 height, uint16 x, uint16 y) {
+ // NB : These resilience checks were not in the original engine, but did they result in undefined behaviour
+ // or was something broken during porting to C++?
+ assert(pitch == 320);
+
+ if(x >= 320)
+ return;
+ if(y >= 200)
+ return;
+ if(x + width > 320) {
+ width = 320 - x;
+ }
+ if(y + height > 200) {
+ height = 200 - y;
+ }
+
+ uint16 stride = pitch - width;
+ dst += pitch * y + x;
+
+ for (uint16 j = 0; j < height; ++j) {
+ for (uint16 i = 0; i < width; ++i) {
+ uint8 pixel = *src++;
+ if (pixel)
+ *dst = pixel;
+ ++dst;
+ }
+ dst += stride;
+ }
+}
+
+void DreamGenContext::showframe(const Frame *frameData, uint16 x, uint16 y, uint16 frameNumber, uint8 effectsFlag, uint8 *width, uint8 *height) {
+ const Frame *frame = frameData + frameNumber;
+ if ((frame->width == 0) && (frame->height == 0)) {
+ *width = 0;
+ *height = 0;
+ return;
+ }
+
+//notblankshow:
+ if ((effectsFlag & 128) == 0) {
+ x += frame->x;
+ y += frame->y;
+ }
+//skipoffsets:
+
+ *width = frame->width;
+ *height = frame->height;
+ const uint8 *pSrc = ((const uint8 *)frameData) + frame->ptr() + 2080;
+
+ if (effectsFlag) {
+ if (effectsFlag & 128) { //centred
+ x -= *width / 2;
+ y -= *height / 2;
+ }
+ if (effectsFlag & 64) { //diffdest
+ frameoutfx(es.ptr(0, dx * *height), pSrc, dx, *width, *height, x, y);
+ return;
+ }
+ if (effectsFlag & 8) { //printlist
+ /*
+ push(ax);
+ al = x - data.word(kMapadx);
+ ah = y - data.word(kMapady);
+ //addtoprintlist(); // NB: Commented in the original asm
+ ax = pop();
+ */
+ }
+ if (effectsFlag & 4) { //flippedx
+ frameoutfx(workspace(), pSrc, 320, *width, *height, x, y);
+ return;
+ }
+ if (effectsFlag & 2) { //nomask
+ frameoutnm(workspace(), pSrc, 320, *width, *height, x, y);
+ return;
+ }
+ if (effectsFlag & 32) {
+ frameoutbh(workspace(), pSrc, 320, *width, *height, x, y);
+ return;
+ }
+ }
+//noeffects:
+ frameoutv(workspace(), pSrc, 320, *width, *height, x, y);
+ return;
+}
+
+void DreamGenContext::showframe() {
+ uint8 width, height;
+ showframe((Frame *)ds.ptr(0, 0), di, bx, ax & 0x1ff, ah & 0xfe, &width, &height);
+ cl = width;
+ ch = height;
+}
+
+void DreamGenContext::clearwork() {
+ memset(workspace(), 0, 320*200);
+}
+
+void DreamGenContext::doblocks() {
+ uint16 dstOffset = data.word(kMapady) * 320 + data.word(kMapadx);
+ uint16 mapOffset = kMap + data.byte(kMapy) * kMapwidth + data.byte(kMapx);
+ ds = data.word(kMapdata);
+ const uint8 *mapData = ds.ptr(mapOffset, 0);
+ ds = data.word(kBackdrop);
+ const uint8 *blocks = ds.ptr(kBlocks, 0);
+ es = data.word(kWorkspace);
+ uint8 *dstBuffer = es.ptr(dstOffset, 0);
+
+ for (size_t i = 0; i < 10; ++i) {
+ for (size_t j = 0; j < 11; ++j) {
+ uint16 blockType = mapData[j];
+ if (blockType != 0) {
+ uint8 *dst = dstBuffer + i * 320 * 16 + j * 16;
+ const uint8 *block = blocks + blockType * 256;
+ for (size_t k = 0; k < 4; ++k) {
+ memcpy(dst, block, 16);
+ block += 16;
+ dst += 320;
+ }
+ for (size_t k = 0; k < 12; ++k) {
+ memcpy(dst, block, 16);
+ memset(dst + 16, 0xdf, 4);
+ block += 16;
+ dst += 320;
+ }
+ dst += 4;
+ ax = 0x0dfdf;
+ memset(dst, 0xdf, 16);
+ dst += 320;
+ memset(dst, 0xdf, 16);
+ dst += 320;
+ memset(dst, 0xdf, 16);
+ dst += 320;
+ memset(dst, 0xdf, 16);
+ }
+ }
+ mapData += kMapwidth;
+ }
+}
+
+void DreamGenContext::zoom() {
+ if (data.word(kWatchingtime) != 0)
+ return;
+ if (data.byte(kZoomon) != 1)
+ return;
+ if (data.byte(kCommandtype) >= 199) {
+ putunderzoom();
+ return;
+ }
+ uint16 srcOffset = (data.word(kOldpointery) - 9) * 320 + (data.word(kOldpointerx) - 11);
+ uint16 dstOffset = (kZoomy + 4) * 320 + (kZoomx + 5);
+ const uint8 *src = workspace() + srcOffset;
+ uint8 *dst = workspace() + dstOffset;
+ for(size_t i=0; i<20; ++i) {
+ for(size_t j=0; j<23; ++j) {
+ uint8 v = src[j];
+ dst[2*j+0] = v;
+ dst[2*j+1] = v;
+ dst[2*j+320] = v;
+ dst[2*j+321] = v;
+ }
+ src += 320;
+ dst += 320*2;
+ }
+ crosshair();
+ data.byte(kDidzoom) = 1;
+}
+
+} /*namespace dreamgen */
+
diff --git a/engines/made/detection.cpp b/engines/made/detection.cpp
index 1320daaf9d..fa08923e44 100644
--- a/engines/made/detection.cpp
+++ b/engines/made/detection.cpp
@@ -104,7 +104,7 @@ static const MadeGameDescription gameDescriptions[] = {
AD_ENTRY1("rtzcd.red", "cd8b62ece4677c438688c1de3f5379b9"),
Common::EN_ANY,
Common::kPlatformPC,
- ADGF_NO_FLAGS,
+ ADGF_CD,
GUIO_NONE
},
GID_RTZ,
@@ -121,7 +121,7 @@ static const MadeGameDescription gameDescriptions[] = {
AD_ENTRY1s("rtzcd.dat", "a1db8c97a78dae10f91d356f16ad07b8", 536064),
Common::EN_ANY,
Common::kPlatformPC,
- ADGF_NO_FLAGS,
+ ADGF_CD,
GUIO_NONE
},
GID_RTZ,
@@ -138,7 +138,7 @@ static const MadeGameDescription gameDescriptions[] = {
AD_ENTRY1s("rtzcd.red", "c4e2430e6b6c6ff1562a80fb4a9df24c", 276177),
Common::EN_ANY,
Common::kPlatformPC,
- ADGF_NO_FLAGS,
+ ADGF_CD,
GUIO_NONE
},
GID_RTZ,
@@ -156,7 +156,7 @@ static const MadeGameDescription gameDescriptions[] = {
AD_ENTRY1("rtzcd.dat", "9d740378da2d16e83d0d0efff01bf83a"),
Common::EN_ANY,
Common::kPlatformPC,
- ADGF_NO_FLAGS,
+ ADGF_CD,
GUIO_NONE
},
GID_RTZ,
@@ -173,7 +173,7 @@ static const MadeGameDescription gameDescriptions[] = {
AD_ENTRY1s("rtzcd.red", "946997d8b0aa6cb4e848bad02a1fc3d2", 276584),
Common::EN_ANY,
Common::kPlatformPC,
- ADGF_NO_FLAGS,
+ ADGF_CD,
GUIO_NONE
},
GID_RTZ,
@@ -191,7 +191,7 @@ static const MadeGameDescription gameDescriptions[] = {
AD_ENTRY1s("rtzcd.dat", "9d740378da2d16e83d0d0efff01bf83a", 525824),
Common::DE_DEU,
Common::kPlatformPC,
- ADGF_NO_FLAGS,
+ ADGF_CD,
GUIO_NONE
},
GID_RTZ,
@@ -209,7 +209,7 @@ static const MadeGameDescription gameDescriptions[] = {
AD_ENTRY1s("rtzcd.red", "946997d8b0aa6cb4e848bad02a1fc3d2", 355442),
Common::DE_DEU,
Common::kPlatformPC,
- ADGF_NO_FLAGS,
+ ADGF_CD,
GUIO_NONE
},
GID_RTZ,
@@ -227,7 +227,7 @@ static const MadeGameDescription gameDescriptions[] = {
AD_ENTRY1s("rtzcd.dat", "5b86035aed0277f96e3d173542b5364a", 523776),
Common::IT_ITA,
Common::kPlatformPC,
- ADGF_NO_FLAGS,
+ ADGF_CD,
GUIO_NONE
},
GID_RTZ,
@@ -245,7 +245,7 @@ static const MadeGameDescription gameDescriptions[] = {
AD_ENTRY1s("rtzcd.red", "946997d8b0aa6cb4e848bad02a1fc3d2", 354971),
Common::IT_ITA,
Common::kPlatformPC,
- ADGF_NO_FLAGS,
+ ADGF_CD,
GUIO_NONE
},
GID_RTZ,
@@ -263,7 +263,7 @@ static const MadeGameDescription gameDescriptions[] = {
AD_ENTRY1s("rtzcd.dat", "bde8251a8e34e87c54e3f93147d56c9e", 523776),
Common::FR_FRA,
Common::kPlatformPC,
- ADGF_NO_FLAGS,
+ ADGF_CD,
GUIO_NONE
},
GID_RTZ,
@@ -281,7 +281,7 @@ static const MadeGameDescription gameDescriptions[] = {
AD_ENTRY1s("rtzcd.red", "946997d8b0aa6cb4e848bad02a1fc3d2", 354614),
Common::FR_FRA,
Common::kPlatformPC,
- ADGF_NO_FLAGS,
+ ADGF_CD,
GUIO_NONE
},
GID_RTZ,
@@ -333,7 +333,7 @@ static const MadeGameDescription gameDescriptions[] = {
AD_ENTRY1("rtzcd.dat", "c4fccf67ad247f09b94c3c808b138576"),
Common::JA_JPN,
Common::kPlatformPC,
- ADGF_NO_FLAGS,
+ ADGF_CD,
GUIO_NONE
},
GID_RTZ,
@@ -351,7 +351,7 @@ static const MadeGameDescription gameDescriptions[] = {
AD_ENTRY1("rtzcd.dat", "e949a6a42d82daabfa7d4dc0a87a9843"),
Common::JA_JPN,
Common::kPlatformFMTowns,
- ADGF_NO_FLAGS,
+ ADGF_CD,
GUIO_NONE
},
GID_RTZ,
@@ -369,7 +369,7 @@ static const MadeGameDescription gameDescriptions[] = {
AD_ENTRY1("rtzcd.dat", "0c0117e98530c736a141c2aad6834dc5"),
Common::JA_JPN,
Common::kPlatformPC98,
- ADGF_NO_FLAGS,
+ ADGF_CD,
GUIO_NONE
},
GID_RTZ,
@@ -386,7 +386,7 @@ static const MadeGameDescription gameDescriptions[] = {
AD_ENTRY1("manhole.dat", "cb21e31ed35c963208343bc995225b73"),
Common::EN_ANY,
Common::kPlatformPC,
- ADGF_NO_FLAGS,
+ ADGF_CD,
GUIO_NOSPEECH
},
GID_MANHOLE,
diff --git a/engines/mohawk/cursors.cpp b/engines/mohawk/cursors.cpp
index 78e099ccfe..cbd17e0b86 100644
--- a/engines/mohawk/cursors.cpp
+++ b/engines/mohawk/cursors.cpp
@@ -49,36 +49,13 @@ void CursorManager::hideCursor() {
}
void CursorManager::setDefaultCursor() {
- static const byte defaultCursor[] = {
- 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 1, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 1, 2, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0,
- 1, 2, 2, 2, 1, 0, 0, 0, 0, 0, 0, 0,
- 1, 2, 2, 2, 2, 1, 0, 0, 0, 0, 0, 0,
- 1, 2, 2, 2, 2, 2, 1, 0, 0, 0, 0, 0,
- 1, 2, 2, 2, 2, 2, 2, 1, 0, 0, 0, 0,
- 1, 2, 2, 2, 2, 2, 2, 2, 1, 0, 0, 0,
- 1, 2, 2, 2, 2, 2, 2, 2, 2, 1, 0, 0,
- 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 0,
- 1, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1,
- 1, 2, 2, 2, 1, 2, 2, 1, 0, 0, 0, 0,
- 1, 2, 2, 1, 1, 2, 2, 1, 0, 0, 0, 0,
- 1, 2, 1, 0, 1, 1, 2, 2, 1, 0, 0, 0,
- 1, 1, 0, 0, 0, 1, 2, 2, 1, 0, 0, 0,
- 1, 0, 0, 0, 0, 0, 1, 2, 2, 1, 0, 0,
- 0, 0, 0, 0, 0, 0, 1, 2, 2, 1, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 1, 2, 2, 1, 0,
- 0, 0, 0, 0, 0, 0, 0, 1, 2, 2, 1, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0
- };
-
- static const byte bwPalette[] = {
- 0x00, 0x00, 0x00, // Black
- 0xFF, 0xFF, 0xFF // White
- };
-
- CursorMan.replaceCursor(defaultCursor, 12, 20, 0, 0, 0);
- CursorMan.replaceCursorPalette(bwPalette, 1, 2);
+ Graphics::Cursor *cursor = Graphics::makeDefaultWinCursor();
+
+ CursorMan.replaceCursor(cursor->getSurface(), cursor->getWidth(), cursor->getHeight(), cursor->getHotspotX(),
+ cursor->getHotspotY(), cursor->getKeyColor());
+ CursorMan.replaceCursorPalette(cursor->getPalette(), cursor->getPaletteStartIndex(), cursor->getPaletteCount());
+
+ delete cursor;
}
void CursorManager::setCursor(uint16 id) {
diff --git a/engines/mohawk/detection_tables.h b/engines/mohawk/detection_tables.h
index 01eac0aaba..a587d06760 100644
--- a/engines/mohawk/detection_tables.h
+++ b/engines/mohawk/detection_tables.h
@@ -653,6 +653,23 @@ static const MohawkGameDescription gameDescriptions[] = {
"HARRY.EXE"
},
+ // part of "Super Living Books" compilation
+ // from rgemini, bug #3309343
+ {
+ {
+ "harryhh",
+ "",
+ AD_ENTRY1("HARRY.512", "39d11399796dfa36d3f631d2d87e8b85"),
+ Common::EN_ANY,
+ Common::kPlatformWindows,
+ ADGF_NO_FLAGS,
+ Common::GUIO_NONE
+ },
+ GType_LIVINGBOOKSV1,
+ 0,
+ "HARRY.EXE"
+ },
+
{
{
"carmentq",
@@ -929,6 +946,23 @@ static const MohawkGameDescription gameDescriptions[] = {
"TORTOISE.EXE"
},
+ // part of "Super Living Books" compilation
+ // from rgemini, bug #3309343
+ {
+ {
+ "tortoise",
+ "",
+ AD_ENTRY1("TORTOISE.512", "e9ec7a6bc6b451c9e85e5b4f072d5143"),
+ Common::EN_ANY,
+ Common::kPlatformWindows,
+ ADGF_NO_FLAGS,
+ Common::GUIO_NONE
+ },
+ GType_LIVINGBOOKSV1,
+ 0,
+ "TORTOISE.EXE"
+ },
+
// From afholman in bug#3309308
{
{
@@ -1053,6 +1087,23 @@ static const MohawkGameDescription gameDescriptions[] = {
"ARTHUR.EXE"
},
+ // part of "Super Living Books" compilation
+ // from rgemini, bug #3309343
+ {
+ {
+ "arthur",
+ "",
+ AD_ENTRY1("PAGES.512", "cd995d20d0d7b4642476fd76044b4e5b"),
+ Common::EN_ANY,
+ Common::kPlatformWindows,
+ ADGF_NO_FLAGS,
+ Common::GUIO_NONE
+ },
+ GType_LIVINGBOOKSV1,
+ GF_LB_10,
+ "ARTHUR.EXE"
+ },
+
// From afholman in bug#3309308
{
{
@@ -1195,6 +1246,22 @@ static const MohawkGameDescription gameDescriptions[] = {
"GRANDMA.EXE"
},
+ // from jjnryan in bug #3389857
+ {
+ {
+ "grandma",
+ "v1.0",
+ AD_ENTRY1("PAGES.512", "613ca946bc8d91087fb7c10e9b84e88b"),
+ Common::EN_ANY,
+ Common::kPlatformWindows,
+ ADGF_NO_FLAGS,
+ Common::GUIO_NONE
+ },
+ GType_LIVINGBOOKSV1,
+ GF_LB_10,
+ "GRANDMA.EXE"
+ },
+
{
{
"grandma",
@@ -1366,6 +1433,23 @@ static const MohawkGameDescription gameDescriptions[] = {
"NEWKID.EXE"
},
+ // part of "Super Living Books" compilation
+ // from rgemini, bug #3309343
+ {
+ {
+ "newkid",
+ "",
+ AD_ENTRY1("NEWKID.512", "28a5aef3e6ef7e2ed7742485c25bdff6"),
+ Common::EN_ANY,
+ Common::kPlatformWindows,
+ ADGF_NO_FLAGS,
+ Common::GUIO_NONE
+ },
+ GType_LIVINGBOOKSV1,
+ 0,
+ "NEWKID.EXE"
+ },
+
// From aluff in bug#3309981
{
{
diff --git a/engines/mohawk/dialogs.cpp b/engines/mohawk/dialogs.cpp
index 11e050aa72..2d1cc3bfa3 100644
--- a/engines/mohawk/dialogs.cpp
+++ b/engines/mohawk/dialogs.cpp
@@ -81,7 +81,8 @@ enum {
kTransCmd = 'TRAN',
kWaterCmd = 'WATR',
kDropCmd = 'DROP',
- kMapCmd = 'SMAP'
+ kMapCmd = 'SMAP',
+ kMenuCmd = 'MENU'
};
#ifdef ENABLE_MYST
@@ -97,6 +98,12 @@ MystOptionsDialog::MystOptionsDialog(MohawkEngine_Myst* vm) : GUI::OptionsDialog
else
_showMapButton = 0;
+ // Myst demo only has a menu
+ if (_vm->getFeatures() & GF_DEMO)
+ _returnToMenuButton = new GUI::ButtonWidget(this, 15, 95, 100, 25, _("~M~ain Menu"), 0, kMenuCmd);
+ else
+ _returnToMenuButton = 0;
+
new GUI::ButtonWidget(this, 95, 160, 120, 25, _("~O~K"), 0, GUI::kOKCmd);
new GUI::ButtonWidget(this, 225, 160, 120, 25, _("~C~ancel"), 0, GUI::kCloseCmd);
}
@@ -113,6 +120,11 @@ void MystOptionsDialog::open() {
_showMapButton->setEnabled(_vm->_scriptParser &&
_vm->_scriptParser->getMap());
+ // Return to menu button is not enabled on the menu
+ if (_returnToMenuButton)
+ _returnToMenuButton->setEnabled(_vm->_scriptParser &&
+ _vm->getCurStack() != kDemoStack);
+
// Zip mode is disabled in the demo
if (_vm->getFeatures() & GF_DEMO)
_zipModeCheckbox->setEnabled(false);
@@ -137,6 +149,10 @@ void MystOptionsDialog::handleCommand(GUI::CommandSender *sender, uint32 cmd, ui
_vm->_needsShowMap = true;
close();
break;
+ case kMenuCmd:
+ _vm->_needsShowDemoMenu = true;
+ close();
+ break;
case GUI::kCloseCmd:
close();
break;
diff --git a/engines/mohawk/dialogs.h b/engines/mohawk/dialogs.h
index 853ff30813..844c01ad26 100644
--- a/engines/mohawk/dialogs.h
+++ b/engines/mohawk/dialogs.h
@@ -83,6 +83,7 @@ private:
GUI::CheckboxWidget *_transitionsCheckbox;
GUI::ButtonWidget *_dropPageButton;
GUI::ButtonWidget *_showMapButton;
+ GUI::ButtonWidget *_returnToMenuButton;
};
#endif
diff --git a/engines/mohawk/graphics.cpp b/engines/mohawk/graphics.cpp
index b3653b1fdf..35c9d478d8 100644
--- a/engines/mohawk/graphics.cpp
+++ b/engines/mohawk/graphics.cpp
@@ -672,6 +672,14 @@ void MystGraphics::simulatePreviousDrawDelay(const Common::Rect &dest) {
_nextAllowedDrawTime = time + _constantDrawDelay + dest.height() * dest.width() / _proportionalDrawDelay;
}
+void MystGraphics::fadeToBlack() {
+ // TODO: Implement
+}
+
+void MystGraphics::fadeFromBlack() {
+ // TODO: Implement
+}
+
#endif // ENABLE_MYST
#ifdef ENABLE_RIVEN
@@ -913,7 +921,8 @@ void RivenGraphics::clearMainScreen() {
}
void RivenGraphics::fadeToBlack() {
- // Self-explanatory
+ // The transition speed is forced to best here
+ setTransitionSpeed(kRivenTransitionSpeedBest);
scheduleTransition(16);
clearMainScreen();
runScheduledTransition();
diff --git a/engines/mohawk/graphics.h b/engines/mohawk/graphics.h
index d7057f48cf..96357bbff1 100644
--- a/engines/mohawk/graphics.h
+++ b/engines/mohawk/graphics.h
@@ -129,6 +129,8 @@ public:
void drawRect(Common::Rect rect, RectState state);
void drawLine(const Common::Point &p1, const Common::Point &p2, uint32 color);
void enableDrawingTimeSimulation(bool enable);
+ void fadeToBlack();
+ void fadeFromBlack();
protected:
MohawkSurface *decodeImage(uint16 id);
@@ -194,6 +196,7 @@ public:
void scheduleTransition(uint16 id, Common::Rect rect = Common::Rect(0, 0, 608, 392));
void runScheduledTransition();
void fadeToBlack();
+ void setTransitionSpeed(uint32 speed) { _transitionSpeed = speed; }
// Inventory
void showInventory();
@@ -229,6 +232,7 @@ private:
// Transitions
int16 _scheduledTransition;
Common::Rect _transitionRect;
+ uint32 _transitionSpeed;
// Inventory
void clearInventoryArea();
diff --git a/engines/mohawk/myst.cpp b/engines/mohawk/myst.cpp
index 342fa4e78c..eeb4594f3c 100644
--- a/engines/mohawk/myst.cpp
+++ b/engines/mohawk/myst.cpp
@@ -343,6 +343,7 @@ Common::Error MohawkEngine_Myst::run() {
case Common::KEYCODE_F5:
_needsPageDrop = false;
_needsShowMap = false;
+ _needsShowDemoMenu = false;
runDialog(*_optionsDialog);
@@ -355,6 +356,11 @@ Common::Error MohawkEngine_Myst::run() {
_scriptParser->showMap();
_needsShowMap = false;
}
+
+ if (_needsShowDemoMenu) {
+ changeToStack(kDemoStack, 2002, 0, 0);
+ _needsShowDemoMenu = false;
+ }
break;
default:
break;
diff --git a/engines/mohawk/myst.h b/engines/mohawk/myst.h
index ebcc3b445c..02f0a46e3f 100644
--- a/engines/mohawk/myst.h
+++ b/engines/mohawk/myst.h
@@ -167,6 +167,7 @@ public:
bool _needsUpdate;
bool _needsPageDrop;
bool _needsShowMap;
+ bool _needsShowDemoMenu;
MystView _view;
MystGraphics *_gfx;
diff --git a/engines/mohawk/myst_stacks/demo.cpp b/engines/mohawk/myst_stacks/demo.cpp
index 5788f4b3a3..c9e806655e 100644
--- a/engines/mohawk/myst_stacks/demo.cpp
+++ b/engines/mohawk/myst_stacks/demo.cpp
@@ -20,16 +20,20 @@
*
*/
+#include "mohawk/cursors.h"
+#include "mohawk/graphics.h"
#include "mohawk/myst.h"
#include "mohawk/myst_stacks/demo.h"
-#include "gui/message.h"
+#include "common/system.h"
namespace Mohawk {
namespace MystStacks {
Demo::Demo(MohawkEngine_Myst *vm) : Intro(vm) {
setupOpcodes();
+
+ _returnToMenuStep = 0;
}
Demo::~Demo() {
@@ -47,15 +51,12 @@ Demo::~Demo() {
void Demo::setupOpcodes() {
// "Stack-Specific" Opcodes
- OVERRIDE_OPCODE(100, opcode_100);
- OPCODE(101, opcode_101);
- OPCODE(102, opcode_102);
+ OVERRIDE_OPCODE(100, o_stopIntro);
+ OPCODE(101, o_fadeFromBlack);
+ OPCODE(102, o_fadeToBlack);
// "Init" Opcodes
- OVERRIDE_OPCODE(201, opcode_201);
-
- // "Exit" Opcodes
- OVERRIDE_OPCODE(300, opcode_300);
+ OVERRIDE_OPCODE(201, o_returnToMenu_init);
}
#undef OPCODE
@@ -64,61 +65,66 @@ void Demo::setupOpcodes() {
void Demo::disablePersistentScripts() {
Intro::disablePersistentScripts();
- _enabled201 = false;
+ _returnToMenuRunning = false;
}
void Demo::runPersistentScripts() {
Intro::runPersistentScripts();
- if (_enabled201) {
- // Used on Card 2001, 2002 and 2003
-
- // TODO: Fill in Function...
+ if (_returnToMenuRunning) {
+ returnToMenu_run();
}
}
-void Demo::opcode_100(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
- // TODO: Fill in Function...
+void Demo::o_stopIntro(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+ debugC(kDebugScript, "Opcode %d: Unk", op);
+ // The original also seems to stop the movies. Not needed with this engine.
+ _vm->_gfx->fadeToBlack();
}
-void Demo::opcode_101(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
- varUnusedCheck(op, var);
-
- // Used on Card 2000, 2002 and 2003
- // Triggered by Click
- if (argc == 0) {
- // TODO: Fill in Logic.. Fade in?
- } else
- unknown(op, var, argc, argv);
+void Demo::o_fadeFromBlack(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+ debugC(kDebugScript, "Opcode %d: Fade from black", op);
+ _vm->_gfx->fadeFromBlack();
}
-void Demo::opcode_102(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
- varUnusedCheck(op, var);
-
- // Used on Card 2002 and 2003
- // Triggered by Click
- if (argc == 0) {
- // TODO: Fill in Logic.. Fade out?
- } else
- unknown(op, var, argc, argv);
+void Demo::o_fadeToBlack(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+ debugC(kDebugScript, "Opcode %d: Fade to black", op);
+ _vm->_gfx->fadeToBlack();
}
-void Demo::opcode_201(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
- varUnusedCheck(op, var);
-
- // Used on Card 2001, 2002 and 2003
- if (argc == 0)
- _enabled201 = true;
- else
- unknown(op, var, argc, argv);
+void Demo::returnToMenu_run() {
+ uint32 time = _vm->_system->getMillis();
+
+ if (time < _returnToMenuNextTime)
+ return;
+
+ switch (_returnToMenuStep){
+ case 0:
+ _vm->_gfx->fadeToBlack();
+ _vm->changeToCard(2003, true);
+ _vm->_gfx->fadeFromBlack();
+
+ _returnToMenuStep++;
+ break;
+ case 1:
+ _vm->_gfx->fadeToBlack();
+ _vm->changeToCard(2001, true);
+ _vm->_gfx->fadeFromBlack();
+ _vm->_cursor->showCursor();
+
+ _returnToMenuStep++;
+ break;
+ default:
+ break;
+ }
}
+void Demo::o_returnToMenu_init(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+ debugC(kDebugScript, "Opcode %d: Return to menu init", op);
-void Demo::opcode_300(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
- // Used on Card 2000
- varUnusedCheck(op, var);
-
- // TODO: Fill in Function...
+ // Used on Card 2001, 2002 and 2003
+ _returnToMenuNextTime = _vm->_system->getMillis() + 5000;
+ _returnToMenuRunning = true;
}
} // End of namespace MystStacks
diff --git a/engines/mohawk/myst_stacks/demo.h b/engines/mohawk/myst_stacks/demo.h
index 4f8d68759b..c3e57cf7ae 100644
--- a/engines/mohawk/myst_stacks/demo.h
+++ b/engines/mohawk/myst_stacks/demo.h
@@ -46,15 +46,19 @@ public:
private:
void setupOpcodes();
- DECLARE_OPCODE(opcode_100);
- DECLARE_OPCODE(opcode_101);
- DECLARE_OPCODE(opcode_102);
+ DECLARE_OPCODE(o_stopIntro);
+ DECLARE_OPCODE(o_fadeFromBlack);
+ DECLARE_OPCODE(o_fadeToBlack);
- DECLARE_OPCODE(opcode_201);
+ DECLARE_OPCODE(o_returnToMenu_init);
DECLARE_OPCODE(opcode_300);
- bool _enabled201;
+ bool _returnToMenuRunning;
+ uint16 _returnToMenuStep; // 42
+ uint32 _returnToMenuNextTime; // 6
+
+ void returnToMenu_run();
};
} // End of namespace MystStacks
diff --git a/engines/mohawk/myst_stacks/myst.h b/engines/mohawk/myst_stacks/myst.h
index 9510d371d7..e9bff08cb4 100644
--- a/engines/mohawk/myst_stacks/myst.h
+++ b/engines/mohawk/myst_stacks/myst.h
@@ -40,8 +40,8 @@ public:
Myst(MohawkEngine_Myst *vm);
~Myst();
- void disablePersistentScripts();
- void runPersistentScripts();
+ virtual void disablePersistentScripts();
+ virtual void runPersistentScripts();
private:
void setupOpcodes();
diff --git a/engines/mohawk/myst_stacks/preview.cpp b/engines/mohawk/myst_stacks/preview.cpp
index 07e4fa6e57..1b72c85d96 100644
--- a/engines/mohawk/myst_stacks/preview.cpp
+++ b/engines/mohawk/myst_stacks/preview.cpp
@@ -54,86 +54,187 @@ Preview::~Preview() {
void Preview::setupOpcodes() {
// "Stack-Specific" Opcodes
- OVERRIDE_OPCODE(196, opcode_196);
- OVERRIDE_OPCODE(197, opcode_197);
- OVERRIDE_OPCODE(198, opcode_198);
- OVERRIDE_OPCODE(199, opcode_199);
+ OVERRIDE_OPCODE(196, o_fadeToBlack);
+ OVERRIDE_OPCODE(197, o_fadeFromBlack);
+ OVERRIDE_OPCODE(198, o_stayHere);
+ OVERRIDE_OPCODE(199, o_speechStop);
// "Init" Opcodes
- OPCODE(298, opcode_298);
- OPCODE(299, opcode_299);
+ OPCODE(298, o_speech_init);
+ OPCODE(299, o_library_init);
}
#undef OPCODE
#undef OVERRIDE_OPCODE
-void Preview::opcode_196(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
- varUnusedCheck(op, var);
+void Preview::disablePersistentScripts() {
+ Myst::disablePersistentScripts();
+}
+
+void Preview::runPersistentScripts() {
+ Myst::runPersistentScripts();
- // Used on Card ...
- // TODO: Finish Implementation...
- // Voice Over and Card Advance?
+ if (_speechRunning)
+ speech_run();
}
-void Preview::opcode_197(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
- varUnusedCheck(op, var);
+void Preview::o_fadeToBlack(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+ debugC(kDebugScript, "Opcode %d: Fade to black", op);
+ _vm->_gfx->fadeToBlack();
+}
- // Used on Card ...
- // TODO: Finish Implementation...
- // Voice Over and Card Advance?
+void Preview::o_fadeFromBlack(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+ debugC(kDebugScript, "Opcode %d: Fade from black", op);
+ _vm->_gfx->fadeFromBlack();
}
-// TODO: Merge with Opcode 42?
-void Preview::opcode_198(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
- varUnusedCheck(op, var);
+void Preview::o_stayHere(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+ debugC(kDebugScript, "Opcode %d: Stay here dialog", op);
- if (argc == 0) {
- // Nuh-uh! No leaving the library in the demo!
- GUI::MessageDialog dialog("You can't leave the library in the demo.");
- dialog.runModal();
- } else
- unknown(op, var, argc, argv);
+ // Nuh-uh! No leaving the library in the demo!
+ GUI::MessageDialog dialog("You can't leave the library in the demo.");
+ dialog.runModal();
}
-void Preview::opcode_199(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
- varUnusedCheck(op, var);
+void Preview::o_speechStop(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+ debugC(kDebugScript, "Opcode %d: Speech stop", op);
- // Used on Card ...
- // TODO: Finish Implementation...
- // Voice Over and Card Advance?
+ _speechRunning = false;
+ _globals.currentAge = 2;
}
-void Preview::opcode_298(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
- varUnusedCheck(op, var);
+void Preview::speechUpdateCue() {
+ // This is a callback in the original, handling audio events.
+ if (!_vm->_sound->isPlaying(3001)) {
+ return;
+ }
- // Used for Card 3000 (Closed Myst Book)
- // TODO: Fill in logic.
- // Start Voice Over... which controls book opening
- _vm->_sound->replaceSoundMyst(3001);
-
- // then link to Myst - Trigger of Hotspot? then opcode 199/196/197 for voice over continue?
- // TODO: Sync Voice and Actions to Original
- // TODO: Flash Library Red
- // TODO: Move to run process based delay to prevent
- // blocking...
- _vm->_system->updateScreen();
- _vm->_system->delayMillis(20 * 1000);
-
- for (uint16 imageId = 3001; imageId <= 3012; imageId++) {
- _vm->_gfx->copyImageToScreen(imageId, Common::Rect(0, 0, 544, 333));
- _vm->_system->updateScreen();
- _vm->_system->delayMillis(5 * 1000);
+ uint samples = _vm->_sound->getNumSamplesPlayed(3001);
+ for (int16 i = 0; i < _cueList.pointCount; i++) {
+ if (_cueList.points[i].sampleFrame > samples)
+ return;
+ if (i > _currentCue - 1) {
+ _currentCue++;
+ debugC(kDebugScript, "Sneak speech advanced to cue %d", _currentCue);
+ }
}
}
-void Preview::opcode_299(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
- varUnusedCheck(op, var);
+void Preview::speech_run() {
+ uint32 time = _vm->_system->getMillis();
+
+ // Update current speech sound cue
+ speechUpdateCue();
+
+ switch (_speechStep) {
+ case 0: // Start Voice Over... which controls book opening
+ _currentCue = 0;
+ _vm->_sound->playSound(3001, Audio::Mixer::kMaxChannelVolume, false, &_cueList);
+
+ _speechStep++;
+ break;
+ case 1: // Open book
+ if (_currentCue >= 1) {
+ _vm->changeToCard(3001, true);
+
+ _speechStep++;
+ }
+ break;
+ case 2: // Go to Myst
+ if (_currentCue >= 2) {
+ _vm->_gfx->fadeToBlack();
+ _vm->changeToCard(3002, true);
+ _vm->_gfx->fadeFromBlack();
+
+ _speechStep++;
+ }
+ break;
+ case 3: // Start blinking the library
+ if (_currentCue >= 3) {
+ _libraryState = 1;
+ _speechNextTime = 0;
+ _speechStep++;
+ }
+ break;
+ case 4: // Library blinking, zoom in library
+ if (_currentCue >= 4) {
+ _library->drawConditionalDataToScreen(0);
+
+ _vm->changeToCard(3003, true);
+
+ _speechNextTime = time + 2000;
+ _speechStep++;
+ } else {
+ if (time < _speechNextTime)
+ break;
+
+ _library->drawConditionalDataToScreen(_libraryState);
+ _libraryState = (_libraryState + 1) % 2;
+ _speechNextTime = time + 500;
+ }
+ break;
+ case 5: // Go to library near view
+ if (time < _speechNextTime)
+ break;
+
+ _vm->changeToCard(3004, true);
+ _speechNextTime = time + 2000;
+ _speechStep++;
+ break;
+ case 6: // Fade to courtyard
+ if (time < _speechNextTime)
+ break;
+
+ _vm->_gfx->fadeToBlack();
+ _vm->changeToCard(3005, true);
+ _vm->_gfx->fadeFromBlack();
+ _speechNextTime = time + 1000;
+ _speechStep++;
+ break;
+ case 7: // Walk to library
+ case 8:
+ case 9:
+ case 10:
+ case 11:
+ case 12:
+ case 13:
+ if (time < _speechNextTime)
+ break;
+
+ _vm->changeToCard(3006 + _speechStep - 7, true);
+ _speechNextTime = time + 2000;
+ _speechStep++;
+ break;
+ case 14: // Go to playable library card
+ if (time < _speechNextTime)
+ break;
+
+ _vm->changeToCard(4329, true);
+
+ _speechRunning = false;
+ _globals.currentAge = 2;
+
+ _vm->_cursor->showCursor();
+ break;
+ default:
+ warning("Unknown speech step");
+ break;
+ }
+}
+
+void Preview::o_speech_init(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+ debugC(kDebugScript, "Opcode %d: Speech init", op);
+
+ // Used for Card 3000 (Closed Myst Book)
+ _speechStep = 0;
+ _speechRunning = true;
+}
+
+void Preview::o_library_init(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+ debugC(kDebugScript, "Opcode %d: Library init", op);
// Used for Card 3002 (Myst Island Overview)
- // TODO: Fill in logic.
- // Zoom into Island?
- // On this card is a Type 8 controlled by Var 0, which
- // can change the Myst Library to Red..
+ _library = static_cast<MystResourceType8 *>(_invokingResource);
}
} // End of namespace MystStacks
diff --git a/engines/mohawk/myst_stacks/preview.h b/engines/mohawk/myst_stacks/preview.h
index 7e4e418eef..1e4ff3efb4 100644
--- a/engines/mohawk/myst_stacks/preview.h
+++ b/engines/mohawk/myst_stacks/preview.h
@@ -40,16 +40,31 @@ public:
Preview(MohawkEngine_Myst *vm);
~Preview();
+ void disablePersistentScripts();
+ void runPersistentScripts();
+
private:
void setupOpcodes();
- DECLARE_OPCODE(opcode_196);
- DECLARE_OPCODE(opcode_197);
- DECLARE_OPCODE(opcode_198);
- DECLARE_OPCODE(opcode_199);
+ DECLARE_OPCODE(o_fadeToBlack);
+ DECLARE_OPCODE(o_fadeFromBlack);
+ DECLARE_OPCODE(o_stayHere);
+ DECLARE_OPCODE(o_speechStop);
+
+ DECLARE_OPCODE(o_speech_init);
+ DECLARE_OPCODE(o_library_init);
+
+ uint16 _libraryState; // 4
+ MystResourceType8 *_library; // 32
+
+ bool _speechRunning;
+ uint _speechStep;
+ CueList _cueList;
+ int16 _currentCue;
+ uint32 _speechNextTime; // 6
- DECLARE_OPCODE(opcode_298);
- DECLARE_OPCODE(opcode_299);
+ void speech_run();
+ void speechUpdateCue();
};
} // End of namespace MystStacks
diff --git a/engines/mohawk/myst_stacks/slides.cpp b/engines/mohawk/myst_stacks/slides.cpp
index e9bb91c84d..943cb90071 100644
--- a/engines/mohawk/myst_stacks/slides.cpp
+++ b/engines/mohawk/myst_stacks/slides.cpp
@@ -61,18 +61,26 @@ void Slides::disablePersistentScripts() {
void Slides::runPersistentScripts() {
if (_cardSwapEnabled) {
// Used on Cards...
- if (_vm->_system->getMillis() > _nextCardTime)
+ if (_vm->_system->getMillis() > _nextCardTime) {
+ _vm->_gfx->fadeToBlack();
_vm->changeToCard(_nextCardID, true);
+ _vm->_gfx->fadeFromBlack();
+ }
}
}
void Slides::o_returnToMenu(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+ debugC(kDebugScript, "Opcode %d: Return to menu", op);
+
// Go to the information screens of the menu
_vm->changeToStack(kDemoStack, 2002, 0, 0);
}
void Slides::o_setCardSwap(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
_nextCardID = argv[0];
+
+ debugC(kDebugScript, "Opcode %d: Set next card %d", op, _nextCardID);
+
_nextCardTime = _vm->_system->getMillis() + 5000;
_cardSwapEnabled = true;
}
diff --git a/engines/mohawk/riven.cpp b/engines/mohawk/riven.cpp
index 612b8b3685..3e2fa4f979 100644
--- a/engines/mohawk/riven.cpp
+++ b/engines/mohawk/riven.cpp
@@ -150,6 +150,9 @@ Common::Error MohawkEngine_Riven::run() {
return Common::kNoGameDataFoundError;
}
+ // Set the transition speed
+ _gfx->setTransitionSpeed(_vars["transitionmode"]);
+
// Start at main cursor
_cursor->setCursor(kRivenMainCursor);
_cursor->showCursor();
@@ -209,8 +212,10 @@ void MohawkEngine_Riven::handleEvents() {
needsUpdate = true;
break;
case Common::EVENT_LBUTTONDOWN:
- if (_curHotspot >= 0)
+ if (_curHotspot >= 0) {
+ checkSunnerAlertClick();
runHotspotScript(_curHotspot, kMouseDownScript);
+ }
break;
case Common::EVENT_LBUTTONUP:
// See RivenScript::switchCard() for more information on why we sometimes
@@ -812,6 +817,138 @@ static void catherineIdleTimer(MohawkEngine_Riven *vm) {
vm->installTimer(&catherineIdleTimer, timeUntilNextMovie);
}
+static void sunnersTopStairsTimer(MohawkEngine_Riven *vm) {
+ // If the sunners are gone, we have no video to play
+ if (vm->_vars["jsunners"] != 0) {
+ vm->removeTimer();
+ return;
+ }
+
+ // Play a random sunners video if the script one is not playing already
+ // and then set a new timer for when the new video should be played
+
+ VideoHandle oldHandle = vm->_video->findVideoHandleRiven(1);
+ uint32 timerTime = 500;
+
+ if (oldHandle == NULL_VID_HANDLE || vm->_video->endOfVideo(oldHandle)) {
+ uint32 &sunnerTime = vm->_vars["jsunnertime"];
+
+ if (sunnerTime == 0) {
+ timerTime = vm->_rnd->getRandomNumberRng(2, 15) * 1000;
+ } else if (sunnerTime < vm->getTotalPlayTime()) {
+ VideoHandle handle = vm->_video->playMovieRiven(vm->_rnd->getRandomNumberRng(1, 3));
+
+ timerTime = vm->_video->getDuration(handle) + vm->_rnd->getRandomNumberRng(2, 15) * 1000;
+ }
+
+ sunnerTime = timerTime + vm->getTotalPlayTime();
+ }
+
+ vm->installTimer(&sunnersTopStairsTimer, timerTime);
+}
+
+static void sunnersMidStairsTimer(MohawkEngine_Riven *vm) {
+ // If the sunners are gone, we have no video to play
+ if (vm->_vars["jsunners"] != 0) {
+ vm->removeTimer();
+ return;
+ }
+
+ // Play a random sunners video if the script one is not playing already
+ // and then set a new timer for when the new video should be played
+
+ VideoHandle oldHandle = vm->_video->findVideoHandleRiven(1);
+ uint32 timerTime = 500;
+
+ if (oldHandle == NULL_VID_HANDLE || vm->_video->endOfVideo(oldHandle)) {
+ uint32 &sunnerTime = vm->_vars["jsunnertime"];
+
+ if (sunnerTime == 0) {
+ timerTime = vm->_rnd->getRandomNumberRng(1, 10) * 1000;
+ } else if (sunnerTime < vm->getTotalPlayTime()) {
+ // Randomize the video
+ int randValue = vm->_rnd->getRandomNumber(5);
+ uint16 movie = 4;
+ if (randValue == 4)
+ movie = 2;
+ else if (randValue == 5)
+ movie = 3;
+
+ VideoHandle handle = vm->_video->playMovieRiven(movie);
+
+ timerTime = vm->_video->getDuration(handle) + vm->_rnd->getRandomNumberRng(1, 10) * 1000;
+ }
+
+ sunnerTime = timerTime + vm->getTotalPlayTime();
+ }
+
+ vm->installTimer(&sunnersMidStairsTimer, timerTime);
+}
+
+static void sunnersLowerStairsTimer(MohawkEngine_Riven *vm) {
+ // If the sunners are gone, we have no video to play
+ if (vm->_vars["jsunners"] != 0) {
+ vm->removeTimer();
+ return;
+ }
+
+ // Play a random sunners video if the script one is not playing already
+ // and then set a new timer for when the new video should be played
+
+ VideoHandle oldHandle = vm->_video->findVideoHandleRiven(1);
+ uint32 timerTime = 500;
+
+ if (oldHandle == NULL_VID_HANDLE || vm->_video->endOfVideo(oldHandle)) {
+ uint32 &sunnerTime = vm->_vars["jsunnertime"];
+
+ if (sunnerTime == 0) {
+ timerTime = vm->_rnd->getRandomNumberRng(1, 30) * 1000;
+ } else if (sunnerTime < vm->getTotalPlayTime()) {
+ VideoHandle handle = vm->_video->playMovieRiven(vm->_rnd->getRandomNumberRng(3, 5));
+
+ timerTime = vm->_video->getDuration(handle) + vm->_rnd->getRandomNumberRng(1, 30) * 1000;
+ }
+
+ sunnerTime = timerTime + vm->getTotalPlayTime();
+ }
+
+ vm->installTimer(&sunnersLowerStairsTimer, timerTime);
+}
+
+static void sunnersBeachTimer(MohawkEngine_Riven *vm) {
+ // If the sunners are gone, we have no video to play
+ if (vm->_vars["jsunners"] != 0) {
+ vm->removeTimer();
+ return;
+ }
+
+ // Play a random sunners video if the script one is not playing already
+ // and then set a new timer for when the new video should be played
+
+ VideoHandle oldHandle = vm->_video->findVideoHandleRiven(3);
+ uint32 timerTime = 500;
+
+ if (oldHandle == NULL_VID_HANDLE || vm->_video->endOfVideo(oldHandle)) {
+ uint32 &sunnerTime = vm->_vars["jsunnertime"];
+
+ if (sunnerTime == 0) {
+ timerTime = vm->_rnd->getRandomNumberRng(1, 30) * 1000;
+ } else if (sunnerTime < vm->getTotalPlayTime()) {
+ // Unlike the other cards' scripts which automatically
+ // activate the MLST, we have to set it manually here.
+ uint16 mlstID = vm->_rnd->getRandomNumberRng(3, 8);
+ vm->_video->activateMLST(mlstID, vm->getCurCard());
+ VideoHandle handle = vm->_video->playMovieRiven(mlstID);
+
+ timerTime = vm->_video->getDuration(handle) + vm->_rnd->getRandomNumberRng(1, 30) * 1000;
+ }
+
+ sunnerTime = timerTime + vm->getTotalPlayTime();
+ }
+
+ vm->installTimer(&sunnersBeachTimer, timerTime);
+}
+
void MohawkEngine_Riven::installCardTimer() {
switch (getCurCardRMAP()) {
case 0x3a85: // Top of elevator on prison island
@@ -819,16 +956,16 @@ void MohawkEngine_Riven::installCardTimer() {
installTimer(&catherineIdleTimer, _rnd->getRandomNumberRng(1, 33) * 1000);
break;
case 0x77d6: // Sunners, top of stairs
- // TODO: Background Sunner videos
+ installTimer(&sunnersTopStairsTimer, 500);
break;
case 0x79bd: // Sunners, middle of stairs
- // TODO: Background Sunner videos
+ installTimer(&sunnersMidStairsTimer, 500);
break;
case 0x7beb: // Sunners, bottom of stairs
- // TODO: Background Sunner videos
+ installTimer(&sunnersLowerStairsTimer, 500);
break;
case 0xb6ca: // Sunners, shoreline
- // TODO: Background Sunner videos
+ installTimer(&sunnersBeachTimer, 500);
break;
}
}
@@ -846,6 +983,34 @@ void MohawkEngine_Riven::doVideoTimer(VideoHandle handle, bool force) {
_scriptMan->runStoredMovieOpcode();
}
+void MohawkEngine_Riven::checkSunnerAlertClick() {
+ // We need to do a manual hardcoded check for the sunners'
+ // alert movies.
+
+ uint32 &sunners = _vars["jsunners"];
+
+ // If the sunners are gone, there's nothing for us to do
+ if (sunners != 0)
+ return;
+
+ uint32 rmapCode = getCurCardRMAP();
+
+ // This is only for the mid/lower staircase sections
+ if (rmapCode != 0x79bd && rmapCode != 0x7beb)
+ return;
+
+ // Only set the sunners variable on the forward hotspot
+ if ((rmapCode == 0x79bd && _curHotspot != 1) || (rmapCode == 0x7beb && _curHotspot != 2))
+ return;
+
+ // If the alert video is no longer playing, we have nothing left to do
+ VideoHandle handle = _video->findVideoHandleRiven(1);
+ if (handle == NULL_VID_HANDLE || _video->endOfVideo(handle))
+ return;
+
+ sunners = 1;
+}
+
bool ZipMode::operator== (const ZipMode &z) const {
return z.name == name && z.id == id;
}
diff --git a/engines/mohawk/riven.h b/engines/mohawk/riven.h
index c7d36e585d..e99a9f78fc 100644
--- a/engines/mohawk/riven.h
+++ b/engines/mohawk/riven.h
@@ -67,6 +67,13 @@ enum {
StackNames = 5
};
+enum RivenTransitionSpeed {
+ kRivenTransitionSpeedNone = 5000,
+ kRivenTransitionSpeedFastest = 5001,
+ kRivenTransitionSpeedNormal = 5002,
+ kRivenTransitionSpeedBest = 5003
+};
+
// Rects for the inventory object positions (initialized in
// MohawkEngine_Riven's constructor).
extern Common::Rect *g_atrusJournalRect1;
@@ -164,6 +171,7 @@ private:
// Miscellaneous
bool _gameOver;
bool _ignoreNextMouseUp;
+ void checkSunnerAlertClick();
public:
// Stack/card/script funtions
diff --git a/engines/mohawk/riven_external.cpp b/engines/mohawk/riven_external.cpp
index 60e94ea795..9e1365f8da 100644
--- a/engines/mohawk/riven_external.cpp
+++ b/engines/mohawk/riven_external.cpp
@@ -234,10 +234,10 @@ void RivenExternal::runCredits(uint16 video, uint32 delay) {
// Set us up to start after delay ms
nextCreditsFrameStart = _vm->_system->getMillis() + delay;
} else if (_vm->_system->getMillis() >= nextCreditsFrameStart) {
- // the first two frames stay on for 5 seconds
+ // the first two frames stay on for 4 seconds
// the rest of the scroll updates happen at 30Hz
if (_vm->_gfx->getCurCreditsImage() < 304)
- nextCreditsFrameStart = _vm->_system->getMillis() + 5000;
+ nextCreditsFrameStart = _vm->_system->getMillis() + 4000;
else
nextCreditsFrameStart = _vm->_system->getMillis() + 1000 / 30;
@@ -1889,21 +1889,42 @@ void RivenExternal::xjplaybeetle_1450(uint16 argc, uint16 *argv) {
}
void RivenExternal::xjlagoon700_alert(uint16 argc, uint16 *argv) {
- // TODO: Sunner related
+ // Handle sunner reactions (mid-staircase)
+
+ if (_vm->_vars["jsunners"] == 0)
+ _vm->_video->playMovieRiven(1);
}
void RivenExternal::xjlagoon800_alert(uint16 argc, uint16 *argv) {
- // TODO: Sunner related
+ // Handle sunner reactions (lower-staircase)
+
+ uint32 &sunners = _vm->_vars["jsunners"];
+
+ if (sunners == 0) {
+ // Show the sunners alert video
+ _vm->_video->playMovieRiven(1);
+ } else if (sunners == 1) {
+ // Show the sunners leaving if you moved forward in their "alert" status
+ _vm->_video->playMovieBlockingRiven(2);
+ _vm->_video->playMovieBlockingRiven(6);
+ sunners = 2;
+ _vm->refreshCard();
+ }
}
void RivenExternal::xjlagoon1500_alert(uint16 argc, uint16 *argv) {
- // Have the sunners move a bit as you get closer ;)
+ // Handle sunner reactions (beach)
+
uint32 &sunners = _vm->_vars["jsunners"];
+
if (sunners == 0) {
+ // Show the sunners alert video
_vm->_video->playMovieBlockingRiven(3);
} else if (sunners == 1) {
+ // Show the sunners leaving if you moved forward in their "alert" status
_vm->_video->playMovieBlockingRiven(2);
sunners = 2;
+ _vm->refreshCard();
}
}
@@ -2726,6 +2747,7 @@ void RivenExternal::xtatboundary(uint16 argc, uint16 *argv) {
void RivenExternal::xflies(uint16 argc, uint16 *argv) {
// TODO: Activate the "flies" effect
+ debug(1, "STUB: xflies(): create %d %s fl%s", argv[1], (argv[0] == 0) ? "black" : "glowing", (argv[1] == 1) ? "y" : "ies");
}
} // End of namespace Mohawk
diff --git a/engines/mohawk/riven_vars.cpp b/engines/mohawk/riven_vars.cpp
index 946e2e0496..ba5c343e07 100644
--- a/engines/mohawk/riven_vars.cpp
+++ b/engines/mohawk/riven_vars.cpp
@@ -268,7 +268,12 @@ static const char *variableNames[] = {
};
uint32 &MohawkEngine_Riven::getStackVar(uint32 index) {
- return _vars[getName(VariableNames, index)];
+ Common::String name = getName(VariableNames, index);
+
+ if (!_vars.contains(name))
+ error("Could not find variable '%s' (stack variable %d)", name.c_str(), index);
+
+ return _vars[name];
}
void MohawkEngine_Riven::initVars() {
@@ -299,6 +304,7 @@ void MohawkEngine_Riven::initVars() {
_vars["bmagcar"] = 1;
_vars["gnmagcar"] = 1;
_vars["omusicplayer"] = 1;
+ _vars["transitionmode"] = kRivenTransitionSpeedFastest;
// Randomize the telescope combination
uint32 &teleCombo = _vars["tcorrectorder"];
diff --git a/engines/mohawk/sound.cpp b/engines/mohawk/sound.cpp
index 68b60515be..f92bebf10e 100644
--- a/engines/mohawk/sound.cpp
+++ b/engines/mohawk/sound.cpp
@@ -85,7 +85,7 @@ Audio::AudioStream *Sound::makeAudioStream(uint16 id, CueList *cueList) {
if (_vm->getFeatures() & GF_ME)
audStream = Audio::makeWAVStream(_vm->getResource(ID_MSND, convertMystID(id)), DisposeAfterUse::YES);
else
- audStream = makeMohawkWaveStream(_vm->getResource(ID_MSND, id));
+ audStream = makeMohawkWaveStream(_vm->getResource(ID_MSND, id), cueList);
break;
case GType_ZOOMBINI:
audStream = makeMohawkWaveStream(_vm->getResource(ID_SND, id));
diff --git a/engines/saga/detection_tables.h b/engines/saga/detection_tables.h
index a29d835a54..3e83c30eef 100644
--- a/engines/saga/detection_tables.h
+++ b/engines/saga/detection_tables.h
@@ -328,7 +328,7 @@ static const SAGAGameDescription gameDescriptions[] = {
},
Common::EN_ANY,
Common::kPlatformMacintosh,
- ADGF_NO_FLAGS,
+ ADGF_CD,
GUIO_NONE
},
GID_ITE,
@@ -352,7 +352,7 @@ static const SAGAGameDescription gameDescriptions[] = {
},
Common::EN_ANY,
Common::kPlatformMacintosh,
- ADGF_NO_FLAGS,
+ ADGF_CD,
GUIO_NONE
},
GID_ITE,
@@ -384,7 +384,7 @@ static const SAGAGameDescription gameDescriptions[] = {
},
Common::EN_ANY,
Common::kPlatformUnknown,
- ADGF_NO_FLAGS,
+ ADGF_CD,
GUIO_NONE
},
GID_ITE,
@@ -414,7 +414,7 @@ static const SAGAGameDescription gameDescriptions[] = {
},
Common::IT_ITA,
Common::kPlatformUnknown,
- ADGF_NO_FLAGS,
+ ADGF_CD,
GUIO_NONE
},
GID_ITE,
@@ -438,7 +438,7 @@ static const SAGAGameDescription gameDescriptions[] = {
},
Common::EN_ANY,
Common::kPlatformPC,
- ADGF_NO_FLAGS,
+ ADGF_CD,
GUIO_NONE
},
GID_ITE,
@@ -462,7 +462,7 @@ static const SAGAGameDescription gameDescriptions[] = {
},
Common::IT_ITA,
Common::kPlatformPC,
- ADGF_NO_FLAGS,
+ ADGF_CD,
GUIO_NONE
},
GID_ITE,
@@ -486,7 +486,7 @@ static const SAGAGameDescription gameDescriptions[] = {
},
Common::EN_ANY,
Common::kPlatformPC,
- ADGF_NO_FLAGS,
+ ADGF_CD,
GUIO_NONE
},
GID_ITE,
@@ -511,7 +511,7 @@ static const SAGAGameDescription gameDescriptions[] = {
},
Common::DE_DEU,
Common::kPlatformPC,
- ADGF_NO_FLAGS,
+ ADGF_CD,
GUIO_NONE
},
GID_ITE,
diff --git a/engines/scumm/cursor.cpp b/engines/scumm/cursor.cpp
index a8adb4d5c5..29b5eaedcb 100644
--- a/engines/scumm/cursor.cpp
+++ b/engines/scumm/cursor.cpp
@@ -22,6 +22,9 @@
#include "common/system.h"
#include "common/util.h"
#include "graphics/cursorman.h"
+#ifdef ENABLE_HE
+#include "graphics/wincursor.h"
+#endif
#include "scumm/bomp.h"
#include "scumm/charset.h"
#include "scumm/he/intern_he.h"
@@ -177,12 +180,8 @@ void ScummEngine_v70he::setDefaultCursor() {
0xff, 0xff, 0xff,
0, 0, 0, };
- if (_bytesPerPixel == 2) {
- for (i = 0; i < 1024; i++)
- WRITE_UINT16(_grabbedCursor + i * 2, 5);
- } else {
- memset(_grabbedCursor, 5, sizeof(_grabbedCursor));
- }
+
+ memset(_grabbedCursor, 5, sizeof(_grabbedCursor));
_cursor.hotspotX = _cursor.hotspotY = 2;
src = default_he_cursor;
@@ -195,16 +194,10 @@ void ScummEngine_v70he::setDefaultCursor() {
for (j = 0; j < 32; j++) {
switch ((p & (0x3 << 14)) >> 14) {
case 1:
- if (_bytesPerPixel == 2)
- WRITE_UINT16(_grabbedCursor + 64 * i + j * 2, get16BitColor(palette[4], palette[5], palette[6]));
- else
- _grabbedCursor[32 * i + j] = 0xfe;
+ _grabbedCursor[32 * i + j] = 0xfe;
break;
case 2:
- if (_bytesPerPixel == 2)
- WRITE_UINT16(_grabbedCursor + 64 * i + j * 2, get16BitColor(palette[0], palette[1], palette[2]));
- else
- _grabbedCursor[32 * i + j] = 0xfd;
+ _grabbedCursor[32 * i + j] = 0xfd;
break;
default:
break;
@@ -216,15 +209,61 @@ void ScummEngine_v70he::setDefaultCursor() {
}
}
- if (_bytesPerPixel == 1) {
- // Since white color position is not guaranteed
- // we setup our own palette if supported by backend
- CursorMan.disableCursorPalette(false);
- CursorMan.replaceCursorPalette(palette, 0xfd, 3);
+ // Since white color position is not guaranteed
+ // we setup our own palette if supported by backend
+ CursorMan.disableCursorPalette(false);
+ CursorMan.replaceCursorPalette(palette, 0xfd, 3);
+
+ updateCursor();
+}
+
+#ifdef ENABLE_HE
+void ScummEngine_v80he::setDefaultCursor() {
+ // v80+ games use the default Windows cursor instead of the usual
+ // default HE cursor.
+ Graphics::Cursor *cursor = Graphics::makeDefaultWinCursor();
+
+ // Clear the cursor
+ if (_bytesPerPixel == 2) {
+ for (int i = 0; i < 1024; i++)
+ WRITE_UINT16(_grabbedCursor + i * 2, 5);
+ } else {
+ memset(_grabbedCursor, 5, sizeof(_grabbedCursor));
}
+ _cursor.width = cursor->getWidth();
+ _cursor.height = cursor->getHeight();
+ _cursor.hotspotX = cursor->getHotspotX();
+ _cursor.hotspotY = cursor->getHotspotY();
+
+ const byte *surface = cursor->getSurface();
+ const byte *palette = cursor->getPalette();
+
+ for (uint16 y = 0; y < _cursor.height; y++) {
+ for (uint16 x = 0; x < _cursor.width; x++) {
+ byte pixel = *surface++;
+
+ if (pixel != cursor->getKeyColor()) {
+ pixel -= cursor->getPaletteStartIndex();
+
+ if (_bytesPerPixel == 2)
+ WRITE_UINT16(_grabbedCursor + (y * _cursor.width + x) * 2, get16BitColor(palette[pixel * 3], palette[pixel * 3 + 1], palette[pixel * 3 + 2]));
+ else
+ _grabbedCursor[y * _cursor.width + x] = (pixel == 0) ? 0xfd : 0xfe;
+ }
+ }
+ }
+
+ delete cursor;
+
+ // Since white color position is not guaranteed
+ // we setup our own palette if supported by backend
+ CursorMan.disableCursorPalette(false);
+ CursorMan.replaceCursorPalette(palette, 0xfd, cursor->getPaletteCount() * 3);
+
updateCursor();
}
+#endif
void ScummEngine_v6::setCursorFromImg(uint img, uint room, uint imgindex) {
int w, h;
diff --git a/engines/scumm/he/intern_he.h b/engines/scumm/he/intern_he.h
index c49217b650..f4df6571fa 100644
--- a/engines/scumm/he/intern_he.h
+++ b/engines/scumm/he/intern_he.h
@@ -383,6 +383,8 @@ protected:
void drawLine(int x1, int y1, int x, int unk1, int unk2, int type, int id);
void drawPixel(int x, int y, int flags);
+ virtual void setDefaultCursor();
+
/* HE version 80 script opcodes */
void o80_createSound();
void o80_getFileSize();
diff --git a/engines/scumm/he/logic/basketball.cpp b/engines/scumm/he/logic/basketball.cpp
index 0a2f99aa90..8352aa4357 100644
--- a/engines/scumm/he/logic/basketball.cpp
+++ b/engines/scumm/he/logic/basketball.cpp
@@ -35,6 +35,28 @@ public:
int versionID();
int32 dispatch(int op, int numArgs, int32 *args);
+
+private:
+ int op_1012();
+ int op_1050(int32 *args);
+ int op_1053();
+
+ // op_1050 loads court object data
+ enum CourtObjectType {
+ kObjectTypeBackboard = 1,
+ kObjectTypeRim = 2,
+ kObjectTypeOther = 3,
+ kObjectTypeFloor = 4
+ };
+
+ struct CourtObject {
+ Common::String name;
+ CourtObjectType type;
+ uint32 data[10];
+ };
+
+ Common::Array<CourtObject> _courtObjects;
+ uint32 _backboardObjectLeft, _backboardObjectRight;
};
int LogicHEbasketball::versionID() {
@@ -55,12 +77,14 @@ int32 LogicHEbasketball::dispatch(int op, int numArgs, int32 *args) {
break;
case 1012:
+ res = op_1012();
break;
case 1035:
break;
case 1050:
+ res = op_1050(args);
break;
case 1051:
@@ -69,6 +93,10 @@ int32 LogicHEbasketball::dispatch(int op, int numArgs, int32 *args) {
case 1052:
break;
+ case 1053:
+ res = op_1053();
+ break;
+
case 1056:
break;
@@ -118,6 +146,83 @@ int32 LogicHEbasketball::dispatch(int op, int numArgs, int32 *args) {
return res;
}
+int LogicHEbasketball::op_1012() {
+ writeScummVar(108, 12000);
+ writeScummVar(109, 8000);
+ writeScummVar(110, 760);
+ writeScummVar(111, 4000);
+ writeScummVar(112, 1600);
+ return 1;
+}
+
+int LogicHEbasketball::op_1050(int32 *args) {
+ // This function loads the court data
+ static const char *courtNames[] = {
+ "Dobbaguchi", "Jocindas", "SandyFlats", "Queens",
+ "Park", "Scheffler", "Polk", "McMillan",
+ "CrownHill", "Memorial", "TechState", "Garden",
+ "Moon", "Barn"
+ };
+
+ Common::String courtFileName = Common::String::format("data/courts/%s.cof", courtNames[args[0] - 1]);
+
+ Common::File file;
+ if (!file.open(courtFileName))
+ error("Could not open file '%s'", courtFileName.c_str());
+
+ debug(0, "Loading court data from '%s'", courtFileName.c_str());
+
+ // First, read in the header
+ file.readUint32LE(); // Header size (?)
+
+ char version[6];
+ file.read(version, 5);
+ version[5] = 0;
+
+ if (strcmp(version, "01.05"))
+ error("Invalid court version field: %s", version);
+
+ uint32 objectCount = file.readUint32LE();
+
+ for (uint32 i = 0; i < objectCount; i++) {
+ char nameBuf[100];
+ memset(nameBuf, 0, sizeof(nameBuf));
+
+ uint32 nameLength = file.readUint32LE();
+ assert(nameLength < sizeof(nameBuf) - 1);
+ file.read(nameBuf, nameLength);
+
+ CourtObject object;
+ object.name = nameBuf;
+ object.type = (CourtObjectType)file.readUint32LE();
+ for (uint32 j = 0; j < 10; j++)
+ object.data[j] = file.readUint32LE();
+
+ debug(1, "Found court object '%s' - Type %d", nameBuf, object.type);
+
+ // Store backboard object indices for later
+ if (object.type == kObjectTypeBackboard) {
+ if (object.data[7] + object.data[4] / 2 >= 6000)
+ _backboardObjectRight = i;
+ else
+ _backboardObjectLeft = i;
+ }
+
+ _courtObjects.push_back(object);
+ }
+
+ // TODO: Some other variables are initialized with constants here
+
+ return 1;
+}
+
+int LogicHEbasketball::op_1053() {
+ _courtObjects.clear();
+ // TODO: This also calls op_1065 with one argument (5)
+
+ return 1;
+}
+
LogicHE *makeLogicHEbasketball(ScummEngine_v90he *vm) {
return new LogicHEbasketball(vm);
}
diff --git a/engines/scumm/player_v2cms.cpp b/engines/scumm/player_v2cms.cpp
index d16f9d2be7..d4b21774ed 100644
--- a/engines/scumm/player_v2cms.cpp
+++ b/engines/scumm/player_v2cms.cpp
@@ -36,6 +36,10 @@ Player_V2CMS::Player_V2CMS(ScummEngine *scumm, Audio::Mixer *mixer)
_outputTableReady(0), _midiChannel(), _midiChannelUse() {
setMusicVolume(255);
+ memset(_sfxFreq, 0xFF, sizeof(_sfxFreq));
+ memset(_sfxAmpl, 0x00, sizeof(_sfxAmpl));
+ memset(_sfxOctave, 0x66, sizeof(_sfxOctave));
+
_cmsVoices[0].amplitudeOutput = &_cmsChips[0].ampl[0];
_cmsVoices[0].freqOutput = &_cmsChips[0].freq[0];
_cmsVoices[0].octaveOutput = &_cmsChips[0].octave[0];
@@ -596,7 +600,6 @@ void Player_V2CMS::play() {
_octaveMask = 0xF0;
channel_data *chan = &_channels[0].d;
- MusicChip &cms = _cmsChips[0];
byte noiseGen = 3;
for (int i = 1; i <= 4; ++i) {
@@ -608,8 +611,8 @@ void Player_V2CMS::play() {
noiseGen = freq & 0xFF;
} else {
noiseGen = 3;
- cms.freq[0] = cms.freq[3];
- cms.octave[0] = (cms.octave[0] & 0xF0) | ((cms.octave[1] & 0xF0) >> 4);
+ _sfxFreq[0] = _sfxFreq[3];
+ _sfxOctave[0] = (_sfxOctave[0] & 0xF0) | ((_sfxOctave[1] & 0xF0) >> 4);
}
} else {
if (freq == 0) {
@@ -635,15 +638,15 @@ void Player_V2CMS::play() {
oct |= cmsOct;
oct &= _octaveMask;
- oct |= (~_octaveMask) & cms.octave[(i & 3) >> 1];
- cms.octave[(i & 3) >> 1] = oct;
+ oct |= (~_octaveMask) & _sfxOctave[(i & 3) >> 1];
+ _sfxOctave[(i & 3) >> 1] = oct;
freq >>= -(cmsOct - 9);
- cms.freq[i & 3] = (-(freq - 511)) & 0xFF;
+ _sfxFreq[i & 3] = (-(freq - 511)) & 0xFF;
}
- cms.ampl[i & 3] = _volumeTable[chan->volume >> 12];
+ _sfxAmpl[i & 3] = _volumeTable[chan->volume >> 12];
} else {
- cms.ampl[i & 3] = 0;
+ _sfxAmpl[i & 3] = 0;
}
chan = &_channels[i].d;
@@ -654,25 +657,25 @@ void Player_V2CMS::play() {
// the right channels amplitude is set
// with the low value the left channels amplitude
_cmsEmu->portWrite(0x221, 0);
- _cmsEmu->portWrite(0x220, cms.ampl[0]);
+ _cmsEmu->portWrite(0x220, _sfxAmpl[0]);
_cmsEmu->portWrite(0x221, 1);
- _cmsEmu->portWrite(0x220, cms.ampl[1]);
+ _cmsEmu->portWrite(0x220, _sfxAmpl[1]);
_cmsEmu->portWrite(0x221, 2);
- _cmsEmu->portWrite(0x220, cms.ampl[2]);
+ _cmsEmu->portWrite(0x220, _sfxAmpl[2]);
_cmsEmu->portWrite(0x221, 3);
- _cmsEmu->portWrite(0x220, cms.ampl[3]);
+ _cmsEmu->portWrite(0x220, _sfxAmpl[3]);
_cmsEmu->portWrite(0x221, 8);
- _cmsEmu->portWrite(0x220, cms.freq[0]);
+ _cmsEmu->portWrite(0x220, _sfxFreq[0]);
_cmsEmu->portWrite(0x221, 9);
- _cmsEmu->portWrite(0x220, cms.freq[1]);
+ _cmsEmu->portWrite(0x220, _sfxFreq[1]);
_cmsEmu->portWrite(0x221, 10);
- _cmsEmu->portWrite(0x220, cms.freq[2]);
+ _cmsEmu->portWrite(0x220, _sfxFreq[2]);
_cmsEmu->portWrite(0x221, 11);
- _cmsEmu->portWrite(0x220, cms.freq[3]);
+ _cmsEmu->portWrite(0x220, _sfxFreq[3]);
_cmsEmu->portWrite(0x221, 0x10);
- _cmsEmu->portWrite(0x220, cms.octave[0]);
+ _cmsEmu->portWrite(0x220, _sfxOctave[0]);
_cmsEmu->portWrite(0x221, 0x11);
- _cmsEmu->portWrite(0x220, cms.octave[1]);
+ _cmsEmu->portWrite(0x220, _sfxOctave[1]);
_cmsEmu->portWrite(0x221, 0x14);
_cmsEmu->portWrite(0x220, 0x3E);
_cmsEmu->portWrite(0x221, 0x15);
diff --git a/engines/scumm/player_v2cms.h b/engines/scumm/player_v2cms.h
index cbad46fe5d..905c7c141e 100644
--- a/engines/scumm/player_v2cms.h
+++ b/engines/scumm/player_v2cms.h
@@ -50,7 +50,6 @@ public:
virtual bool isStereo() const { return true; }
private:
-#include "common/pack-start.h" // START STRUCT PACKING
struct Voice {
byte attack;
byte decay;
@@ -60,7 +59,7 @@ private:
int16 vibrato;
int16 vibrato2;
int16 noise;
- } PACKED_STRUCT;
+ };
struct Voice2 {
byte *amplitudeOutput;
@@ -105,14 +104,13 @@ private:
Voice2 *nextVoice;
byte chanNumber;
- } PACKED_STRUCT;
+ };
struct MusicChip {
byte ampl[4];
byte freq[4];
byte octave[2];
- } PACKED_STRUCT;
-#include "common/pack-end.h" // END STRUCT PACKING
+ };
Voice _cmsVoicesBase[16];
Voice2 _cmsVoices[8];
@@ -130,6 +128,8 @@ private:
int _loadedMidiSong;
+ byte _sfxFreq[4], _sfxAmpl[4], _sfxOctave[2];
+
byte _lastMidiCommand;
uint _outputTableReady;
byte _voiceTimer;
diff --git a/engines/scumm/sound.cpp b/engines/scumm/sound.cpp
index 50ae045052..5aded50600 100644
--- a/engines/scumm/sound.cpp
+++ b/engines/scumm/sound.cpp
@@ -1157,7 +1157,9 @@ int ScummEngine::readSoundResource(ResId idx) {
// only contains a ROL resource for sound id 60. Formerly we tried
// to play that via the AdLib or FM-Towns audio driver resulting
// in strange noises. Now we behave like the original did.
- if ((_sound->_musicType == MDT_ADLIB || _sound->_musicType == MDT_TOWNS) && pri != 10)
+ // We make an exception for priority 2 for the Mac output since
+ // we're doing GM -> AdLib conversion.
+ if ((_sound->_musicType == MDT_ADLIB || _sound->_musicType == MDT_TOWNS) && pri != 10 && pri != 2)
pri = -1;
debugC(DEBUG_RESOURCE, " tag: %s, total_size=%d, pri=%d", tag2str(tag), size, pri);
diff --git a/engines/tinsel/detection_tables.h b/engines/tinsel/detection_tables.h
index 116322aa89..bea0938fad 100644
--- a/engines/tinsel/detection_tables.h
+++ b/engines/tinsel/detection_tables.h
@@ -214,7 +214,7 @@ static const TinselGameDescription gameDescriptions[] = {
},
Common::EN_ANY,
Common::kPlatformPC,
- ADGF_NO_FLAGS,
+ ADGF_CD,
GUIO_NONE
},
GID_DW1,
@@ -236,7 +236,7 @@ static const TinselGameDescription gameDescriptions[] = {
},
Common::IT_ITA,
Common::kPlatformPC,
- ADGF_DROPLANGUAGE,
+ ADGF_DROPLANGUAGE | ADGF_CD,
GUIO_NONE
},
GID_DW1,
@@ -261,7 +261,7 @@ static const TinselGameDescription gameDescriptions[] = {
},
Common::FR_FRA,
Common::kPlatformPC,
- ADGF_DROPLANGUAGE,
+ ADGF_DROPLANGUAGE | ADGF_CD,
GUIO_NONE
},
GID_DW1,
@@ -285,7 +285,7 @@ static const TinselGameDescription gameDescriptions[] = {
},
Common::DE_DEU,
Common::kPlatformPC,
- ADGF_DROPLANGUAGE,
+ ADGF_DROPLANGUAGE | ADGF_CD,
GUIO_NONE
},
GID_DW1,
@@ -308,7 +308,7 @@ static const TinselGameDescription gameDescriptions[] = {
},
Common::IT_ITA,
Common::kPlatformPC,
- ADGF_DROPLANGUAGE,
+ ADGF_DROPLANGUAGE | ADGF_CD,
GUIO_NONE
},
GID_DW1,
@@ -331,7 +331,7 @@ static const TinselGameDescription gameDescriptions[] = {
},
Common::ES_ESP,
Common::kPlatformPC,
- ADGF_DROPLANGUAGE,
+ ADGF_DROPLANGUAGE | ADGF_CD,
GUIO_NONE
},
GID_DW1,
@@ -351,7 +351,7 @@ static const TinselGameDescription gameDescriptions[] = {
},
Common::EN_ANY,
Common::kPlatformPC,
- ADGF_NO_FLAGS,
+ ADGF_CD,
GUIO_NONE
},
GID_DW1,
@@ -371,7 +371,7 @@ static const TinselGameDescription gameDescriptions[] = {
},
Common::HE_ISR,
Common::kPlatformPC,
- ADGF_NO_FLAGS,
+ ADGF_CD,
GUIO_NONE
},
GID_DW1,
@@ -390,7 +390,7 @@ static const TinselGameDescription gameDescriptions[] = {
},
Common::EN_ANY,
Common::kPlatformPSX,
- ADGF_NO_FLAGS,
+ ADGF_CD,
GUIO_NONE
},
GID_DW1,
@@ -434,7 +434,7 @@ static const TinselGameDescription gameDescriptions[] = {
},
Common::EN_ANY,
Common::kPlatformPC,
- ADGF_NO_FLAGS,
+ ADGF_CD,
GUIO_NONE
},
GID_DW1,
@@ -456,7 +456,7 @@ static const TinselGameDescription gameDescriptions[] = {
},
Common::EN_ANY,
Common::kPlatformMacintosh,
- ADGF_NO_FLAGS,
+ ADGF_CD,
GUIO_NONE
},
GID_DW1,
@@ -475,7 +475,7 @@ static const TinselGameDescription gameDescriptions[] = {
AD_ENTRY1s("dw.scn", "6182c7986eaec893c62fb6ea13a9f225", 774556),
Common::DE_DEU,
Common::kPlatformPC,
- ADGF_NO_FLAGS,
+ ADGF_CD,
GUIO_NONE
},
GID_DW1,
@@ -496,7 +496,7 @@ static const TinselGameDescription gameDescriptions[] = {
},
Common::RU_RUS,
Common::kPlatformPC,
- ADGF_NO_FLAGS,
+ ADGF_CD,
GUIO_NONE
},
GID_DW1,
diff --git a/engines/toon/path.cpp b/engines/toon/path.cpp
index 785b84a78e..60ca007930 100644
--- a/engines/toon/path.cpp
+++ b/engines/toon/path.cpp
@@ -33,15 +33,15 @@ PathFindingHeap::PathFindingHeap() {
}
PathFindingHeap::~PathFindingHeap() {
- delete[] _data;
+ free(_data);
}
void PathFindingHeap::init(int32 size) {
debugC(1, kDebugPath, "init(%d)", size);
_size = size;
- delete[] _data;
- _data = new HeapDataGrid[_size];
+ free(_data);
+ _data = (HeapDataGrid *)malloc(sizeof(HeapDataGrid) * _size);
memset(_data, 0, sizeof(HeapDataGrid) * _size);
_count = 0;
}
@@ -49,7 +49,7 @@ void PathFindingHeap::init(int32 size) {
void PathFindingHeap::unload() {
_count = 0;
_size = 0;
- delete[] _data;
+ free(_data);
_data = NULL;
}
@@ -64,8 +64,19 @@ void PathFindingHeap::push(int32 x, int32 y, int32 weight) {
debugC(2, kDebugPath, "push(%d, %d, %d)", x, y, weight);
if (_count == _size) {
- warning("Aborting attempt to push onto PathFindingHeap at maximum size: %d", _count);
- return;
+ // Increase size by 50%
+ int newSize = _size + (_size >> 1) + 1;
+ HeapDataGrid *newData;
+
+ newData = (HeapDataGrid *)realloc(_data, sizeof(HeapDataGrid) * newSize);
+ if (newData == NULL) {
+ warning("Aborting attempt to push onto PathFindingHeap at maximum size: %d", _count);
+ return;
+ }
+
+ memset(newData + _size, 0, sizeof(HeapDataGrid) * (newSize - _size));
+ _data = newData;
+ _size = newSize;
}
_data[_count]._x = x;
@@ -427,11 +438,7 @@ void PathFinding::init(Picture *mask) {
_height = mask->getHeight();
_currentMask = mask;
_heap->unload();
- // In order to reduce memory fragmentation on small devices, we use the maximum
- // possible size here which is TOON_BACKBUFFER_WIDTH. Even though this is
- // 1280 as opposed to the possible 640, it actually helps memory allocation on
- // those devices.
- _heap->init(TOON_BACKBUFFER_WIDTH * _height); // should really be _width
+ _heap->init(500);
delete[] _gridTemp;
_gridTemp = new int32[_width*_height];
}
diff --git a/engines/tsage/blue_force/blueforce_logic.cpp b/engines/tsage/blue_force/blueforce_logic.cpp
new file mode 100644
index 0000000000..ec85e48fbf
--- /dev/null
+++ b/engines/tsage/blue_force/blueforce_logic.cpp
@@ -0,0 +1,255 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "tsage/blue_force/blueforce_logic.h"
+#include "tsage/blue_force/blueforce_scenes0.h"
+#include "tsage/blue_force/blueforce_scenes1.h"
+#include "tsage/scenes.h"
+#include "tsage/tsage.h"
+#include "tsage/staticres.h"
+
+namespace TsAGE {
+
+namespace BlueForce {
+
+void BlueForceGame::start() {
+ // Start the game
+ _globals->_sceneManager.changeScene(100);
+
+ _globals->_events.setCursor(CURSOR_WALK);
+}
+
+Scene *BlueForceGame::createScene(int sceneNumber) {
+ switch (sceneNumber) {
+ /* Scene Group #0 */
+ case 20:
+ // Tsunami Title Screen
+ return new Scene20();
+ case 50:
+ case 60:
+ error("Scene group 0 not implemented");
+ /* Scene Group #1 */
+ case 100:
+ // Tsnunami Title Screen #2
+ return new Scene100();
+ case 109:
+ // Introduction Bar Room
+ return new Scene109();
+ case 110:
+ case 114:
+ case 115:
+ case 125:
+ case 140:
+ case 150:
+ case 160:
+ case 180:
+ case 190:
+ error("Scene group 1 not implemented");
+ case 200:
+ case 210:
+ case 220:
+ case 225:
+ case 265:
+ case 270:
+ case 271:
+ case 280:
+ error("Scene group 2 not implemented");
+ case 300:
+ case 315:
+ case 325:
+ case 330:
+ case 340:
+ case 342:
+ case 350:
+ case 355:
+ case 360:
+ case 370:
+ case 380:
+ case 385:
+ case 390:
+ error("Scene group 3 not implemented");
+ case 410:
+ case 415:
+ case 440:
+ case 450:
+ error("Scene group 4 not implemented");
+ case 550:
+ case 551:
+ case 560:
+ case 570:
+ case 580:
+ case 590:
+ error("Scene group 5 not implemented");
+ case 600:
+ case 620:
+ case 666:
+ case 690:
+ error("Scene group 6 not implemented");
+ case 710:
+ error("Scene group 7 not implemented");
+ case 800:
+ case 810:
+ case 820:
+ case 830:
+ case 840:
+ case 850:
+ case 860:
+ case 870:
+ case 880:
+ error("Scene group 8 not implemented");
+ case 900:
+ case 910:
+ case 920:
+ case 930:
+ case 935:
+ case 940:
+ error("Scene group 9 not implemented");
+ default:
+ error("Unknown scene number - %d", sceneNumber);
+ break;
+ }
+}
+
+/*--------------------------------------------------------------------------*/
+
+ObjArray::ObjArray(): EventHandler() {
+ _inUse = false;
+ clear();
+}
+
+void ObjArray::clear() {
+ for (int i = 0; i < OBJ_ARRAY_SIZE; ++i)
+ _objList[i] = NULL;
+}
+
+void ObjArray::synchronize(Serializer &s) {
+ EventHandler::synchronize(s);
+ for (int i = 0; i < OBJ_ARRAY_SIZE; ++i)
+ SYNC_POINTER(_objList[i]);
+}
+
+void ObjArray::process(Event &event) {
+ if (_inUse)
+ error("Array error");
+ _inUse = true;
+
+ for (int i = 0; i < OBJ_ARRAY_SIZE; ++i) {
+ if (_objList[i])
+ _objList[i]->process(event);
+ }
+
+ _inUse = false;
+}
+
+void ObjArray::dispatch() {
+ if (_inUse)
+ error("Array error");
+ _inUse = true;
+
+ for (int i = 0; i < OBJ_ARRAY_SIZE; ++i) {
+ if (_objList[i])
+ _objList[i]->dispatch();
+ }
+
+ _inUse = false;
+}
+
+/*--------------------------------------------------------------------------*/
+
+SceneExt::SceneExt(): Scene() {
+ warning("TODO: dword_503AA/dword_503AE/dword_53030");
+
+ _field372 = 0;
+ _field37C = NULL;
+}
+
+void SceneExt::postInit(SceneObjectList *OwnerList) {
+ Scene::postInit(OwnerList);
+ if (BF_GLOBALS._v4CEA2) {
+ // Blank out the bottom portion of the screen
+ BF_GLOBALS._interfaceY = BF_INTERFACE_Y;
+
+ Rect r(0, BF_INTERFACE_Y, SCREEN_WIDTH, SCREEN_HEIGHT);
+ BF_GLOBALS.gfxManager().getSurface().fillRect(r, 0);
+ }
+}
+
+void SceneExt::process(Event &event) {
+ _objArray2.process(event);
+ if (!event.handled)
+ Scene::process(event);
+}
+
+void SceneExt::dispatch() {
+ _objArray1.dispatch();
+
+ if (_field37A) {
+ if ((--_field37A == 0) && BF_GLOBALS._v4CEA2) {
+ if (BF_GLOBALS._v4E238 && (BF_GLOBALS._v4CF9E == 1)) {
+ warning("sub_1B052");
+ }
+
+ _field37A = 0;
+ }
+ }
+
+ Scene::dispatch();
+}
+
+void SceneExt::loadScene(int sceneNum) {
+ Scene::loadScene(sceneNum);
+
+ _v51C34.top = 0;
+ _v51C34.bottom = 300;
+}
+
+/*--------------------------------------------------------------------------*/
+
+GameScene::GameScene() {
+
+}
+
+void GameScene::postInit(SceneObjectList *OwnerList) {
+ _field794 = 0;
+ _field412 = 1;
+ SceneExt::postInit(OwnerList);
+}
+
+void GameScene::remove() {
+ SceneExt::remove();
+ if (_field794 == 1) {
+ for (SynchronizedList<SceneObject *>::iterator i = BF_GLOBALS._sceneObjects->begin();
+ i != BF_GLOBALS._sceneObjects->end(); ++i)
+ (*i)->remove();
+
+ BF_GLOBALS._sceneObjects->draw();
+ BF_GLOBALS._scenePalette.loadPalette(2);
+ BF_GLOBALS._v51C44 = 1;
+ BF_GLOBALS._v51C42 = 1;
+ }
+
+ BF_GLOBALS._scenePalette._field412 = 1;
+}
+
+} // End of namespace BlueForce
+
+} // End of namespace TsAGE
diff --git a/engines/tsage/blueforce_logic.h b/engines/tsage/blue_force/blueforce_logic.h
index 9237e50a13..1ff6ecf507 100644
--- a/engines/tsage/blueforce_logic.h
+++ b/engines/tsage/blue_force/blueforce_logic.h
@@ -29,7 +29,13 @@
#include "tsage/scenes.h"
#include "tsage/globals.h"
-namespace tSage {
+#define BF_INTERFACE_Y 168
+
+namespace TsAGE {
+
+namespace BlueForce {
+
+using namespace TsAGE;
class BlueForceGame: public Game {
public:
@@ -37,6 +43,57 @@ public:
virtual Scene *createScene(int sceneNumber);
};
-} // End of namespace tSage
+#define OBJ_ARRAY_SIZE 10
+class ObjArray: public EventHandler {
+public:
+ EventHandler *_objList[OBJ_ARRAY_SIZE];
+ bool _inUse;
+public:
+ ObjArray();
+ void clear();
+
+ virtual Common::String getClassName() { return "ObjArray"; }
+ virtual void synchronize(Serializer &s);
+ virtual void process(Event &event);
+ virtual void dispatch();
+};
+
+class SceneExt: public Scene {
+public:
+ ObjArray _objArray1, _objArray2;
+ int _field372;
+ int _field37A;
+ EventHandler *_field37C;
+
+ Rect _v51C34;
+public:
+ SceneExt();
+
+ virtual Common::String getClassName() { return "SceneExt"; }
+ virtual void postInit(SceneObjectList *OwnerList = NULL);
+ virtual void process(Event &event);
+ virtual void dispatch();
+ virtual void loadScene(int sceneNum);
+ virtual void proc13() { warning("TODO: SceneExt::proc13"); }
+};
+
+class GameScene: public SceneExt {
+public:
+ int _field412;
+ int _field794;
+public:
+ GameScene();
+
+ virtual void postInit(SceneObjectList *OwnerList = NULL);
+ virtual void remove();
+};
+
+class BlueAnimatedSpeaker: public Speaker {
+public:
+};
+
+} // End of namespace BlueForce
+
+} // End of namespace TsAGE
#endif
diff --git a/engines/tsage/blueforce_scenes0.cpp b/engines/tsage/blue_force/blueforce_scenes0.cpp
index 4a0259cb98..cc0f9bb1fd 100644
--- a/engines/tsage/blueforce_scenes0.cpp
+++ b/engines/tsage/blue_force/blueforce_scenes0.cpp
@@ -20,20 +20,22 @@
*
*/
-#include "tsage/blueforce_scenes0.h"
+#include "tsage/blue_force/blueforce_scenes0.h"
#include "tsage/scenes.h"
#include "tsage/tsage.h"
#include "tsage/staticres.h"
-namespace tSage {
+namespace TsAGE {
+
+namespace BlueForce {
/*--------------------------------------------------------------------------
* Scene 20 - Tsunami Title Screen
*
*--------------------------------------------------------------------------*/
-void BF_Scene20::Action1::signal() {
- BF_Scene20 *scene = (BF_Scene20 *)_globals->_sceneManager._scene;
+void Scene20::Action1::signal() {
+ Scene20 *scene = (Scene20 *)BF_GLOBALS._sceneManager._scene;
static byte black[3] = { 0, 0, 0 };
switch (_actionIndex++) {
@@ -42,7 +44,7 @@ void BF_Scene20::Action1::signal() {
break;
case 1:
_sound.play(1);
- _globals->_scenePalette.addRotation(64, 127, -1, 1, this);
+ BF_GLOBALS._scenePalette.addRotation(64, 127, -1, 1, this);
break;
case 2:
scene->_object1.setVisage(22);
@@ -88,7 +90,7 @@ void BF_Scene20::Action1::signal() {
setDelay(1);
break;
case 3:
- _globals->_scenePalette.addFader(scene->_scenePalette._palette, 256, 8, this);
+ BF_GLOBALS._scenePalette.addFader(scene->_scenePalette._palette, 256, 8, this);
break;
case 4:
setDelay(60);
@@ -105,10 +107,10 @@ void BF_Scene20::Action1::signal() {
setDelay(120);
break;
case 7:
- _globals->_scenePalette.addFader(black, 1, 5, this);
+ BF_GLOBALS._scenePalette.addFader(black, 1, 5, this);
break;
case 8:
- _globals->_sceneManager.changeScene(100);
+ BF_GLOBALS._sceneManager.changeScene(100);
remove();
break;
}
@@ -116,13 +118,11 @@ void BF_Scene20::Action1::signal() {
/*--------------------------------------------------------------------------*/
-void BF_Scene20::postInit(SceneObjectList *OwnerList) {
+void Scene20::postInit(SceneObjectList *OwnerList) {
loadScene(20);
Scene::postInit();
setZoomPercents(60, 85, 200, 100);
- preloadVisage(21);
- preloadVisage(22);
_scenePalette.loadPalette(1);
_scenePalette.loadPalette(22);
@@ -193,4 +193,52 @@ void BF_Scene20::postInit(SceneObjectList *OwnerList) {
setAction(&_action1);
}
-} // End of namespace tSage
+/*--------------------------------------------------------------------------
+ * Scene 50 - Map Screen
+ *
+ *--------------------------------------------------------------------------*/
+
+Scene50::Tooltip::Tooltip(): SavedObject() {
+ strcpy(_msg, "");
+ _field60 = _field62 = 0;
+}
+
+void Scene50::Tooltip::synchronize(Serializer &s) {
+ SavedObject::synchronize(s);
+ _bounds.synchronize(s);
+ s.syncBytes((byte *)&_msg[0], 84);
+}
+
+void Scene50::Tooltip2::signal() {
+ switch (_actionIndex++) {
+ case 0:
+ setDelay(60);
+ break;
+ case 1: {
+ Common::Point pt(410, 181);
+ NpcMover *mover = new NpcMover();
+ ((SceneObject *)_owner)->addMover(mover, &pt, this);
+ break;
+ }
+ case 2:
+ _owner->remove();
+ break;
+ default:
+ break;
+ }
+}
+
+void Scene50::Tooltip2::dispatch() {
+ Action::dispatch();
+ SceneObject *owner = (SceneObject *)_owner;
+
+ if ((_actionIndex == 2) && (owner->_percent < 100)) {
+ owner->changeZoom(owner->_percent + 1);
+ }
+}
+
+/*--------------------------------------------------------------------------*/
+
+} // End of namespace BlueForce
+
+} // End of namespace TsAGE
diff --git a/engines/tsage/blueforce_scenes0.h b/engines/tsage/blue_force/blueforce_scenes0.h
index 06f7912959..587941e59e 100644
--- a/engines/tsage/blueforce_scenes0.h
+++ b/engines/tsage/blue_force/blueforce_scenes0.h
@@ -24,7 +24,7 @@
#define TSAGE_BLUEFORCE_SCENES0_H
#include "common/scummsys.h"
-#include "tsage/blueforce_logic.h"
+#include "tsage/blue_force/blueforce_logic.h"
#include "tsage/converse.h"
#include "tsage/events.h"
#include "tsage/core.h"
@@ -32,9 +32,13 @@
#include "tsage/globals.h"
#include "tsage/sound.h"
-namespace tSage {
+namespace TsAGE {
-class BF_Scene20 : public Scene {
+namespace BlueForce {
+
+using namespace TsAGE;
+
+class Scene20 : public SceneExt {
/* Actions */
class Action1 : public Action {
private:
@@ -51,6 +55,33 @@ public:
virtual void postInit(SceneObjectList *OwnerList = NULL);
};
-} // End of namespace tSage
+class Scene50: public SceneExt {
+ class Tooltip: public SavedObject {
+ public:
+ Rect _bounds;
+ char _msg[80];
+ int _field60;
+ int _field62;
+ public:
+ Tooltip();
+
+ virtual Common::String getClassName() { return "Scene50_Tooltip"; }
+ virtual void synchronize(Serializer &s);
+ };
+ class Tooltip2: public Action {
+ public:
+ Tooltip2(): Action() {}
+
+ virtual Common::String getClassName() { return "Scene50_Tooltip2"; }
+ virtual void signal();
+ virtual void dispatch();
+ };
+public:
+
+};
+
+} // End of namespace BlueForce
+
+} // End of namespace TsAGE
#endif
diff --git a/engines/tsage/blue_force/blueforce_scenes1.cpp b/engines/tsage/blue_force/blueforce_scenes1.cpp
new file mode 100644
index 0000000000..650b63c24b
--- /dev/null
+++ b/engines/tsage/blue_force/blueforce_scenes1.cpp
@@ -0,0 +1,432 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "common/config-manager.h"
+#include "tsage/blue_force/blueforce_scenes1.h"
+#include "tsage/scenes.h"
+#include "tsage/tsage.h"
+#include "tsage/staticres.h"
+#include "tsage/globals.h"
+
+namespace TsAGE {
+
+namespace BlueForce {
+
+/*--------------------------------------------------------------------------
+ * Scene 100 - Tsunami Title Screen #2
+ *
+ *--------------------------------------------------------------------------*/
+
+void Scene100::Text::dispatch() {
+ SceneText::dispatch();
+
+ // Keep the second text string below the first one
+ Scene100 *scene = (Scene100 *)BF_GLOBALS._sceneManager._scene;
+ Common::Point &pt = scene->_action1._sceneText1._position;
+ scene->_action1._sceneText2.setPosition(Common::Point(pt.x,
+ pt.y + scene->_action1._textHeight));
+}
+
+
+void Scene100::Action1::signal() {
+ static byte black[3] = { 0, 0, 0 };
+
+ switch (_actionIndex++) {
+ case 0:
+ _state = 0;
+ setDelay(6);
+ break;
+ case 1: {
+ Common::String msg1 = _resourceManager->getMessage(100, _state++);
+ if (msg1.compareTo("LASTCREDIT")) {
+ Common::String msg2 = _resourceManager->getMessage(100, _state++);
+ setTextStrings(msg1, msg2, this);
+ --_actionIndex;
+ } else {
+ setTextStrings(BF_NAME, BF_ALL_RIGHTS_RESERVED, this);
+
+ Common::Point pt(_sceneText1._position.x, 80);
+ NpcMover *mover = new NpcMover();
+ _sceneText1.addMover(mover, &pt, this);
+ }
+ break;
+ }
+ case 2:
+ setDelay(600);
+ break;
+ case 3:
+ BF_GLOBALS._sound1.fade(0, 10, 10, 1, this);
+ GLOBALS._scenePalette.addFader(black, 1, 2, NULL);
+ break;
+ case 4:
+ error("??exit");
+ break;
+ }
+}
+
+void Scene100::Action1::setTextStrings(const Common::String &msg1, const Common::String &msg2, Action *action) {
+ // Set data for first text control
+ _sceneText1._fontNumber = 10;
+ _sceneText1._width = 160;
+ _sceneText1._textMode = ALIGN_RIGHT;
+ _sceneText1._color1 = BF_GLOBALS._scenePalette._colors.foreground;
+ _sceneText1._color2 = BF_GLOBALS._scenePalette._colors.background;
+ _sceneText1._color3 = BF_GLOBALS._scenePalette._colors.foreground;
+ _sceneText1.setup(msg1);
+ _sceneText1.fixPriority(255);
+ _sceneText1.setPosition(Common::Point(
+ (SCREEN_WIDTH - _sceneText1.getFrame().getBounds().width()) / 2, 202));
+ _sceneText1._moveRate = 30;
+ _sceneText1._moveDiff.y = 1;
+
+ // Set data for second text control
+ _sceneText2._fontNumber = 10;
+ _sceneText2._width = _sceneText1._width;
+ _sceneText2._textMode = _sceneText1._textMode;
+ _sceneText2._color1 = _sceneText1._color1;
+ _sceneText2._color2 = 31;
+ _sceneText2._color3 = _sceneText1._color3;
+ _sceneText2.setup(msg2);
+ _sceneText2.fixPriority(255);
+ GfxSurface textSurface = _sceneText2.getFrame();
+ _sceneText2.setPosition(Common::Point((SCREEN_WIDTH - textSurface.getBounds().width()) / 2, 202));
+ _sceneText2._moveRate = 30;
+ _sceneText2._moveDiff.y = 1;
+
+ _textHeight = textSurface.getBounds().height();
+ int yp = -(_textHeight * 2);
+
+ Common::Point pt(_sceneText1._position.x, yp);
+ NpcMover *mover = new NpcMover();
+ _sceneText1.addMover(mover, &pt, action);
+}
+
+void Scene100::Action2::signal() {
+ Scene100 *scene = (Scene100 *)_globals->_sceneManager._scene;
+ static byte black[3] = {0, 0, 0};
+
+ switch (_actionIndex++) {
+ case 0:
+ BF_GLOBALS._scenePalette.addFader(black, 1, -2, this);
+ break;
+ case 1:
+ setDelay(180);
+ break;
+ case 2: {
+ const char *SEEN_INTRO = "seen_intro";
+ if (!ConfMan.hasKey(SEEN_INTRO) || !ConfMan.getBool(SEEN_INTRO)) {
+ // First time being played, so will need to show the intro
+ ConfMan.setBool(SEEN_INTRO, true);
+ ConfMan.flushToDisk();
+ } else {
+ // Prompt user for whether to start play or watch introduction
+ _globals->_player.enableControl();
+
+ if (MessageDialog::show2(WATCH_INTRO_MSG, START_PLAY_BTN_STRING, INTRODUCTION_BTN_STRING) == 0) {
+ // Signal to start the game
+ scene->_index = 190;
+ remove();
+ return;
+ }
+ }
+
+ // At this point the introduction needs to start
+ _globals->_scenePalette.addFader(black, 1, 2, this);
+ break;
+ }
+ case 3:
+ remove();
+ break;
+ }
+}
+
+/*--------------------------------------------------------------------------*/
+
+Scene100::Scene100(): SceneExt() {
+ _index = 0;
+}
+
+void Scene100::postInit(SceneObjectList *OwnerList) {
+ BF_GLOBALS._scenePalette.loadPalette(2);
+ BF_GLOBALS._v51C44 = 1;
+ Scene::postInit();
+ BF_GLOBALS._interfaceY = SCREEN_HEIGHT;
+
+ _globals->_player.enableControl();
+ _globals->_player.hide();
+ _globals->_player.disableControl();
+ _index = 109;
+
+ if (BF_GLOBALS._v4CEA2 < 6) {
+ // Title
+ loadScene(100);
+ BF_GLOBALS._sound1.play(2);
+ setAction(&_action2, this);
+ } else {
+ // Credits
+ loadScene(101);
+ BF_GLOBALS._sound1.play(118);
+ setAction(&_action1, this);
+ }
+}
+
+void Scene100::signal() {
+ ++_sceneMode;
+ if (BF_GLOBALS._v4CEA2 < 6) {
+ BF_GLOBALS._scenePalette.clearListeners();
+ BF_GLOBALS._scenePalette.loadPalette(100);
+ BF_GLOBALS._sceneManager.changeScene(_index);
+ } else {
+ if (_sceneMode > 1)
+ BF_GLOBALS._events.setCursor(CURSOR_ARROW);
+
+ setAction(this, &_action1, this);
+ }
+}
+
+/*--------------------------------------------------------------------------
+ * Scene 109 - Introduction Bar Room
+ *
+ *--------------------------------------------------------------------------*/
+
+void Scene109::Action1::signal() {
+ Scene109 *scene = (Scene109 *)BF_GLOBALS._sceneManager._scene;
+
+ switch (_actionIndex++) {
+ case 0:
+ setDelay(30);
+ break;
+ case 1:
+ BF_GLOBALS._sound1.play(12);
+ BF_GLOBALS._sceneObjects->draw();
+ BF_GLOBALS._scenePalette.loadPalette(2);
+ BF_GLOBALS._scenePalette.refresh();
+ setDelay(10);
+ break;
+ case 2:
+ scene->_text.setup(BF_19840515, this);
+ break;
+ case 3:
+ BF_GLOBALS._v51C44 = 1;
+ scene->loadScene(115);
+
+ scene->_protaginist2.show();
+ scene->_protaginist2.setPriority(133);
+ scene->_protaginist1.show();
+ scene->_bartender.show();
+ scene->_object1.show();
+ scene->_drunk.show();
+ scene->_drunk.setAction(&scene->_action3);
+ scene->_object2.show();
+ scene->_object9.show();
+ scene->_object9.setAction(&scene->_action2);
+
+ BF_GLOBALS._v501FC = 170;
+ setDelay(60);
+ break;
+ case 4:
+ // Start drinking
+ scene->_bartender.setAction(&scene->_sequenceManager4, NULL, 109, &scene->_bartender, &scene->_object2, NULL);
+ scene->_protaginist1.setAction(&scene->_sequenceManager5, NULL, 107, &scene->_protaginist1, NULL);
+ scene->_protaginist2.setAction(&scene->_sequenceManager6, this, 106, &scene->_protaginist2, NULL);
+ break;
+ case 5:
+ // Open briefcase and pass over disk
+ setAction(&scene->_sequenceManager6, this, 105, &scene->_object10, NULL);
+ break;
+ case 6:
+ // Protaginist 2 walk to the bar
+ scene->_object10.remove();
+ setAction(&scene->_sequenceManager6, this, 100, &scene->_protaginist2, NULL);
+ break;
+ case 7:
+ // Two thugs enter and walk to table
+ scene->_object7.setAction(&scene->_sequenceManager7, NULL, 103, &scene->_object7, NULL);
+ scene->_object5.setAction(&scene->_sequenceManager8, this, 102, &scene->_object5, NULL);
+ scene->_protaginist2.setAction(&scene->_sequenceManager6, NULL, 104, &scene->_protaginist2, &scene->_bartender, NULL);
+ break;
+ case 8:
+ // Protaginist 1 leaves, protaginist 2 stands up
+ setAction(&scene->_sequenceManager8, this, 101, &scene->_object5, &scene->_protaginist1, NULL);
+ break;
+ case 9:
+ // Shots fired!
+ scene->_protaginist1.setAction(&scene->_sequenceManager5, this, 98, &scene->_protaginist1, NULL);
+ scene->_object7.setAction(&scene->_sequenceManager7, NULL, 99, &scene->_object7, NULL);
+ break;
+ case 10:
+ // End scene
+ scene->_sceneMode = 1;
+ remove();
+ break;
+ }
+}
+
+void Scene109::Action2::signal() {
+ Scene109 *scene = (Scene109 *)BF_GLOBALS._sceneManager._scene;
+ scene->setAction(&scene->_sequenceManager2, this, 3117, &scene->_object9, NULL);
+}
+
+void Scene109::Action3::signal() {
+ Scene109 *scene = (Scene109 *)BF_GLOBALS._sceneManager._scene;
+ scene->setAction(&scene->_sequenceManager3, this, 108, &scene->_drunk, NULL);
+}
+
+/*--------------------------------------------------------------------------*/
+
+Scene109::Text::Text(): SceneText() {
+ _action = NULL;
+ _frameNumber = 0;
+ _diff = 0;
+}
+
+void Scene109::Text::setup(const Common::String &msg, Action *action) {
+ _frameNumber = BF_GLOBALS._events.getFrameNumber();
+ _diff = 180;
+ _action = action;
+ _fontNumber = 4;
+ _width = 300;
+ _textMode = ALIGN_CENTER;
+ _color1 = BF_GLOBALS._scenePalette._colors.background;
+ _color2 = _color3 = 0;
+
+ SceneText::setup(msg);
+
+ // Center the text on-screen
+ reposition();
+ _bounds.center(SCREEN_WIDTH / 2, SCREEN_HEIGHT / 2);
+
+ // Set the new position
+ _position.x = _bounds.left;
+ _position.y = _bounds.top;
+}
+
+void Scene109::Text::synchronize(Serializer &s) {
+ SceneText::synchronize(s);
+ SYNC_POINTER(_action);
+ s.syncAsUint32LE(_frameNumber);
+ s.syncAsSint16LE(_diff);
+}
+
+void Scene109::Text::dispatch() {
+ if (_diff) {
+ uint32 frameNumber = BF_GLOBALS._events.getFrameNumber();
+ if (_frameNumber < frameNumber) {
+ _diff -= frameNumber - _frameNumber;
+ _frameNumber = frameNumber;
+
+ if (_diff <= 0) {
+ // Time has expired, so remove the text and signal the designated action
+ remove();
+ if (_action)
+ _action->signal();
+ }
+ }
+ }
+}
+
+/*--------------------------------------------------------------------------*/
+
+Scene109::Scene109(): GameScene() {
+}
+
+void Scene109::postInit(SceneObjectList *OwnerList) {
+ GameScene::postInit(OwnerList);
+ loadScene(999);
+
+ _protaginist2.postInit();
+ _protaginist2.setVisage(119);
+ _protaginist2.setFrame(11);
+ _protaginist2.fixPriority(133);
+ _protaginist2.setPosition(Common::Point(165, 124));
+ _protaginist2.hide();
+
+ _protaginist1.postInit();
+ _protaginist1.setVisage(118);
+ _protaginist1.setStrip(1);
+ _protaginist1.setFrame(8);
+ _protaginist1.fixPriority(132);
+ _protaginist1.setPosition(Common::Point(143, 125));
+ _protaginist1.hide();
+
+ _bartender.postInit();
+ _bartender.setVisage(121);
+ _bartender.setStrip(2);
+ _bartender.setFrame(1);
+ _bartender.setPriority(-1);
+ _bartender.setPosition(Common::Point(92, 64));
+ _bartender.hide();
+
+ _object1.postInit();
+ _object1.setVisage(121);
+ _object1.setStrip(6);
+ _object1.setFrame(1);
+ _object1.setPriority(-1);
+ _object1.setPosition(Common::Point(110, 64));
+ _object1.hide();
+
+ _drunk.postInit();
+ _drunk.setVisage(120);
+ _drunk.setStrip(2);
+ _drunk.setFrame(5);
+ _drunk.setPriority(-1);
+ _drunk.setPosition(Common::Point(127, 97));
+ _drunk.hide();
+
+ _object2.postInit();
+ _object2.setVisage(121);
+ _object2.setStrip(5);
+ _object2.setFrame(1);
+ _object2.setPriority(-1);
+ _object2.setPosition(Common::Point(104, 64));
+ _object2.hide();
+
+ _object9.postInit();
+ _object9.setVisage(115);
+ _object9.setStrip(4);
+ _object9.setFrame(1);
+ _object9.setPosition(Common::Point(262, 29));
+ _object9.hide();
+
+ _object5.postInit();
+ _object5.hide();
+
+ _object7.postInit();
+ _object7.hide();
+
+ _object10.postInit();
+ _object10.hide();
+
+ BF_GLOBALS._player.disableControl();
+ setAction(&_action1, this);
+}
+
+void Scene109::signal() {
+ if (_sceneMode == 1) {
+ BF_GLOBALS._scenePalette.clearListeners();
+ BF_GLOBALS._sceneManager.changeScene(110);
+ }
+}
+
+} // End of namespace BlueForce
+
+} // End of namespace TsAGE
diff --git a/engines/tsage/blue_force/blueforce_scenes1.h b/engines/tsage/blue_force/blueforce_scenes1.h
new file mode 100644
index 0000000000..0769c6e3c6
--- /dev/null
+++ b/engines/tsage/blue_force/blueforce_scenes1.h
@@ -0,0 +1,132 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef TSAGE_BLUEFORCE_SCENES1_H
+#define TSAGE_BLUEFORCE_SCENES1_H
+
+#include "common/scummsys.h"
+#include "tsage/blue_force/blueforce_logic.h"
+#include "tsage/converse.h"
+#include "tsage/events.h"
+#include "tsage/core.h"
+#include "tsage/scenes.h"
+#include "tsage/globals.h"
+#include "tsage/sound.h"
+
+namespace TsAGE {
+
+namespace BlueForce {
+
+using namespace TsAGE;
+
+class Scene100: public SceneExt {
+ /* Support classes */
+ class Text: public SceneText {
+ public:
+ virtual Common::String getClassName() { return "BF100Text"; }
+ virtual void dispatch();
+ };
+
+ /* Actions */
+ class Action1: public ActionExt {
+ private:
+ void setTextStrings(const Common::String &msg1, const Common::String &msg2, Action *action);
+ public:
+ Text _sceneText1;
+ SceneText _sceneText2;
+ int _textHeight;
+
+ virtual Common::String getClassName() { return "BF100Action1"; }
+ virtual void synchronize(Serializer &s) {
+ ActionExt::synchronize(s);
+ s.syncAsSint16LE(_textHeight);
+ }
+ virtual void signal();
+ };
+ class Action2: public ActionExt {
+ public:
+ virtual void signal();
+ };
+public:
+ SequenceManager _sequenceManager;
+ Action1 _action1;
+ Action2 _action2;
+ ScenePalette _scenePalette;
+ SceneObjectExt2 _object1, _object2, _object3, _object4, _object5;
+ int _index;
+
+ Scene100();
+ virtual void postInit(SceneObjectList *OwnerList = NULL);
+ virtual void signal();
+};
+
+class Scene109: public GameScene {
+ /* Actions */
+ class Action1: public Action {
+ public:
+ virtual void signal();
+ };
+ class Action2: public Action {
+ public:
+ virtual void signal();
+ };
+ class Action3: public Action {
+ public:
+ virtual void signal();
+ };
+
+ /* Texts */
+ class Text: public SceneText {
+ public:
+ Action *_action;
+ uint32 _frameNumber;
+ int _diff;
+ public:
+ Text();
+ void setup(const Common::String &msg, Action *action);
+
+ virtual Common::String getClassName() { return "BF109Text"; }
+ virtual void synchronize(Serializer &s);
+ virtual void dispatch();
+ };
+public:
+ SequenceManager _sequenceManager1, _sequenceManager2, _sequenceManager3;
+ SequenceManager _sequenceManager4, _sequenceManager5, _sequenceManager6;
+ SequenceManager _sequenceManager7, _sequenceManager8;
+ SceneObject _object1, _object2, _protaginist2, _protaginist1, _object5;
+ SceneObject _drunk, _object7, _bartender, _object9, _object10;
+ Text _text;
+ BlueAnimatedSpeaker _speaker;
+ Action1 _action1;
+ Action _action2, _action3;
+public:
+ Scene109();
+
+ virtual void postInit(SceneObjectList *OwnerList = NULL);
+ virtual void signal();
+};
+
+} // End of namespace BlueForce
+
+} // End of namespace TsAGE
+
+#endif
diff --git a/engines/tsage/blueforce_logic.cpp b/engines/tsage/blueforce_logic.cpp
deleted file mode 100644
index 3cf31b0b0a..0000000000
--- a/engines/tsage/blueforce_logic.cpp
+++ /dev/null
@@ -1,123 +0,0 @@
-/* ScummVM - Graphic Adventure Engine
- *
- * ScummVM is the legal property of its developers, whose names
- * are too numerous to list here. Please refer to the COPYRIGHT
- * file distributed with this source distribution.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
-
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
-
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- */
-
-#include "tsage/blueforce_logic.h"
-#include "tsage/blueforce_scenes0.h"
-#include "tsage/scenes.h"
-#include "tsage/tsage.h"
-#include "tsage/staticres.h"
-
-namespace tSage {
-
-void BlueForceGame::start() {
- // Start the game
- _globals->_sceneManager.changeScene(20);
-
- _globals->_events.setCursor(CURSOR_WALK);
-}
-
-Scene *BlueForceGame::createScene(int sceneNumber) {
- switch (sceneNumber) {
- case 20:
- // Tsunami Title Screen
- return new BF_Scene20();
- case 50:
- case 60:
- error("Scene group 0 not implemented");
- case 100:
- case 109:
- case 110:
- case 114:
- case 115:
- case 125:
- case 140:
- case 150:
- case 160:
- case 180:
- case 190:
- error("Scene group 1 not implemented");
- case 200:
- case 210:
- case 220:
- case 225:
- case 265:
- case 270:
- case 271:
- case 280:
- error("Scene group 2 not implemented");
- case 300:
- case 315:
- case 325:
- case 330:
- case 340:
- case 342:
- case 350:
- case 355:
- case 360:
- case 370:
- case 380:
- case 385:
- case 390:
- error("Scene group 3 not implemented");
- case 410:
- case 415:
- case 440:
- case 450:
- error("Scene group 4 not implemented");
- case 550:
- case 551:
- case 560:
- case 570:
- case 580:
- case 590:
- error("Scene group 5 not implemented");
- case 600:
- case 620:
- case 666:
- case 690:
- error("Scene group 6 not implemented");
- case 710:
- error("Scene group 7 not implemented");
- case 800:
- case 810:
- case 820:
- case 830:
- case 840:
- case 850:
- case 860:
- case 870:
- case 880:
- error("Scene group 8 not implemented");
- case 900:
- case 910:
- case 920:
- case 930:
- case 935:
- case 940:
- error("Scene group 9 not implemented");
- default:
- error("Unknown scene number - %d", sceneNumber);
- break;
- }
-}
-
-} // End of namespace tSage
diff --git a/engines/tsage/converse.cpp b/engines/tsage/converse.cpp
index 0ae575c557..615b1c36fd 100644
--- a/engines/tsage/converse.cpp
+++ b/engines/tsage/converse.cpp
@@ -26,7 +26,7 @@
#include "tsage/globals.h"
#include "tsage/staticres.h"
-namespace tSage {
+namespace TsAGE {
#define STRIP_WORD_DELAY 30
@@ -34,7 +34,7 @@ namespace tSage {
SequenceManager::SequenceManager() : Action() {
Common::set_to(&_objectList[0], &_objectList[6], (SceneObject *)NULL);
_sequenceData.clear();
- _field24 = 0;
+ _fontNum = 0;
_sequenceOffset = 0;
_resNum = 0;
_field26 = 0;
@@ -56,7 +56,7 @@ void SequenceManager::synchronize(Serializer &s) {
s.syncAsSint32LE(_resNum);
s.syncAsSint32LE(_sequenceOffset);
s.syncAsByte(_keepActive);
- s.syncAsSint32LE(_field24);
+ s.syncAsSint32LE(_fontNum);
s.syncAsSint32LE(_field26);
s.syncAsSint32LE(_objectIndex);
@@ -284,6 +284,32 @@ void SequenceManager::signal() {
_objectList[objIndex3], _objectList[objIndex4], _objectList[objIndex5], _objectList[objIndex6], NULL);
break;
}
+ /* Following indexes were introduced for Blue Force */
+ case 35:
+ v1 = getNextValue();
+ _sceneObject->updateAngle(_objectList[v1]);
+ break;
+ case 36:
+ _sceneObject->animate(ANIM_MODE_9, NULL);
+ break;
+ case 37:
+ v1 = getNextValue();
+ v2 = getNextValue();
+ warning("TODO: dword_53030(%d,%d)", v1, v2);
+ break;
+ case 38: {
+ int resNum = getNextValue();
+ int lineNum = getNextValue();
+ int fontNum = getNextValue();
+ int color1 = getNextValue();
+ int color2 = getNextValue();
+ int color3 = getNextValue();
+ int xp = getNextValue();
+ int yp = getNextValue();
+ int width = getNextValue();
+ setMessage(resNum, lineNum, fontNum, color1, color2, color3, Common::Point(xp, yp), width);
+ break;
+ }
default:
error("SequenceManager::signal - Unknown action %d at offset %xh", idx, _sequenceOffset - 2);
break;
@@ -337,10 +363,15 @@ uint16 SequenceManager::getNextValue() {
}
void SequenceManager::setMessage(int resNum, int lineNum, int color, const Common::Point &pt, int width) {
- _sceneText._color1 = color;
- _sceneText._color2 = 0;
- _sceneText._color3 = 0;
- _sceneText._fontNumber = 2;
+ setMessage(resNum, lineNum, 2, color, 0, 0, pt, width);
+}
+
+void SequenceManager::setMessage(int resNum, int lineNum, int fontNum, int color1, int color2, int color3,
+ const Common::Point &pt, int width) {
+ _sceneText._color1 = color1;
+ _sceneText._color2 = color2;
+ _sceneText._color3 = color3;
+ _sceneText._fontNumber = fontNum;
_sceneText._width = width;
// Get the display message
@@ -954,4 +985,4 @@ void AnimatedSpeaker::removeText() {
_objectList.draw();
}
-} // end of namespace tSage
+} // end of namespace TsAGE
diff --git a/engines/tsage/converse.h b/engines/tsage/converse.h
index 13c490e995..e263a12d12 100644
--- a/engines/tsage/converse.h
+++ b/engines/tsage/converse.h
@@ -27,7 +27,7 @@
#include "tsage/dialogs.h"
#include "tsage/sound.h"
-namespace tSage {
+namespace TsAGE {
class StripCallback : public Action {
public:
@@ -39,13 +39,15 @@ private:
void setup();
uint16 getNextValue();
void setMessage(int resNum, int lineNum, int color, const Common::Point &pt, int width);
+ void setMessage(int resNum, int lineNum, int fontNum, int color1, int color2, int color3,
+ const Common::Point &pt, int width);
SequenceManager *globalManager();
public:
SceneText _sceneText;
int _resNum;
uint _sequenceOffset;
bool _keepActive;
- int _field24;
+ int _fontNum;
int _field26;
Common::Array<byte> _sequenceData;
int _objectIndex;
@@ -222,6 +224,6 @@ public:
void addSpeaker(Speaker *speaker);
};
-} // End of namespace tSage
+} // End of namespace TsAGE
#endif
diff --git a/engines/tsage/core.cpp b/engines/tsage/core.cpp
index d0075d5acf..864c3af103 100644
--- a/engines/tsage/core.cpp
+++ b/engines/tsage/core.cpp
@@ -33,7 +33,7 @@
#include "tsage/globals.h"
#include "tsage/sound.h"
-namespace tSage {
+namespace TsAGE {
// The engine uses ScumMVM screen buffering, so all logic is hardcoded to use pane buffer 0
#define CURRENT_PANENUM 0
@@ -1161,6 +1161,20 @@ void PaletteFader::remove() {
action->signal();
}
+void PaletteFader::setPalette(ScenePalette *palette, int step) {
+ if (step < 0) {
+ // Reverse step means moving from dest palette to source, so swap the two palettes
+ byte tempPal[256 * 3];
+ Common::copy(&palette->_palette[0], &palette->_palette[256 * 3], &tempPal[0]);
+ Common::copy(&this->_palette[0], &this->_palette[256 * 3], &palette->_palette[0]);
+ Common::copy(&tempPal[0], &tempPal[256 * 3], &this->_palette[0]);
+
+ step = -step;
+ }
+
+ PaletteModifierCached::setPalette(palette, step);
+}
+
/*--------------------------------------------------------------------------*/
ScenePalette::ScenePalette() {
@@ -1314,7 +1328,7 @@ PaletteRotation *ScenePalette::addRotation(int start, int end, int rotationMode,
return obj;
}
-PaletteFader *ScenePalette::addFader(const byte *arrBufferRGB, int palSize, int percent, Action *action) {
+PaletteFader *ScenePalette::addFader(const byte *arrBufferRGB, int palSize, int step, Action *action) {
PaletteFader *fader = new PaletteFader();
fader->_action = action;
for (int i = 0; i < 256 * 3; i += 3) {
@@ -1326,7 +1340,7 @@ PaletteFader *ScenePalette::addFader(const byte *arrBufferRGB, int palSize, int
arrBufferRGB += 3;
}
- fader->setPalette(this, percent);
+ fader->setPalette(this, step);
_globals->_scenePalette._listeners.push_back(fader);
return fader;
}
@@ -1641,6 +1655,11 @@ void SceneObjectWrapper::remove() {
}
void SceneObjectWrapper::dispatch() {
+ if (_vm->getGameID() == GType_Ringworld)
+ check();
+}
+
+void SceneObjectWrapper::check() {
_visageImages.setVisage(_sceneObject->_visage);
int frameCount = _visageImages.getFrameCount();
int angle = _sceneObject->_angle;
@@ -2263,6 +2282,18 @@ void SceneObject::updateScreen() {
}
}
+void SceneObject::updateAngle(SceneObject *sceneObj) {
+ checkAngle(sceneObj);
+ if (_objectWrapper)
+ _objectWrapper->check();
+}
+
+void SceneObject::changeAngle(int angle) {
+ _angle = angle;
+ if (_objectWrapper)
+ _objectWrapper->check();
+}
+
void SceneObject::setup(int visage, int stripFrameNum, int frameNum, int posX, int posY, int priority) {
postInit();
setVisage(visage);
@@ -2274,6 +2305,22 @@ void SceneObject::setup(int visage, int stripFrameNum, int frameNum, int posX, i
/*--------------------------------------------------------------------------*/
+void SceneObjectExt2::postInit(SceneObjectList *OwnerList) {
+ _v8A = -1;
+ _v8C = -1;
+ _v8E = -1;
+ SceneObject::postInit();
+}
+
+void SceneObjectExt2::synchronize(Serializer &s) {
+ SceneObject::synchronize(s);
+ s.syncAsSint16LE(_v8A);
+ s.syncAsSint16LE(_v8C);
+ s.syncAsSint16LE(_v8E);
+}
+
+/*--------------------------------------------------------------------------*/
+
void SceneObjectList::draw() {
Common::Array<SceneObject *> objList;
int paneNum = 0;
@@ -3573,4 +3620,4 @@ void SceneHandler::dispatchObject(EventHandler *obj) {
void SceneHandler::saveListener(Serializer &ser) {
}
-} // End of namespace tSage
+} // End of namespace TsAGE
diff --git a/engines/tsage/core.h b/engines/tsage/core.h
index b86e2f63fe..96e7e82fe5 100644
--- a/engines/tsage/core.h
+++ b/engines/tsage/core.h
@@ -34,7 +34,7 @@
#include "tsage/resources.h"
#include "tsage/saveload.h"
-namespace tSage {
+namespace TsAGE {
#define MAX_FLAGS 256
@@ -287,7 +287,7 @@ public:
PaletteModifierCached();
- void setPalette(ScenePalette *palette, int step);
+ virtual void setPalette(ScenePalette *palette, int step);
virtual Common::String getClassName() { return "PaletteModifierCached"; }
virtual void synchronize(Serializer &s);
};
@@ -323,6 +323,7 @@ public:
virtual void synchronize(Serializer &s);
virtual void signal();
virtual void remove();
+ virtual void setPalette(ScenePalette *palette, int step);
};
/*--------------------------------------------------------------------------*/
@@ -356,7 +357,7 @@ public:
void clearListeners();
void fade(const byte *adjustData, bool fullAdjust, int percent);
PaletteRotation *addRotation(int start, int end, int rotationMode, int duration = 0, Action *action = NULL);
- PaletteFader *addFader(const byte *arrBufferRGB, int palSize, int percent, Action *action);
+ PaletteFader *addFader(const byte *arrBufferRGB, int palSize, int step, Action *action);
static void changeBackground(const Rect &bounds, FadeMode fadeMode);
@@ -436,7 +437,10 @@ public:
};
enum AnimateMode {ANIM_MODE_NONE = 0, ANIM_MODE_1 = 1, ANIM_MODE_2 = 2, ANIM_MODE_3 = 3,
- ANIM_MODE_4 = 4, ANIM_MODE_5 = 5, ANIM_MODE_6 = 6, ANIM_MODE_7 = 7, ANIM_MODE_8 = 8};
+ ANIM_MODE_4 = 4, ANIM_MODE_5 = 5, ANIM_MODE_6 = 6, ANIM_MODE_7 = 7, ANIM_MODE_8 = 8,
+ // Introduced in Blue Force
+ ANIM_MODE_9 = 9
+};
class SceneObject;
@@ -467,6 +471,7 @@ public:
virtual ~SceneObjectWrapper() {}
void setSceneObject(SceneObject *so);
+ void check();
virtual void synchronize(Serializer &s);
virtual Common::String getClassName() { return "SceneObjectWrapper"; }
@@ -555,6 +560,10 @@ public:
virtual void draw();
virtual void proc19() {}
virtual void updateScreen();
+ // New methods introduced by Blue FOrce
+ virtual void updateAngle(SceneObject *sceneObj);
+ virtual void changeAngle(int angle);
+
void setup(int visage, int stripFrameNum, int frameNum, int posX, int posY, int priority);
};
@@ -569,6 +578,16 @@ public:
virtual Common::String getClassName() { return "SceneObjectExt"; }
};
+class SceneObjectExt2: public SceneObject {
+public:
+ int _v88, _v8A, _v8C, _v8E;
+
+ virtual Common::String getClassName() { return "BF100Object"; }
+ virtual void synchronize(Serializer &s);
+ virtual void postInit(SceneObjectList *OwnerList = NULL);
+};
+
+
class SceneText : public SceneObject {
public:
int _fontNumber;
@@ -695,7 +714,7 @@ public:
SynchronizedList<SceneObject *>::iterator begin() { return _objList.begin(); }
SynchronizedList<SceneObject *>::iterator end() { return _objList.end(); }
int size() const { return _objList.size(); }
- bool contains(SceneObject *sceneObj) { return tSage::contains(_objList, sceneObj); }
+ bool contains(SceneObject *sceneObj) { return TsAGE::contains(_objList, sceneObj); }
void push_back(SceneObject *sceneObj) { _objList.push_back(sceneObj); }
void push_front(SceneObject *sceneObj) { _objList.push_front(sceneObj); }
void remove(SceneObject *sceneObj) {
@@ -840,6 +859,6 @@ public:
static void saveListener(Serializer &ser);
};
-} // End of namespace tSage
+} // End of namespace TsAGE
#endif
diff --git a/engines/tsage/debugger.cpp b/engines/tsage/debugger.cpp
index 00cd61ae07..e3c4569dd2 100644
--- a/engines/tsage/debugger.cpp
+++ b/engines/tsage/debugger.cpp
@@ -23,9 +23,9 @@
#include "tsage/debugger.h"
#include "tsage/globals.h"
#include "tsage/graphics.h"
-#include "tsage/ringworld_logic.h"
+#include "tsage/ringworld/ringworld_logic.h"
-namespace tSage {
+namespace TsAGE {
Debugger::Debugger() : GUI::Debugger() {
DCmd_Register("continue", WRAP_METHOD(Debugger, Cmd_Exit));
@@ -449,4 +449,4 @@ bool Debugger::Cmd_Sound(int argc, const char **argv) {
return false;
}
-} // End of namespace tSage
+} // End of namespace TsAGE
diff --git a/engines/tsage/debugger.h b/engines/tsage/debugger.h
index 44fd61ec5e..8bc1b06336 100644
--- a/engines/tsage/debugger.h
+++ b/engines/tsage/debugger.h
@@ -26,7 +26,7 @@
#include "common/scummsys.h"
#include "gui/debugger.h"
-namespace tSage {
+namespace TsAGE {
class Debugger : public GUI::Debugger {
public:
@@ -46,6 +46,6 @@ protected:
bool Cmd_Sound(int argc, const char **argv);
};
-} // End of namespace tSage
+} // End of namespace TsAGE
#endif
diff --git a/engines/tsage/detection.cpp b/engines/tsage/detection.cpp
index c8aa415914..f12efc02e8 100644
--- a/engines/tsage/detection.cpp
+++ b/engines/tsage/detection.cpp
@@ -30,7 +30,7 @@
#include "tsage/tsage.h"
-namespace tSage {
+namespace TsAGE {
struct tSageGameDescription {
ADGameDescription desc;
@@ -55,7 +55,7 @@ Common::String TSageEngine::getPrimaryFilename() const {
return Common::String(_gameDescription->desc.filesDescriptions[0].fileName);
}
-} // End of namespace tSage
+} // End of namespace TsAGE
static const PlainGameDescriptor tSageGameTitles[] = {
{ "tsage", "Unknown Tsunami TSAGE-based Game" },
@@ -72,7 +72,7 @@ enum {
class TSageMetaEngine : public AdvancedMetaEngine {
public:
- TSageMetaEngine() : AdvancedMetaEngine(tSage::gameDescriptions, sizeof(tSage::tSageGameDescription), tSageGameTitles) {
+ TSageMetaEngine() : AdvancedMetaEngine(TsAGE::gameDescriptions, sizeof(TsAGE::tSageGameDescription), tSageGameTitles) {
_md5Bytes = 5000;
_singleid = "tsage";
_guioptions = Common::GUIO_NOSPEECH;
@@ -103,7 +103,7 @@ public:
virtual bool createInstance(OSystem *syst, Engine **engine, const ADGameDescription *desc) const {
if (desc) {
- *engine = new tSage::TSageEngine(syst, (const tSage::tSageGameDescription *)desc);
+ *engine = new TsAGE::TSageEngine(syst, (const TsAGE::tSageGameDescription *)desc);
}
return desc != 0;
}
@@ -118,7 +118,7 @@ public:
Common::StringArray filenames = g_system->getSavefileManager()->listSavefiles(pattern);
sort(filenames.begin(), filenames.end());
- tSage::tSageSavegameHeader header;
+ TsAGE::tSageSavegameHeader header;
SaveStateList saveList;
for (Common::StringArray::const_iterator file = filenames.begin(); file != filenames.end(); ++file) {
@@ -129,7 +129,7 @@ public:
Common::InSaveFile *in = g_system->getSavefileManager()->openForLoading(*file);
if (in) {
- if (tSage::Saver::readSavegameHeader(in, header)) {
+ if (TsAGE::Saver::readSavegameHeader(in, header)) {
saveList.push_back(SaveStateDescriptor(slot, header.saveName));
delete header.thumbnail;
}
@@ -156,8 +156,8 @@ public:
generateGameStateFileName(target, slot));
assert(f);
- tSage::tSageSavegameHeader header;
- tSage::Saver::readSavegameHeader(f, header);
+ TsAGE::tSageSavegameHeader header;
+ TsAGE::Saver::readSavegameHeader(f, header);
delete f;
// Create the return descriptor
diff --git a/engines/tsage/detection_tables.h b/engines/tsage/detection_tables.h
index 7fbfa55c95..4b69549673 100644
--- a/engines/tsage/detection_tables.h
+++ b/engines/tsage/detection_tables.h
@@ -20,7 +20,7 @@
*
*/
-namespace tSage {
+namespace TsAGE {
static const tSageGameDescription gameDescriptions[] = {
@@ -32,7 +32,7 @@ static const tSageGameDescription gameDescriptions[] = {
AD_ENTRY1s("ring.rlb", "466f0e6492d9d0f34d35c5cd088de90f", 37847618),
Common::EN_ANY,
Common::kPlatformPC,
- ADGF_TESTING,
+ ADGF_TESTING | ADGF_CD,
Common::GUIO_NOSPEECH | Common::GUIO_NOSFX
},
GType_Ringworld,
@@ -46,7 +46,7 @@ static const tSageGameDescription gameDescriptions[] = {
AD_ENTRY1s("ring.rlb", "cb8bba91b30cd172712371d7123bd763", 7427980),
Common::ES_ESP,
Common::kPlatformPC,
- ADGF_TESTING,
+ ADGF_TESTING | ADGF_CD,
Common::GUIO_NOSPEECH | Common::GUIO_NOSFX
},
GType_Ringworld,
@@ -120,11 +120,11 @@ static const tSageGameDescription gameDescriptions[] = {
AD_ENTRY1s("blue.rlb", "17eabb456cb1546c66baf1aff387ba6a", 10032614),
Common::EN_ANY,
Common::kPlatformPC,
- ADGF_NO_FLAGS,
+ ADGF_UNSTABLE,
Common::GUIO_NOSPEECH | Common::GUIO_NOSFX
},
GType_BlueForce,
- GF_FLOPPY
+ GF_FLOPPY | GF_ALT_REGIONS
},
// Blue Force CD and First Wave use the same files
{
@@ -134,13 +134,13 @@ static const tSageGameDescription gameDescriptions[] = {
AD_ENTRY1s("blue.rlb", "99983f48cb218f1f3760cf2f9a7ef11d", 63863322),
Common::EN_ANY,
Common::kPlatformPC,
- ADGF_NO_FLAGS,
+ ADGF_CD | ADGF_UNSTABLE,
Common::GUIO_NOSPEECH | Common::GUIO_NOSFX
},
GType_BlueForce,
- GF_CD
+ GF_CD | GF_ALT_REGIONS
},
{ AD_TABLE_END_MARKER, 0, 0 }
};
-} // End of namespace tSage
+} // End of namespace TsAGE
diff --git a/engines/tsage/dialogs.cpp b/engines/tsage/dialogs.cpp
index d315ce092b..ae385b8c15 100644
--- a/engines/tsage/dialogs.cpp
+++ b/engines/tsage/dialogs.cpp
@@ -30,9 +30,9 @@
#include "tsage/dialogs.h"
#include "tsage/staticres.h"
#include "tsage/globals.h"
-#include "tsage/ringworld_logic.h"
+#include "tsage/ringworld/ringworld_logic.h"
-namespace tSage {
+namespace TsAGE {
/*--------------------------------------------------------------------------*/
@@ -595,4 +595,4 @@ OptionsDialog::OptionsDialog() {
}
-} // End of namespace tSage
+} // End of namespace TsAGE
diff --git a/engines/tsage/dialogs.h b/engines/tsage/dialogs.h
index a50307f775..55adb6c813 100644
--- a/engines/tsage/dialogs.h
+++ b/engines/tsage/dialogs.h
@@ -30,7 +30,7 @@
#include "common/rect.h"
#include "common/system.h"
-namespace tSage {
+namespace TsAGE {
class MessageDialog : public GfxDialog {
public:
@@ -128,6 +128,6 @@ public:
static void show();
};
-} // End of namespace tSage
+} // End of namespace TsAGE
#endif
diff --git a/engines/tsage/events.cpp b/engines/tsage/events.cpp
index 7aadf62b8d..44c79bd2fe 100644
--- a/engines/tsage/events.cpp
+++ b/engines/tsage/events.cpp
@@ -31,7 +31,7 @@
#include "tsage/tsage.h"
#include "tsage/globals.h"
-namespace tSage {
+namespace TsAGE {
EventsClass::EventsClass() {
_currentCursor = CURSOR_NONE;
@@ -155,7 +155,7 @@ void EventsClass::setCursor(CursorType cursorType) {
// No cursor
_globals->setFlag(122);
- if (_vm->getFeatures() & GF_DEMO) {
+ if ((_vm->getFeatures() & GF_DEMO) || (_vm->getGameID() == GType_BlueForce)) {
CursorMan.showMouse(false);
return;
}
@@ -325,4 +325,4 @@ void EventsClass::loadNotifierProc(bool postFlag) {
}
}
-} // end of namespace tSage
+} // end of namespace TsAGE
diff --git a/engines/tsage/events.h b/engines/tsage/events.h
index 772de24b5a..c36db59270 100644
--- a/engines/tsage/events.h
+++ b/engines/tsage/events.h
@@ -29,7 +29,7 @@
#include "graphics/surface.h"
#include "tsage/saveload.h"
-namespace tSage {
+namespace TsAGE {
enum EventType {EVENT_NONE = 0, EVENT_BUTTON_DOWN = 1, EVENT_BUTTON_UP = 2, EVENT_KEYPRESS = 4,
EVENT_MOUSE_MOVE = 8};
@@ -103,6 +103,6 @@ public:
static void loadNotifierProc(bool postFlag);
};
-} // End of namespace tSage
+} // End of namespace TsAGE
#endif
diff --git a/engines/tsage/globals.cpp b/engines/tsage/globals.cpp
index 34b26ec311..47c83fcc94 100644
--- a/engines/tsage/globals.cpp
+++ b/engines/tsage/globals.cpp
@@ -22,11 +22,11 @@
#include "tsage/globals.h"
#include "tsage/tsage.h"
-#include "tsage/blueforce_logic.h"
-#include "tsage/ringworld_demo.h"
-#include "tsage/ringworld_logic.h"
+#include "tsage/blue_force/blueforce_logic.h"
+#include "tsage/ringworld/ringworld_demo.h"
+#include "tsage/ringworld/ringworld_logic.h"
-namespace tSage {
+namespace TsAGE {
Globals *_globals = NULL;
ResourceManager *_resourceManager = NULL;
@@ -51,7 +51,7 @@ static SavedObject *classFactoryProc(const Common::String &className) {
/*--------------------------------------------------------------------------*/
Globals::Globals() : _dialogCenter(160, 140), _gfxManagerInstance(_screenSurface),
- _randomSource("tsage"), _unkColor1(0), _unkColor2(255), _unkColor3(255) {
+ _randomSource("tsage"), _color1(0), _color2(255), _color3(255) {
reset();
_stripNum = 0;
_gfxEdgeAdjust = 3;
@@ -64,18 +64,26 @@ Globals::Globals() : _dialogCenter(160, 140), _gfxManagerInstance(_screenSurface
_fontColors.foreground = 6;
_dialogCenter.y = 80;
// Workaround in order to use later version of the engine
- _unkColor1 = _gfxColors.foreground;
- _unkColor2 = _gfxColors.foreground;
- _unkColor3 = _gfxColors.foreground;
+ _color1 = _gfxColors.foreground;
+ _color2 = _gfxColors.foreground;
+ _color3 = _gfxColors.foreground;
+ } else if (_vm->getGameID() == GType_BlueForce) {
+ // Blue Force
+ _gfxFontNumber = 0;
+ _gfxColors.background = 89;
+ _gfxColors.foreground = 83;
+ _fontColors.background = 88;
+ _fontColors.foreground = 92;
+ _dialogCenter.y = 165;
} else if ((_vm->getGameID() == GType_Ringworld) && (_vm->getFeatures() & GF_CD)) {
_gfxFontNumber = 50;
_gfxColors.background = 53;
_gfxColors.foreground = 0;
_fontColors.background = 51;
_fontColors.foreground = 54;
- _unkColor1 = 18;
- _unkColor2 = 18;
- _unkColor3 = 18;
+ _color1 = 18;
+ _color2 = 18;
+ _color3 = 18;
} else {
_gfxFontNumber = 50;
_gfxColors.background = 53;
@@ -83,9 +91,9 @@ Globals::Globals() : _dialogCenter(160, 140), _gfxManagerInstance(_screenSurface
_fontColors.background = 51;
_fontColors.foreground = 54;
// Workaround in order to use later version of the engine
- _unkColor1 = _gfxColors.foreground;
- _unkColor2 = _gfxColors.foreground;
- _unkColor3 = _gfxColors.foreground;
+ _color1 = _gfxColors.foreground;
+ _color2 = _gfxColors.foreground;
+ _color3 = _gfxColors.foreground;
}
_screenSurface.setScreenSurface();
_gfxManagers.push_back(&_gfxManagerInstance);
@@ -103,20 +111,21 @@ Globals::Globals() : _dialogCenter(160, 140), _gfxManagerInstance(_screenSurface
switch (_vm->getGameID()) {
case GType_Ringworld:
if (!(_vm->getFeatures() & GF_DEMO)) {
- _inventory = new RingworldInvObjectList();
- _game = new RingworldGame();
+ _inventory = new Ringworld::RingworldInvObjectList();
+ _game = new Ringworld::RingworldGame();
} else {
- _game = new RingworldDemoGame();
+ _game = new Ringworld::RingworldDemoGame();
}
break;
case GType_BlueForce:
- _game = new BlueForceGame();
+ _game = new BlueForce::BlueForceGame();
break;
}
}
Globals::~Globals() {
+ _scenePalette.clearListeners();
delete _inventory;
delete _game;
_globals = NULL;
@@ -142,9 +151,9 @@ void Globals::synchronize(Serializer &s) {
s.syncAsSint32LE(_fontColors.foreground);
if (s.getVersion() >= 4) {
- s.syncAsByte(_unkColor1);
- s.syncAsByte(_unkColor2);
- s.syncAsByte(_unkColor3);
+ s.syncAsByte(_color1);
+ s.syncAsByte(_color2);
+ s.syncAsByte(_color3);
}
s.syncAsSint16LE(_dialogCenter.x); s.syncAsSint16LE(_dialogCenter.y);
@@ -166,5 +175,21 @@ void Globals::dispatchSounds() {
Common::for_each(_sounds.begin(), _sounds.end(), Globals::dispatchSound);
}
+/*--------------------------------------------------------------------------*/
+
+namespace BlueForce {
+
+BlueForceGlobals::BlueForceGlobals(): Globals() {
+ _interfaceY = 0;
+ _v51C44 = 1;
+ _v4CEA2 = 0;
+}
+
+void BlueForceGlobals::synchronize(Serializer &s) {
+ Globals::synchronize(s);
+ error("Sync variables");
+}
+
+} // end of namespace BlueForce
-} // end of namespace tSage
+} // end of namespace TsAGE
diff --git a/engines/tsage/globals.h b/engines/tsage/globals.h
index 7cfec718e2..c8cfc1c323 100644
--- a/engines/tsage/globals.h
+++ b/engines/tsage/globals.h
@@ -31,7 +31,7 @@
#include "tsage/sound.h"
#include "tsage/saveload.h"
-namespace tSage {
+namespace TsAGE {
class Globals : public SavedObject {
private:
@@ -54,7 +54,7 @@ public:
int _gfxFontNumber;
GfxColors _gfxColors;
GfxColors _fontColors;
- byte _unkColor1, _unkColor2, _unkColor3;
+ byte _color1, _color2, _color3;
SoundManager _soundManager;
Common::Point _dialogCenter;
WalkRegions _walkRegions;
@@ -98,10 +98,36 @@ public:
extern Globals *_globals;
+#define GLOBALS (*_globals)
+#define BF_GLOBALS (*((::TsAGE::BlueForce::BlueForceGlobals *)_globals))
+
// Note: Currently this can't be part of the _globals structure, since it needs to be constructed
// prior to many of the fields in Globals execute their constructors
extern ResourceManager *_resourceManager;
-} // End of namespace tSage
+
+namespace BlueForce {
+
+using namespace TsAGE;
+
+class BlueForceGlobals: public Globals {
+public:
+ ASound _sound1, _sound2, _sound3;
+ int _v4CEA2;
+ int _v4CF9E;
+ int _v4E238;
+ int _v501FC;
+ int _v51C42;
+ int _v51C44;
+ int _interfaceY;
+
+ BlueForceGlobals();
+ virtual Common::String getClassName() { return "BFGlobals"; }
+ virtual void synchronize(Serializer &s);
+};
+
+} // End of namespace BlueForce
+
+} // End of namespace TsAGE
#endif
diff --git a/engines/tsage/graphics.cpp b/engines/tsage/graphics.cpp
index 87ffdf4494..1884bfb4f5 100644
--- a/engines/tsage/graphics.cpp
+++ b/engines/tsage/graphics.cpp
@@ -30,7 +30,7 @@
#include "graphics/surface.h"
#include "tsage/globals.h"
-namespace tSage {
+namespace TsAGE {
/**
* Creates a new graphics surface with the specified area of another surface
@@ -626,9 +626,9 @@ void GfxElement::setDefaults() {
_fontNumber = _globals->_gfxFontNumber;
_colors = _globals->_gfxColors;
_fontColors = _globals->_fontColors;
- _unkColor1 = _globals->_unkColor1;
- _unkColor2 = _globals->_unkColor2;
- _unkColor3 = _globals->_unkColor3;
+ _color1 = _globals->_color1;
+ _color2 = _globals->_color2;
+ _color3 = _globals->_color3;
}
/**
@@ -824,9 +824,9 @@ void GfxMessage::draw() {
gfxManager.setFillFlag(false);
gfxManager._font.setFontNumber(_fontNumber);
- gfxManager._font._colors.foreground = this->_unkColor1;
- gfxManager._font._colors2.background = this->_unkColor2;
- gfxManager._font._colors2.foreground = this->_unkColor3;
+ gfxManager._font._colors.foreground = this->_color1;
+ gfxManager._font._colors2.background = this->_color2;
+ gfxManager._font._colors2.foreground = this->_color3;
// Display the text
gfxManager._font.writeLines(_message.c_str(), _bounds, _textAlign);
@@ -867,9 +867,9 @@ void GfxButton::draw() {
gfxManager._font.setFontNumber(_fontNumber);
//
- gfxManager._font._colors.foreground = this->_unkColor1;
- gfxManager._font._colors2.background = this->_unkColor2;
- gfxManager._font._colors2.foreground = this->_unkColor3;
+ gfxManager._font._colors.foreground = this->_color1;
+ gfxManager._font._colors2.background = this->_color2;
+ gfxManager._font._colors2.foreground = this->_color3;
// Display the button's text
Rect tempRect(_bounds);
@@ -1512,4 +1512,4 @@ GfxFontBackup::~GfxFontBackup() {
}
-} // End of namespace tSage
+} // End of namespace TsAGE
diff --git a/engines/tsage/graphics.h b/engines/tsage/graphics.h
index e09e1093a3..06b482d7b5 100644
--- a/engines/tsage/graphics.h
+++ b/engines/tsage/graphics.h
@@ -30,7 +30,7 @@
#include "common/system.h"
#include "graphics/surface.h"
-namespace tSage {
+namespace TsAGE {
class GfxSurface;
class Region;
@@ -177,7 +177,7 @@ public:
uint16 _fontNumber;
GfxColors _colors;
GfxColors _fontColors;
- byte _unkColor1, _unkColor2, _unkColor3;
+ byte _color1, _color2, _color3;
uint16 _keycode;
public:
GfxElement();
@@ -343,6 +343,6 @@ GfxSurface *Surface_getArea(GfxSurface &src, const Rect &bounds);
GfxSurface surfaceFromRes(const byte *imgData);
GfxSurface surfaceFromRes(int resNum, int rlbNum, int subNum);
-} // End of namespace tSage
+} // End of namespace TsAGE
#endif
diff --git a/engines/tsage/module.mk b/engines/tsage/module.mk
index 586699593d..5c7104936e 100644
--- a/engines/tsage/module.mk
+++ b/engines/tsage/module.mk
@@ -1,8 +1,9 @@
MODULE := engines/tsage
MODULE_OBJS := \
- blueforce_logic.o \
- blueforce_scenes0.o \
+ blue_force/blueforce_logic.o \
+ blue_force/blueforce_scenes0.o \
+ blue_force/blueforce_scenes1.o \
converse.o \
core.o \
debugger.o \
@@ -12,16 +13,16 @@ MODULE_OBJS := \
globals.o \
graphics.o \
resources.o \
- ringworld_demo.o \
- ringworld_logic.o \
- ringworld_scenes1.o \
- ringworld_scenes2.o \
- ringworld_scenes3.o \
- ringworld_scenes4.o \
- ringworld_scenes5.o \
- ringworld_scenes6.o \
- ringworld_scenes8.o \
- ringworld_scenes10.o \
+ ringworld/ringworld_demo.o \
+ ringworld/ringworld_logic.o \
+ ringworld/ringworld_scenes1.o \
+ ringworld/ringworld_scenes2.o \
+ ringworld/ringworld_scenes3.o \
+ ringworld/ringworld_scenes4.o \
+ ringworld/ringworld_scenes5.o \
+ ringworld/ringworld_scenes6.o \
+ ringworld/ringworld_scenes8.o \
+ ringworld/ringworld_scenes10.o \
saveload.o \
scenes.o \
sound.o \
diff --git a/engines/tsage/resources.cpp b/engines/tsage/resources.cpp
index 6d2c6b5837..99b431b5dc 100644
--- a/engines/tsage/resources.cpp
+++ b/engines/tsage/resources.cpp
@@ -28,7 +28,7 @@
#include "tsage/resources.h"
#include "tsage/tsage.h"
-namespace tSage {
+namespace TsAGE {
MemoryManager::MemoryManager() {
@@ -504,4 +504,4 @@ Common::String ResourceManager::getMessage(int resNum, int lineNum, bool suppres
return result;
}
-} // end of namespace tSage
+} // end of namespace TsAGE
diff --git a/engines/tsage/resources.h b/engines/tsage/resources.h
index efbb86b24e..176d60fcc4 100644
--- a/engines/tsage/resources.h
+++ b/engines/tsage/resources.h
@@ -33,7 +33,7 @@
#include "common/util.h"
#include "graphics/surface.h"
-namespace tSage {
+namespace TsAGE {
// Magic number used by original game to identify valid memory blocks
const uint32 MEMORY_ENTRY_ID = 0xE11DA722;
@@ -175,6 +175,6 @@ public:
};
-} // end of namespace tSage
+} // end of namespace TsAGE
#endif
diff --git a/engines/tsage/ringworld_demo.cpp b/engines/tsage/ringworld/ringworld_demo.cpp
index b24fec98f9..5612325aff 100644
--- a/engines/tsage/ringworld_demo.cpp
+++ b/engines/tsage/ringworld/ringworld_demo.cpp
@@ -20,12 +20,14 @@
*
*/
-#include "tsage/ringworld_demo.h"
+#include "tsage/ringworld/ringworld_demo.h"
#include "tsage/scenes.h"
#include "tsage/tsage.h"
#include "tsage/staticres.h"
-namespace tSage {
+namespace TsAGE {
+
+namespace Ringworld {
void RingworldDemoGame::start() {
// Start the demo's single scene
@@ -117,4 +119,6 @@ void RingworldDemoScene::process(Event &event) {
}
-} // End of namespace tSage
+} // End of namespace Ringworld
+
+} // End of namespace TsAGE
diff --git a/engines/tsage/ringworld_demo.h b/engines/tsage/ringworld/ringworld_demo.h
index 3e7431e107..30527b0aea 100644
--- a/engines/tsage/ringworld_demo.h
+++ b/engines/tsage/ringworld/ringworld_demo.h
@@ -30,7 +30,11 @@
#include "tsage/globals.h"
#include "tsage/sound.h"
-namespace tSage {
+namespace TsAGE {
+
+namespace Ringworld {
+
+using namespace TsAGE;
class RingworldDemoGame: public Game {
private:
@@ -54,6 +58,8 @@ public:
virtual void signal();
};
-} // End of namespace tSage
+} // End of namespace Ringworld
+
+} // End of namespace TsAGE
#endif
diff --git a/engines/tsage/ringworld_logic.cpp b/engines/tsage/ringworld/ringworld_logic.cpp
index 070d8afd25..d6e72fe95c 100644
--- a/engines/tsage/ringworld_logic.cpp
+++ b/engines/tsage/ringworld/ringworld_logic.cpp
@@ -23,21 +23,23 @@
#include "common/config-manager.h"
#include "common/translation.h"
#include "gui/saveload.h"
-#include "tsage/ringworld_logic.h"
+#include "tsage/ringworld/ringworld_logic.h"
#include "tsage/scenes.h"
#include "tsage/tsage.h"
#include "tsage/staticres.h"
-#include "tsage/ringworld_demo.h"
-#include "tsage/ringworld_scenes1.h"
-#include "tsage/ringworld_scenes2.h"
-#include "tsage/ringworld_scenes3.h"
-#include "tsage/ringworld_scenes4.h"
-#include "tsage/ringworld_scenes5.h"
-#include "tsage/ringworld_scenes6.h"
-#include "tsage/ringworld_scenes8.h"
-#include "tsage/ringworld_scenes10.h"
-
-namespace tSage {
+#include "tsage/ringworld/ringworld_demo.h"
+#include "tsage/ringworld/ringworld_scenes1.h"
+#include "tsage/ringworld/ringworld_scenes2.h"
+#include "tsage/ringworld/ringworld_scenes3.h"
+#include "tsage/ringworld/ringworld_scenes4.h"
+#include "tsage/ringworld/ringworld_scenes5.h"
+#include "tsage/ringworld/ringworld_scenes6.h"
+#include "tsage/ringworld/ringworld_scenes8.h"
+#include "tsage/ringworld/ringworld_scenes10.h"
+
+namespace TsAGE {
+
+namespace Ringworld {
Scene *RingworldGame::createScene(int sceneNumber) {
switch (sceneNumber) {
@@ -1487,4 +1489,6 @@ void RingworldGame::processEvent(Event &event) {
}
}
-} // End of namespace tSage
+} // End of namespace Ringworld
+
+} // End of namespace TsAGE
diff --git a/engines/tsage/ringworld_logic.h b/engines/tsage/ringworld/ringworld_logic.h
index 19b0f10b42..73ecc9722b 100644
--- a/engines/tsage/ringworld_logic.h
+++ b/engines/tsage/ringworld/ringworld_logic.h
@@ -29,7 +29,11 @@
#include "tsage/scenes.h"
#include "tsage/globals.h"
-namespace tSage {
+namespace TsAGE {
+
+namespace Ringworld {
+
+using namespace TsAGE;
#define ADD_PLAYER_MOVER(X, Y) { Common::Point pt(X, Y); PlayerMover *mover = new PlayerMover(); \
_globals->_player.addMover(mover, &pt, this); }
@@ -438,7 +442,7 @@ public:
virtual Common::String getClassName() { return "RingworldInvObjectList"; }
};
-#define RING_INVENTORY (*((RingworldInvObjectList *)_globals->_inventory))
+#define RING_INVENTORY (*((::TsAGE::Ringworld::RingworldInvObjectList *)_globals->_inventory))
class RingworldGame: public Game {
protected:
@@ -456,6 +460,8 @@ public:
virtual void processEvent(Event &event);
};
-} // End of namespace tSage
+} // End of namespace Ringworld
+
+} // End of namespace TsAGE
#endif
diff --git a/engines/tsage/ringworld_scenes1.cpp b/engines/tsage/ringworld/ringworld_scenes1.cpp
index f97cfa4ae6..332aef6d8d 100644
--- a/engines/tsage/ringworld_scenes1.cpp
+++ b/engines/tsage/ringworld/ringworld_scenes1.cpp
@@ -20,12 +20,14 @@
*
*/
-#include "tsage/ringworld_scenes1.h"
+#include "tsage/ringworld/ringworld_scenes1.h"
#include "tsage/scenes.h"
#include "tsage/tsage.h"
#include "tsage/staticres.h"
-namespace tSage {
+namespace TsAGE {
+
+namespace Ringworld {
/*--------------------------------------------------------------------------
* Scene 10 - Kziniti Palace (Introduction)
@@ -3342,4 +3344,6 @@ void Scene6100::showMessage(const Common::String &msg, int color, Action *action
}
}
-} // End of namespace tSage
+} // End of namespace Ringworld
+
+} // End of namespace TsAGE
diff --git a/engines/tsage/ringworld_scenes1.h b/engines/tsage/ringworld/ringworld_scenes1.h
index 0f9bf61117..49ea65eb3a 100644
--- a/engines/tsage/ringworld_scenes1.h
+++ b/engines/tsage/ringworld/ringworld_scenes1.h
@@ -24,7 +24,7 @@
#define TSAGE_RINGWORLD_SCENES1_H
#include "common/scummsys.h"
-#include "tsage/ringworld_logic.h"
+#include "tsage/ringworld/ringworld_logic.h"
#include "tsage/converse.h"
#include "tsage/events.h"
#include "tsage/core.h"
@@ -32,7 +32,11 @@
#include "tsage/globals.h"
#include "tsage/sound.h"
-namespace tSage {
+namespace TsAGE {
+
+namespace Ringworld {
+
+using namespace TsAGE;
class Scene10 : public Scene {
/* Actions */
@@ -533,6 +537,8 @@ public:
};
-} // End of namespace tSage
+} // End of namespace Ringworld
+
+} // End of namespace TsAGE
#endif
diff --git a/engines/tsage/ringworld_scenes10.cpp b/engines/tsage/ringworld/ringworld_scenes10.cpp
index 839fa0f008..df25c324ab 100644
--- a/engines/tsage/ringworld_scenes10.cpp
+++ b/engines/tsage/ringworld/ringworld_scenes10.cpp
@@ -21,12 +21,14 @@
*/
#include "graphics/cursorman.h"
-#include "tsage/ringworld_scenes10.h"
+#include "tsage/ringworld/ringworld_scenes10.h"
#include "tsage/scenes.h"
#include "tsage/tsage.h"
#include "tsage/staticres.h"
-namespace tSage {
+namespace TsAGE {
+
+namespace Ringworld {
Scene2::Scene2() : Scene() {
_sceneState = 0;
@@ -2086,4 +2088,6 @@ void Scene9999::postInit(SceneObjectList *OwnerList) {
}
-} // End of namespace tSage
+} // End of namespace Ringworld
+
+} // End of namespace TsAGE
diff --git a/engines/tsage/ringworld_scenes10.h b/engines/tsage/ringworld/ringworld_scenes10.h
index 33b16d0014..02c42f3d01 100644
--- a/engines/tsage/ringworld_scenes10.h
+++ b/engines/tsage/ringworld/ringworld_scenes10.h
@@ -24,13 +24,17 @@
#define TSAGE_RINGWORLD_SCENES10_H
#include "common/scummsys.h"
-#include "tsage/ringworld_logic.h"
+#include "tsage/ringworld/ringworld_logic.h"
#include "tsage/events.h"
#include "tsage/core.h"
#include "tsage/scenes.h"
#include "tsage/globals.h"
-namespace tSage {
+namespace TsAGE {
+
+namespace Ringworld {
+
+using namespace TsAGE;
class SceneObject9150 : public SceneObject {
public:
@@ -526,7 +530,8 @@ public:
virtual void postInit(SceneObjectList *OwnerList = NULL);
};
+} // End of namespace Ringworld
-} // End of namespace tSage
+} // End of namespace TsAGE
#endif
diff --git a/engines/tsage/ringworld_scenes2.cpp b/engines/tsage/ringworld/ringworld_scenes2.cpp
index 0154123c3d..cfd3e3d8f7 100644
--- a/engines/tsage/ringworld_scenes2.cpp
+++ b/engines/tsage/ringworld/ringworld_scenes2.cpp
@@ -21,12 +21,14 @@
*/
#include "common/config-manager.h"
-#include "tsage/ringworld_scenes2.h"
+#include "tsage/ringworld/ringworld_scenes2.h"
#include "tsage/scenes.h"
#include "tsage/tsage.h"
#include "tsage/staticres.h"
-namespace tSage {
+namespace TsAGE {
+
+namespace Ringworld {
/*--------------------------------------------------------------------------
* Scene 1000 - Title Screen
@@ -925,4 +927,6 @@ void Scene1500::postInit(SceneObjectList *OwnerList) {
}
}
-} // End of namespace tSage
+} // End of namespace Ringworld
+
+} // End of namespace TsAGE
diff --git a/engines/tsage/ringworld_scenes2.h b/engines/tsage/ringworld/ringworld_scenes2.h
index 93a8f04fd4..3502aea15b 100644
--- a/engines/tsage/ringworld_scenes2.h
+++ b/engines/tsage/ringworld/ringworld_scenes2.h
@@ -24,13 +24,17 @@
#define TSAGE_RINGWORLD_SCENES2_H
#include "common/scummsys.h"
-#include "tsage/ringworld_logic.h"
+#include "tsage/ringworld/ringworld_logic.h"
#include "tsage/events.h"
#include "tsage/core.h"
#include "tsage/scenes.h"
#include "tsage/globals.h"
-namespace tSage {
+namespace TsAGE {
+
+namespace Ringworld {
+
+using namespace TsAGE;
class Scene1000 : public Scene {
/* Actions */
@@ -142,8 +146,8 @@ public:
virtual void postInit(SceneObjectList *OwnerList = NULL);
};
+} // End of namespace Ringworld
-
-} // End of namespace tSage
+} // End of namespace TsAGE
#endif
diff --git a/engines/tsage/ringworld_scenes3.cpp b/engines/tsage/ringworld/ringworld_scenes3.cpp
index 209144766a..f744a98c33 100644
--- a/engines/tsage/ringworld_scenes3.cpp
+++ b/engines/tsage/ringworld/ringworld_scenes3.cpp
@@ -21,12 +21,14 @@
*/
#include "common/config-manager.h"
-#include "tsage/ringworld_scenes3.h"
+#include "tsage/ringworld/ringworld_scenes3.h"
#include "tsage/scenes.h"
#include "tsage/tsage.h"
#include "tsage/staticres.h"
-namespace tSage {
+namespace TsAGE {
+
+namespace Ringworld {
/*--------------------------------------------------------------------------
* Scene 2000 - Cockpit cutscenes
@@ -6130,4 +6132,6 @@ void Scene2400::postInit(SceneObjectList *OwnerList) {
_globals->_soundHandler.play(153);
}
-} // End of namespace tSage
+} // End of namespace Ringworld
+
+} // End of namespace TsAGE
diff --git a/engines/tsage/ringworld_scenes3.h b/engines/tsage/ringworld/ringworld_scenes3.h
index 711360c190..2dbdc27211 100644
--- a/engines/tsage/ringworld_scenes3.h
+++ b/engines/tsage/ringworld/ringworld_scenes3.h
@@ -26,9 +26,13 @@
#include "common/scummsys.h"
#include "tsage/core.h"
#include "tsage/converse.h"
-#include "tsage/ringworld_logic.h"
+#include "tsage/ringworld/ringworld_logic.h"
-namespace tSage {
+namespace TsAGE {
+
+namespace Ringworld {
+
+using namespace TsAGE;
class Scene2000 : public Scene {
/* Actions */
@@ -890,6 +894,8 @@ public:
virtual void postInit(SceneObjectList *OwnerList = NULL);
};
-} // End of namespace tSage
+} // End of namespace Ringworld
+
+} // End of namespace TsAGE
#endif
diff --git a/engines/tsage/ringworld_scenes4.cpp b/engines/tsage/ringworld/ringworld_scenes4.cpp
index 838769e4af..0f4c3e49a0 100644
--- a/engines/tsage/ringworld_scenes4.cpp
+++ b/engines/tsage/ringworld/ringworld_scenes4.cpp
@@ -21,12 +21,14 @@
*/
#include "common/config-manager.h"
-#include "tsage/ringworld_scenes4.h"
+#include "tsage/ringworld/ringworld_scenes4.h"
#include "tsage/scenes.h"
#include "tsage/tsage.h"
#include "tsage/staticres.h"
-namespace tSage {
+namespace TsAGE {
+
+namespace Ringworld {
/*--------------------------------------------------------------------------
* Scene 3500 - Ringworld Scan
@@ -227,7 +229,7 @@ void Scene3700::Action1::signal() {
/*--------------------------------------------------------------------------*/
-void Scene3700::postInit(tSage::SceneObjectList *OwnerList) {
+void Scene3700::postInit(TsAGE::SceneObjectList *OwnerList) {
Scene::postInit();
loadScene(3700);
@@ -247,4 +249,6 @@ void Scene3700::postInit(tSage::SceneObjectList *OwnerList) {
_globals->_soundHandler.play(195);
}
-} // End of namespace tSage
+} // End of namespace Ringworld
+
+} // End of namespace TsAGE
diff --git a/engines/tsage/ringworld_scenes4.h b/engines/tsage/ringworld/ringworld_scenes4.h
index 0b575d02d3..af31de84b9 100644
--- a/engines/tsage/ringworld_scenes4.h
+++ b/engines/tsage/ringworld/ringworld_scenes4.h
@@ -26,9 +26,13 @@
#include "common/scummsys.h"
#include "tsage/core.h"
#include "tsage/converse.h"
-#include "tsage/ringworld_logic.h"
+#include "tsage/ringworld/ringworld_logic.h"
-namespace tSage {
+namespace TsAGE {
+
+namespace Ringworld {
+
+using namespace TsAGE;
class Scene3500 : public Scene {
/* Actions */
@@ -87,6 +91,8 @@ public:
virtual void postInit(SceneObjectList *OwnerList = NULL);
};
-} // End of namespace tSage
+} // End of namespace Ringworld
+
+} // End of namespace TsAGE
#endif
diff --git a/engines/tsage/ringworld_scenes5.cpp b/engines/tsage/ringworld/ringworld_scenes5.cpp
index fccc7e1b50..58f47d7f82 100644
--- a/engines/tsage/ringworld_scenes5.cpp
+++ b/engines/tsage/ringworld/ringworld_scenes5.cpp
@@ -21,12 +21,14 @@
*/
#include "common/config-manager.h"
-#include "tsage/ringworld_scenes5.h"
+#include "tsage/ringworld/ringworld_scenes5.h"
#include "tsage/scenes.h"
#include "tsage/tsage.h"
#include "tsage/staticres.h"
-namespace tSage {
+namespace TsAGE {
+
+namespace Ringworld {
/*--------------------------------------------------------------------------
* Scene 4000 - Village
@@ -3520,7 +3522,7 @@ Scene4250::Scene4250() :
_hotspot7(0, CURSOR_LOOK, 4250, 0, LIST_END) {
}
-void Scene4250::postInit(tSage::SceneObjectList *OwnerList) {
+void Scene4250::postInit(TsAGE::SceneObjectList *OwnerList) {
loadScene(4250);
Scene::postInit();
setZoomPercents(160, 90, 185, 100);
@@ -4438,4 +4440,6 @@ void Scene4301::dispatch() {
}
}
-} // End of namespace tSage
+} // End of namespace Ringworld
+
+} // End of namespace TsAGE
diff --git a/engines/tsage/ringworld_scenes5.h b/engines/tsage/ringworld/ringworld_scenes5.h
index c3ae9f4aa9..6c6b6b6f32 100644
--- a/engines/tsage/ringworld_scenes5.h
+++ b/engines/tsage/ringworld/ringworld_scenes5.h
@@ -26,9 +26,13 @@
#include "common/scummsys.h"
#include "tsage/core.h"
#include "tsage/converse.h"
-#include "tsage/ringworld_logic.h"
+#include "tsage/ringworld/ringworld_logic.h"
-namespace tSage {
+namespace TsAGE {
+
+namespace Ringworld {
+
+using namespace TsAGE;
class Scene4000 : public Scene {
/* Actions */
@@ -687,7 +691,8 @@ public:
}
};
+} // End of namespace Ringworld
-} // End of namespace tSage
+} // End of namespace TsAGE
#endif
diff --git a/engines/tsage/ringworld_scenes6.cpp b/engines/tsage/ringworld/ringworld_scenes6.cpp
index 68c184196c..f21ae59478 100644
--- a/engines/tsage/ringworld_scenes6.cpp
+++ b/engines/tsage/ringworld/ringworld_scenes6.cpp
@@ -20,12 +20,14 @@
*
*/
-#include "tsage/ringworld_scenes6.h"
+#include "tsage/ringworld/ringworld_scenes6.h"
#include "tsage/scenes.h"
#include "tsage/tsage.h"
#include "tsage/staticres.h"
-namespace tSage {
+namespace TsAGE {
+
+namespace Ringworld {
/*--------------------------------------------------------------------------
* Scene 5000 - Caverns - Entrance
@@ -2196,5 +2198,6 @@ void Scene5300::signal() {
}
}
+} // End of namespace Ringworld
-} // End of namespace tSage
+} // End of namespace TsAGE
diff --git a/engines/tsage/ringworld_scenes6.h b/engines/tsage/ringworld/ringworld_scenes6.h
index 2e99f5ab87..79e604a177 100644
--- a/engines/tsage/ringworld_scenes6.h
+++ b/engines/tsage/ringworld/ringworld_scenes6.h
@@ -24,13 +24,17 @@
#define TSAGE_RINGWORLD_SCENES6_H
#include "common/scummsys.h"
-#include "tsage/ringworld_logic.h"
+#include "tsage/ringworld/ringworld_logic.h"
#include "tsage/events.h"
#include "tsage/core.h"
#include "tsage/scenes.h"
#include "tsage/globals.h"
-namespace tSage {
+namespace TsAGE {
+
+namespace Ringworld {
+
+using namespace TsAGE;
class Scene5000 : public Scene {
/* Actions */
@@ -324,7 +328,8 @@ public:
}
};
+} // End of namespace Ringworld
-} // End of namespace tSage
+} // End of namespace TsAGE
#endif
diff --git a/engines/tsage/ringworld_scenes8.cpp b/engines/tsage/ringworld/ringworld_scenes8.cpp
index d0e7491d4a..5f1ff5cdca 100644
--- a/engines/tsage/ringworld_scenes8.cpp
+++ b/engines/tsage/ringworld/ringworld_scenes8.cpp
@@ -21,12 +21,14 @@
*/
#include "graphics/cursorman.h"
-#include "tsage/ringworld_scenes8.h"
+#include "tsage/ringworld/ringworld_scenes8.h"
#include "tsage/scenes.h"
#include "tsage/tsage.h"
#include "tsage/staticres.h"
-namespace tSage {
+namespace TsAGE {
+
+namespace Ringworld {
void NamedHotspotMult::synchronize(Serializer &s) {
SceneHotspot::synchronize(s);
@@ -2542,4 +2544,6 @@ void Scene7700::synchronize(Serializer &s) {
}
}
-} // End of namespace tSage
+} // End of namespace Ringworld
+
+} // End of namespace TsAGE
diff --git a/engines/tsage/ringworld_scenes8.h b/engines/tsage/ringworld/ringworld_scenes8.h
index fe9560d9d8..4878db5cc8 100644
--- a/engines/tsage/ringworld_scenes8.h
+++ b/engines/tsage/ringworld/ringworld_scenes8.h
@@ -24,13 +24,17 @@
#define TSAGE_RINGWORLD_SCENES8_H
#include "common/scummsys.h"
-#include "tsage/ringworld_logic.h"
+#include "tsage/ringworld/ringworld_logic.h"
#include "tsage/events.h"
#include "tsage/core.h"
#include "tsage/scenes.h"
#include "tsage/globals.h"
-namespace tSage {
+namespace TsAGE {
+
+namespace Ringworld {
+
+using namespace TsAGE;
class NamedHotspotMult : public SceneHotspot {
public:
@@ -485,6 +489,8 @@ public:
virtual void synchronize(Serializer &s);
};
-} // End of namespace tSage
+} // End of namespace Ringworld
+
+} // End of namespace TsAGE
#endif
diff --git a/engines/tsage/saveload.cpp b/engines/tsage/saveload.cpp
index e07964d443..45e655037d 100644
--- a/engines/tsage/saveload.cpp
+++ b/engines/tsage/saveload.cpp
@@ -30,7 +30,7 @@
#include "tsage/sound.h"
#include "tsage/tsage.h"
-namespace tSage {
+namespace TsAGE {
Saver *_saver;
@@ -410,4 +410,4 @@ void Saver::resolveLoadPointers() {
error("Could not resolve savegame block pointers");
}
-} // End of namespace tSage
+} // End of namespace TsAGE
diff --git a/engines/tsage/saveload.h b/engines/tsage/saveload.h
index ce181cbc8f..03beafed7c 100644
--- a/engines/tsage/saveload.h
+++ b/engines/tsage/saveload.h
@@ -29,7 +29,7 @@
#include "common/savefile.h"
#include "common/serializer.h"
-namespace tSage {
+namespace TsAGE {
typedef void (*SaveNotifierFn)(bool postFlag);
@@ -222,6 +222,6 @@ public:
extern Saver *_saver;
-} // End of namespace tSage
+} // End of namespace TsAGE
#endif
diff --git a/engines/tsage/scenes.cpp b/engines/tsage/scenes.cpp
index 9a175ea08f..53e48a1d21 100644
--- a/engines/tsage/scenes.cpp
+++ b/engines/tsage/scenes.cpp
@@ -22,14 +22,11 @@
#include "tsage/scenes.h"
#include "tsage/globals.h"
-#include "tsage/ringworld_logic.h"
+#include "tsage/ringworld/ringworld_logic.h"
#include "tsage/tsage.h"
#include "tsage/saveload.h"
-namespace tSage {
-
-// TODO: Doesn't seem to be ever set
-const bool _v52C9F = false;
+namespace TsAGE {
SceneManager::SceneManager() {
_scene = NULL;
@@ -427,6 +424,11 @@ void Scene::refreshBackground(int xAmount, int yAmount) {
(xSectionSrc + 1) * 160, (ySectionSrc + 1) * 100);
Rect destBounds(xSectionDest * 160, ySectionDest * 100,
(xSectionDest + 1) * 160, (ySectionDest + 1) * 100);
+ if (_vm->getGameID() == GType_BlueForce) {
+ // For Blue Force, if the scene has an interface area, exclude it from the copy
+ srcBounds.bottom = MIN<int16>(srcBounds.bottom, BF_GLOBALS._interfaceY);
+ destBounds.bottom = MIN<int16>(destBounds.bottom, BF_GLOBALS._interfaceY);
+ }
_backSurface.copyFrom(_backSurface, srcBounds, destBounds);
}
@@ -504,11 +506,6 @@ void Scene::setZoomPercents(int yStart, int minPercent, int yEnd, int maxPercent
_zoomPercents[yEnd++] = minPercent;
}
-byte *Scene::preloadVisage(int resNum) {
- assert(!_v52C9F);
- return _resourceManager->getResource(RES_VISAGE, resNum, 9999, false);
-}
-
/*--------------------------------------------------------------------------*/
void Game::execute() {
@@ -527,4 +524,4 @@ void Game::execute() {
} while (activeFlag && !_vm->shouldQuit());
}
-} // End of namespace tSage
+} // End of namespace TsAGE
diff --git a/engines/tsage/scenes.h b/engines/tsage/scenes.h
index 665da585f8..7e8c26f912 100644
--- a/engines/tsage/scenes.h
+++ b/engines/tsage/scenes.h
@@ -29,7 +29,7 @@
#include "tsage/core.h"
#include "tsage/saveload.h"
-namespace tSage {
+namespace TsAGE {
class Scene : public StripCallback {
private:
@@ -67,7 +67,6 @@ public:
void loadBackground(int xAmount, int yAmount);
void refreshBackground(int xAmount, int yAmount);
void loadSceneData(int sceneNum);
- byte *preloadVisage(int resNum);
};
class SceneManager : public GameHandler, public SaveListener {
@@ -135,6 +134,6 @@ public:
virtual void processEvent(Event &event) {}
};
-} // End of namespace tSage
+} // End of namespace TsAGE
#endif
diff --git a/engines/tsage/sound.cpp b/engines/tsage/sound.cpp
index efffa70574..22aff6cb04 100644
--- a/engines/tsage/sound.cpp
+++ b/engines/tsage/sound.cpp
@@ -28,7 +28,7 @@
#include "tsage/graphics.h"
#include "tsage/tsage.h"
-namespace tSage {
+namespace TsAGE {
static SoundManager *_soundManager = NULL;
@@ -2929,4 +2929,4 @@ void SoundBlasterDriver::proc42(int channel, int cmd, int value, int *v1, int *v
*v1 = 1;
}
-} // End of namespace tSage
+} // End of namespace TsAGE
diff --git a/engines/tsage/sound.h b/engines/tsage/sound.h
index 2c9221c27a..9507d22cfb 100644
--- a/engines/tsage/sound.h
+++ b/engines/tsage/sound.h
@@ -33,7 +33,7 @@
#include "tsage/saveload.h"
#include "tsage/core.h"
-namespace tSage {
+namespace TsAGE {
class Sound;
@@ -499,6 +499,6 @@ public:
};
-} // End of namespace tSage
+} // End of namespace TsAGE
#endif
diff --git a/engines/tsage/staticres.cpp b/engines/tsage/staticres.cpp
index 9f36268ce3..deb6fd61a6 100644
--- a/engines/tsage/staticres.cpp
+++ b/engines/tsage/staticres.cpp
@@ -22,7 +22,7 @@
#include "tsage/staticres.h"
-namespace tSage {
+namespace TsAGE {
const byte CURSOR_ARROW_DATA[] = {
15, 0, 15, 0, 0, 0, 0, 0, 9, 0,
@@ -73,7 +73,6 @@ const char *SAVE_ERROR_MSG = "Error occurred saving game. Please do not try to r
const char *SAVING_NOT_ALLOWED_MSG = "Saving is not allowed at this time.";
const char *RESTORING_NOT_ALLOWED_MSG = "Restoring is not allowed at this time.";
const char *RESTART_CONFIRM_MSG = "Do you want to restart your game?";
-const char *WATCH_INTRO_MSG = "Do you wish to watch the introduction?";
const char *INV_EMPTY_MSG = "You have nothing in your possesion.";
const char *HELP_MSG = "Ringworld\rRevenge of the Patriarch\x14\rScummVM Version\r\r\
@@ -93,9 +92,16 @@ const char *SOUND_BTN_STRING = "Sound";
const char *RESUME_BTN_STRING = " Resume \rplay";
const char *LOOK_BTN_STRING = "Look";
const char *PICK_BTN_STRING = "Pick";
+
+
+namespace Ringworld {
+
+// Dialog resources
+const char *WATCH_INTRO_MSG = "Do you wish to watch the introduction?";
const char *START_PLAY_BTN_STRING = " Start Play ";
const char *INTRODUCTION_BTN_STRING = "Introduction";
+// Scene specific resources
const char *EXIT_MSG = " EXIT ";
const char *SCENE6100_CAREFUL = "Be careful! The probe cannot handle too much of that.";
const char *SCENE6100_TOUGHER = "Hey! This is tougher than it looks!";
@@ -118,4 +124,26 @@ const char *EXIT_BTN_STRING = "Exit";
const char *DEMO_BTN_STRING = "Demo";
const char *DEMO_RESUME_BTN_STRING = "Resume";
-} // End of namespace tSage
+} // End of namespace Ringworld
+
+namespace BlueForce {
+
+// Dialog resources
+const char *WATCH_INTRO_MSG = "Do you wish to watch the introduction?";
+const char *START_PLAY_BTN_STRING = " Play ";
+const char *INTRODUCTION_BTN_STRING = " Watch ";
+
+// Blue Force general messages
+const char *BF_NAME = "Blue Force";
+const char *BF_COPYRIGHT = " Copyright, 1993 Tsunami Media, Inc.";
+const char *BF_ALL_RIGHTS_RESERVED = "All Rights Reserved";
+const char *BF_19840518 = "May 18, 1984";
+const char *BF_19840515 = "May 15, 1984";
+const char *BF_3_DAYS = "Three days later";
+const char *BF_11_YEARS = "Eleven years later.";
+const char *BF_NEXT_DAY = "The Next Day";
+const char *BF_ACADEMY = "Here we are at the Academy";
+
+} // End of namespace BlueForce
+
+} // End of namespace TsAGE
diff --git a/engines/tsage/staticres.h b/engines/tsage/staticres.h
index fa93511779..290d627090 100644
--- a/engines/tsage/staticres.h
+++ b/engines/tsage/staticres.h
@@ -25,7 +25,7 @@
#include "common/scummsys.h"
-namespace tSage {
+namespace TsAGE {
extern const byte CURSOR_ARROW_DATA[];
@@ -40,7 +40,6 @@ extern const char *SAVE_ERROR_MSG;
extern const char *SAVING_NOT_ALLOWED_MSG;
extern const char *RESTORING_NOT_ALLOWED_MSG;
extern const char *RESTART_CONFIRM_MSG;
-extern const char *WATCH_INTRO_MSG;
// Dialogs
extern const char *HELP_MSG;
@@ -59,6 +58,11 @@ extern const char *RESUME_BTN_STRING;
extern const char *LOOK_BTN_STRING;
extern const char *PICK_BTN_STRING;
extern const char *INV_EMPTY_MSG;
+
+namespace Ringworld {
+
+// Dialog resources
+extern const char *WATCH_INTRO_MSG;
extern const char *START_PLAY_BTN_STRING;
extern const char *INTRODUCTION_BTN_STRING;
@@ -86,6 +90,28 @@ extern const char *EXIT_BTN_STRING;
extern const char *DEMO_BTN_STRING;
extern const char *DEMO_RESUME_BTN_STRING;
-} // End of namespace tSage
+} // End of namespace Ringworld
+
+namespace BlueForce {
+
+// Dialog resources
+extern const char *WATCH_INTRO_MSG;
+extern const char *START_PLAY_BTN_STRING;
+extern const char *INTRODUCTION_BTN_STRING;
+
+// Blue Force messages
+extern const char *BF_NAME;
+extern const char *BF_COPYRIGHT;
+extern const char *BF_ALL_RIGHTS_RESERVED;
+extern const char *BF_19840518;
+extern const char *BF_19840515;
+extern const char *BF_3_DAYS;
+extern const char *BF_11_YEARS;
+extern const char *BF_NEXT_DAY;
+extern const char *BF_ACADEMY;
+
+} // End of namespace BlueForce
+
+} // End of namespace TsAGE
#endif
diff --git a/engines/tsage/tsage.cpp b/engines/tsage/tsage.cpp
index 23a0193b7c..b958933c0c 100644
--- a/engines/tsage/tsage.cpp
+++ b/engines/tsage/tsage.cpp
@@ -30,7 +30,7 @@
#include "tsage/resources.h"
#include "tsage/globals.h"
-namespace tSage {
+namespace TsAGE {
TSageEngine *_vm = NULL;
@@ -68,18 +68,22 @@ void TSageEngine::initialize() {
if (_vm->getFeatures() & GF_DEMO) {
// Add the single library file associated with the demo
_resourceManager->addLib(getPrimaryFilename());
+ _globals = new Globals();
+
} else if (_vm->getGameID() == GType_Ringworld) {
_resourceManager->addLib("RING.RLB");
_resourceManager->addLib("TSAGE.RLB");
+ _globals = new Globals();
+
} else if (_vm->getGameID() == GType_BlueForce) {
_resourceManager->addLib("BLUE.RLB");
if (_vm->getFeatures() & GF_FLOPPY) {
_resourceManager->addLib("FILES.RLB");
_resourceManager->addLib("TSAGE.RLB");
}
+ _globals = new BlueForce::BlueForceGlobals();
}
- _globals = new Globals();
_globals->gfxManager().setDefaults();
// Setup sound settings
@@ -151,4 +155,4 @@ bool TSageEngine::shouldQuit() {
return getEventManager()->shouldQuit() || getEventManager()->shouldRTL();
}
-} // End of namespace tSage
+} // End of namespace TsAGE
diff --git a/engines/tsage/tsage.h b/engines/tsage/tsage.h
index 805461886a..88175f92ce 100644
--- a/engines/tsage/tsage.h
+++ b/engines/tsage/tsage.h
@@ -36,7 +36,7 @@
#include "tsage/resources.h"
-namespace tSage {
+namespace TsAGE {
enum {
GType_Ringworld = 0,
@@ -99,6 +99,6 @@ extern TSageEngine *_vm;
#define ALLOCATE(x) _vm->_memoryManager.allocate2(x)
#define DEALLOCATE(x) _vm->_memoryManager.deallocate(x)
-} // End of namespace tSage
+} // End of namespace TsAGE
#endif